using UnityEngine;
using mgaia.Utils;
using mgaia.Utils.Pause;

namespace mgaia.Utils.Typing
{
    [DisallowMultipleComponent]
    public class MarqueeBehaviour : MonoBehaviour
    {
        public delegate void MarqueeHandler(MarqueeBehaviour marqueeBehaviour);

        public event MarqueeHandler OnEnded;

        private bool _mIsRunning = false;
        private float _mCurrentGoal;
        private float _mCurrentValue;

        private ITextMesh mTextMesh;
        private float mInitialValue;
        private float mCurrentTime;
        private float mTime;

        [SerializeField]
        private bool _roundToInt = true;

        public bool IsRunning
        {
            get { return _mIsRunning; }
        }

        public float CurrentGoal
        {
            get { return _mCurrentGoal; }
        }

        public float CurrentValue
        {
            get { return _mCurrentValue; }
        }

        public string CustomFormat
        {
            get;
            set;
        }

        public string AdditionalData
        {
            get;
            set;
        }

        public bool RoundToInt
        {
            get { return _roundToInt; }
            set { _roundToInt = value; }
        }

        private void Update()
        {
            if (_mIsRunning)
            {
                mCurrentTime += Time.deltaTime;

                _mCurrentValue = Mathf.Lerp(mInitialValue, _mCurrentGoal, mCurrentTime / mTime);

                SetText(_mCurrentValue);

                if (mCurrentTime >= mTime)
                {
                    _mIsRunning = false;

                    if (OnEnded != null)
                    {
                        OnEnded(this);
                    }
                }
            }
        }

        private void SetText(float value)
        {
            string text = string.Empty;

            if (_roundToInt)
            {
                text = Mathf.RoundToInt(value).ToString();
            }
            else
            {
                text = value.ToString();
            }

            if (!string.IsNullOrEmpty(CustomFormat))
            {
                text = string.Format(CustomFormat, text, AdditionalData);
            }

            mTextMesh.Text = text;
        }

        public void SetNewGoal(float goalValue)
        {
            Assert.AssertTrue(_mIsRunning, "O letreiro precisa estar rodando para chamar esse método!");

            _mCurrentGoal = goalValue;
            mCurrentTime = 0;
            mInitialValue = _mCurrentValue;
        }

        public void StartRunning(ITextMesh textMesh, float initialValue, float goalValue, float time)
        {
            Assert.AssertTrue(!_mIsRunning, "O letreiro já começou a rodar!");

            _mIsRunning = true;

            mTextMesh = textMesh;
            
            mTime = time;
            mCurrentTime = 0;

            mInitialValue = initialValue;
            _mCurrentGoal = goalValue;

            SetText(initialValue);
        }
    }
}