using RothenburgAR.Common;
using RothenburgAR.PointOfInterest;
using RothenburgAR.UI;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace RothenburgAR.Exhibition
{
    public class ExhibitTitleBehaviour : MonoBehaviour
    {
        public GameObject Background;
        public GameObject PoiSpacer;
        public ExhibitBehaviour Exhibit;

        private PoiBehaviour _descriptionPoiBehaviour;
        private PoiData _descriptionPoiData;

        private TextMeshPro GuiText
        {
            get { return this.GetComponentInChildren<TextMeshPro>(); }
        }

        private RectTransform GuiRect
        {
            get { return this.GetComponentInChildren<RectTransform>(); }
        }

        public float FontSize
        {
            get { return this.GuiText.fontSize; }
            set { this.GuiText.fontSize = value; }
        }

        public string DisplayText
        {
            get { return this.GuiText.text; }
            set
            {
                this.GuiText.text = value;
                this.RecalculateSize();
            }
        }

        public TextElement DataText
        {
            get; set;
        }

        void OnEnable()
        {
            this.RecalculateSize();
        }

        private void RecalculateSize()
        {
            GuiText.GetComponent<LayoutElement>().enabled = false;
            GuiText.GetComponent<LayoutElement>().enabled = true;
            StartCoroutine(CreateBorder());
        }

        public void SetDescription(TextElement newDescription)
        {
            if (_descriptionPoiBehaviour == null)
            {
                // Create the POI
                var poiElementPrefab = Resources.Load("Prefabs/POI", typeof(PoiBehaviour));
                _descriptionPoiBehaviour = Instantiate(poiElementPrefab) as PoiBehaviour;

                if (_descriptionPoiBehaviour == null) return;

                _descriptionPoiBehaviour.IsTitlePoi = true;
                var spriteRendererArray = _descriptionPoiBehaviour.gameObject.GetComponentsInChildren<SpriteRenderer>();

                foreach (var spriteRender in spriteRendererArray)
                {
                    spriteRender.material = UIColorSchemeManager.Instance.GetUIMaterial(UIMaterial.BaseOpaque);
                }

                _descriptionPoiBehaviour.transform.localScale = new Vector3(0.85f, 0.85f, 0.85f);
                _descriptionPoiBehaviour.transform.SetParent(PoiSpacer.transform);
                _descriptionPoiBehaviour.transform.localPosition = Vector3.zero;

                // Set position of the POI
                _descriptionPoiBehaviour.Exhibit = Exhibit;
                _descriptionPoiBehaviour.ReferencedID = "TITLE:" + Exhibit.ID;

                // Set POI Rotation
                var transformLocalRotation = _descriptionPoiBehaviour.transform.localRotation;
                transformLocalRotation.x = 0f;
                _descriptionPoiBehaviour.transform.localRotation = transformLocalRotation;
            }

            if (_descriptionPoiData == null)
            {
                _descriptionPoiData = new PoiData { ID = "TITLE:" + Exhibit.ID };
                PoiDataManager.Instance.AddPoiData(_descriptionPoiData);

            }
            _descriptionPoiData.Description = newDescription;
        }

        private IEnumerator CreateBorder()
        {
            yield return null; // wait for next frame so the borderContainer layouter has time to recalculate

            var oldBorder = Background.GetComponentInChildren<LineRenderer>();
            if (oldBorder != null) Destroy(oldBorder.gameObject);

            var borderContainer = new GameObject("BorderContainer");
            borderContainer.transform.SetParent(Background.transform, false);

            var outlineRenderer = borderContainer.AddComponent<LineRenderer>();
            outlineRenderer.useWorldSpace = false;
            outlineRenderer.startWidth = 0.01f;
            outlineRenderer.endWidth = 0.01f;

            Vector3[] corners = new Vector3[4];
            Background.GetComponent<RectTransform>().GetLocalCorners(corners);

            //produces weird seam at begin/end point, so we'll loop it ourselves by drawing back to topLeft and topRight manually
            outlineRenderer.loop = false;

            Vector3 topLeft = corners[1];
            Vector3 topRight = corners[2];
            Vector3 bottomLeft = corners[0];
            Vector3 bottomRight = corners[3];
            outlineRenderer.positionCount = 9;
            outlineRenderer.SetPosition(0, topLeft);
            outlineRenderer.SetPosition(1, topRight);
            outlineRenderer.SetPosition(2, bottomRight);
            outlineRenderer.SetPosition(3, bottomLeft);
            outlineRenderer.SetPosition(4, topLeft);
            outlineRenderer.SetPosition(5, bottomLeft);
            outlineRenderer.SetPosition(6, bottomRight);
            outlineRenderer.SetPosition(7, topRight);
            outlineRenderer.SetPosition(8, topLeft);

            outlineRenderer.numCornerVertices = 2;
            outlineRenderer.numCapVertices = 1;

            outlineRenderer.alignment = LineAlignment.Local;
            outlineRenderer.material = UIColorSchemeManager.Instance.GetUIMaterial(UIMaterial.BaseOpaque);
            outlineRenderer.enabled = GuiText.GetComponent<MeshRenderer>().enabled;
        }
    }
}