using Thousandto.Code.Logic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace Thousandto.SkillEditor.DIY
{
    //技能
    public class EditorSkill
    {
        public EditorEntity Owner { get; private set; }
        public SkillVisualInfo VisualInfo { get; private set; }
        public List<SkillEditorBaseEvent> EventList { get; private set; }
        public bool IsFinish { get; private set; }
        public int CurFrame { get; private set; }
        public float FrameTimer { get; private set; }
        public const float OneFrameTime = 1f / 30f;

        public EditorSkill(EditorEntity owner, SkillVisualInfo visualInfo)
        {
            Owner = owner;
            VisualInfo = visualInfo;

            EventList = new List<SkillEditorBaseEvent>(visualInfo.DataList.Count);
            for (int i = 0; i < visualInfo.DataList.Count; ++i)
            {
                if (!visualInfo.DataList[i].IsEnable)
                    continue;

                var newEvent = NewEvent(visualInfo.DataList[i]);
                if (newEvent != null)
                {
                    EventList.Add(newEvent);
                }
            }
            EventList.Sort(SortEvent);
        }

        private int SortEvent(SkillEditorBaseEvent left, SkillEditorBaseEvent right)
        {
            return right.EventType.CompareTo(left.EventType);
        }

        public void Start()
        {
            IsFinish = false;
            CurFrame = 0;
            FrameTimer = 0f;
            DoEvent(CurFrame);
        }

        public void Stop()
        {
            IsFinish = true;
            for (int i = 0; i < EventList.Count; ++i)
            {
                EventList[i].Stop();
            }
        }

        public void Update(float dt)
        {
            if (IsFinish)
                return;

            for (int i = 0; i < EventList.Count; ++i)
            {
                EventList[i].Update(dt);
            }

            FrameTimer += dt;
            while (FrameTimer >= OneFrameTime)
            {
                ++CurFrame;
                FrameTimer -= OneFrameTime;
                DoEvent(CurFrame);
            }

            if(CurFrame >= VisualInfo.FrameCount)
            {
                //技能结束
                Stop();
            }
        }

        private void DoEvent(int frame)
        {
            for (int i = 0; i < EventList.Count; ++i)
            {
                EventList[i].FrameUpdate(frame);
                if(EventList[i].BaseEventInfo.EventFrame == frame)
                {
                    EventList[i].Enter();
                }
            }
        }
        private SkillEditorBaseEvent NewEvent(SkillBaseEventInfo info)
        {
            switch (info.EventType)
            {
                case SkillEventDefine.PlayAnimation:         //播放动作
                    return new EditorPlayAnimEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayVfx:               //播放特效
                    return new EditorPlayVfxEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlaySfx:               //播放音效
                    return new EditorPlaySFXEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayCameraShake:       //播放摄像机震动
                    return new EditorPlayCameraShakeEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayBlur:              //播放辐射状模糊效果
                    return new EditorPlayBlurEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlaySlow:              //播放减速效果
                    return new EditorPlaySlowEvent(VisualInfo, info, Owner);
                case SkillEventDefine.DisableMove:           //禁止角色移动事件
                    return new EditorDisableMoveEvent(VisualInfo, info, Owner);
                case SkillEventDefine.DisableChangeDir:      //禁止角色改变方向事件
                    return new EditorDisableChangeDirEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayLockTrajectory:    //播放锁定弹道
                    return new EditorPlayLockTrajectoryEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlaySimpleSkillObject: //播放简单召唤物
                    return new EditorPlaySimpleSkillObjectEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlaySkillObject:       //播放技能召唤物
                    return new EditorPlaySkillObjectEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayHit:               //播放产生伤害事件
                    return new EditorPlayHitEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlaySelfMove:          //播放自身移动事件
                    return new EditorPlaySelfMoveEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayHideWeapon:
                    return new EditorPlayHideWeaponEvent(VisualInfo, info, Owner);
                case SkillEventDefine.PlayLinkDamage:
                    return new EditorPlayLinkDamageEvent(VisualInfo, info, Owner);
            }
            return null;
        }
    }
}