using RothenburgAR.Common;
using RothenburgAR.PointOfInterest;
using RothenburgAR.UI;
using UnityEngine;
using Vuforia;

namespace RothenburgAR.Exhibition
{
    public class ExhibitBehaviour : MonoBehaviour
    {
        public string ID { get; set; }
        public TrackableBehaviour Tracker { get; set; }
        public ExhibitionBehaviour Exhibition { get; set; }
        public ExhibitTitleBehaviour TitleBehaviour { get; set; }

        public bool HasTitle
        {
            get { return TitleBehaviour != null; }
        }

        protected void Start()
        {
            CreateEventHandler();
        }

        private void CreateEventHandler()
        {
            var eventHandler = Tracker.gameObject.AddComponent<TrackableEventHandler>();
            eventHandler.Exhibit = this;
            Tracker.RegisterTrackableEventHandler(eventHandler);
        }

        public void SetTitle(PreloadedExhibitTitle newTitle)
        {
            if (!HasTitle)
            {
                var prefab = Resources.Load<ExhibitTitleBehaviour>("Prefabs/ExhibitTitle");
                TitleBehaviour = Instantiate(prefab); 
                TitleBehaviour.transform.SetParent(Tracker.transform);
                TitleBehaviour.Exhibit = this;
            }

            //TODO remove title rotation
            if (newTitle.Rotation.HasValue)
                TitleBehaviour.transform.localEulerAngles = newTitle.Rotation.Value + new Vector3(90, 0, 0);

            //TODO remove title position and calculate on the fly? if tracker is on a wall, below is best. if it sits on the ground, what?
            if (newTitle.Position.HasValue)
                TitleBehaviour.transform.localPosition = newTitle.Position.Value;

            TitleBehaviour.DataText = newTitle.Text;
        }

        public void SetDescription(TextElement newDescription)
        {
            if (!HasTitle) return;
            TitleBehaviour.SetDescription(newDescription);
        }

        public void AddPoiReference(PreloadedPoiReference referencedPoi)
        {
            var poiId = referencedPoi.ReferencedId;
            if (!PoiDataManager.Instance.HasPoiData(poiId))
            {
                Debug.LogWarning("No POI with ID '" + poiId + "'");
                return;
            }

            Debug.Log(
                "Adding POI " + poiId +
                " to exhibit " + this.ID +
                " in exhibition " + this.Exhibition.ID
            );

            var poiElementPrefab = Resources.Load("Prefabs/POI", typeof(PoiBehaviour));
            PoiBehaviour poiElement = Instantiate(poiElementPrefab) as PoiBehaviour;

            // Set the poiElement as child of the tracker
            poiElement.transform.SetParent(Tracker.transform);
            poiElement.ReferencedID = poiId;
            poiElement.Exhibit = this;

            if (referencedPoi.Position.HasValue)
                poiElement.transform.position = referencedPoi.Position.Value;
            if (referencedPoi.Rotation.HasValue)
                poiElement.transform.localEulerAngles = referencedPoi.Rotation.Value;
            if (referencedPoi.Scale.HasValue)
                poiElement.transform.localScale = referencedPoi.Scale.Value;
        }
    }
}