using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace mgaia.Utils
{
    public class CodeAnimationManager : MonoBehaviour
    {
        private static CodeAnimationManager _sInstance;

        public static CodeAnimationManager Instance
        {
            get { return _sInstance; }
        }

        private List<AbstractCodeAnimation> mActiveAnimationsList = new List<AbstractCodeAnimation>();
        private List<AbstractCodeAnimation> mPausedAnimationsList = new List<AbstractCodeAnimation>();

        public static void Initialize()
        {
            _sInstance = (new GameObject("NewCodeAnimation")).AddComponent<CodeAnimationManager>();
        }

        private void Awake()
        {
            DontDestroyOnLoad(this);
        }

        public void PauseAnimation(AbstractCodeAnimation anim)
        {
            if (mActiveAnimationsList.Contains(anim))
            {
                mPausedAnimationsList.Add(anim);
                mActiveAnimationsList.Remove(anim);
            }
        }

        public void ResumeAnimation(AbstractCodeAnimation anim)
        {
            if (mPausedAnimationsList.Contains(anim))
            {
                mPausedAnimationsList.Remove(anim);
                mActiveAnimationsList.Add(anim);
            }
        }

        public void StopAndRemoveAnimation(AbstractCodeAnimation anim)
        {
            if (mActiveAnimationsList.Contains(anim))
            {
                mActiveAnimationsList.Remove(anim);
            }
            else if (mPausedAnimationsList.Contains(anim))
            {
                mPausedAnimationsList.Remove(anim);
            }
        }

        public void ActivateAnimation(AbstractCodeAnimation anim, object[] objs, bool ignoreIfBeingUsed = false)
        {
            Assert.AssertTrue(!mActiveAnimationsList.Contains(anim) || ignoreIfBeingUsed, "This animation is already being used!");
            if (!mActiveAnimationsList.Contains(anim))
            {
                anim.ActivateAnimation(objs);
                mActiveAnimationsList.Add(anim);
            }
        }

        private void Update()
        {
            List<AbstractCodeAnimation> animationsToRemove = new List<AbstractCodeAnimation>();

            for (int idx = 0; idx < mActiveAnimationsList.Count; idx++)
            {
                AbstractCodeAnimation animation = mActiveAnimationsList[idx];
                if (animation.Update(Time.deltaTime))
                {
                    animationsToRemove.Add(animation);
                }
            }

            foreach (AbstractCodeAnimation animation in animationsToRemove)
            {
                mActiveAnimationsList.Remove(animation);
            }
        }
    }
}