using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

namespace SimplifyXR
{
    [System.Serializable]
    public class HoverDepthProperties
    {
        public float initDelay;
        public bool useWorldPos;
        public float depthAmount;
        public AnimationCurve depthCurve;
        public float depthTime;
    }


    [RequireComponent(typeof(Button))]
    public class HoverDepth : EventTrigger
    {
        public HoverDepthProperties depthProperties;

        private float startDepth;
        private Button button;
        private RectTransform buttonRect;
        private Coroutine depthRoutine;
        private Coroutine initRoutine;
        private FlyIn flyIn;

        bool initialized = false;


        public override void OnPointerEnter(PointerEventData eventData)
        {
            if (enabled  && initialized)
            {
                base.OnPointerEnter(eventData);
                ChangeDepth(true);
            }
        }

        public override void OnPointerExit(PointerEventData eventData)
        {
            if (enabled && initialized)
            {
                base.OnPointerExit(eventData);
                ChangeDepth(false);
            }
        }


        IEnumerator InitRoutine()
        {
            initialized = false;
            yield return new WaitForSeconds(depthProperties.initDelay);
            initialized = true;
        }

        private void OnEnable()
        {
            if (initRoutine != null) StopCoroutine(initRoutine);
            if (!flyIn) StartCoroutine(InitRoutine());
        }

        // Start is called before the first frame update
        void Awake()
        {
            button = this.GetComponent<Button>();
            buttonRect = button.GetComponent<RectTransform>();
            startDepth = buttonRect.localPosition.z;

            flyIn = this.GetComponent<FlyIn>();
            if (flyIn)
            {
                flyIn.OnFlyStart.AddListener(() => initialized = false);
                flyIn.OnFlyEnd.AddListener(() => initialized = true);
            }
            else { initialized = true; }          
        }


        public void ChangeDepth(bool hover)
        {
            if (depthRoutine != null) StopCoroutine(depthRoutine);
            depthRoutine = StartCoroutine(ChangeDepthRoutine(hover));
        }

        IEnumerator ChangeDepthRoutine(bool hover)
        {
            var targetDepth = hover ?
                   startDepth + depthProperties.depthAmount :
                   startDepth;

            var currentPos = buttonRect.localPosition;

            var targetPos = new Vector3(
                currentPos.x,
                currentPos.y,
                targetDepth * 
                (depthProperties.useWorldPos ? 
                1 : buttonRect.localScale.x)
                );

            for (float i = 0; i < depthProperties.depthTime; i += Time.deltaTime)
            {               

                buttonRect.localPosition =
                    Vector3.Lerp(
                        currentPos,
                        targetPos,
                        depthProperties
                        .depthCurve.Evaluate(i /
                        depthProperties.depthTime)
                        );

                yield return null;
            }

            buttonRect.localPosition = targetPos;

        }

    }

}

