using Thousandto.Cfg.Data;
using Thousandto.Code.Logic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Thousandto.Editor.ModelEditor
{
    //模型编辑器,用于编辑模型效果
    public class ModelEditor : EditorWindow
    {
        [MenuItem("Ares/ModelEditor")]
        static void Init()
        {
            if (!Application.isPlaying)
            {
                UnityEngine.Debug.LogError("运行模式下才能播放特效,所以先运行起来!");
                return;
            }
            var win = (ModelEditor)EditorWindow.GetWindow(typeof(ModelEditor), true);
            win.minSize = new Vector2(1000, 800);
            win.maxSize = new Vector2(1000, 800);
            win.Show();
            win._startTime = Time.realtimeSinceStartup;
            ModelEditorShowModel.Init(win._drawRect.size);
        }

        private int _typeSelect = 0;
        private int _inputModeID = 0;
        private Vector2 _scrollPos = Vector2.zero;
        private List<int> _showList = null;
        private const int OnePageCount = 36;
        private int _maxPage = 0;
        private int _curPage = 0;
        private ModelData _curSelectModel = null;
        private Rect _drawRect = new Rect(210, 220, 770, 550);
        private bool _drag = false;
        private Vector2 _mousePos = Vector2.zero;
        private int _selectAnim = 0;
        private float _startTime = 0f;
        private void OnGUI()
        {
            var current = Event.current;
            switch (current.type)
            {
                case EventType.MouseUp:
                    {
                        _drag = false;
                        _mousePos = Vector2.zero;
                    }
                    break;
                case EventType.MouseDown:
                    {
                        _mousePos = Event.current.mousePosition;
                        if (_drawRect.Contains(_mousePos))
                        {
                            _drag = true;
                        }
                        else
                        {
                            _drag = false;
                        }
                    }
                    break;
                case EventType.ScrollWheel:
                    {
                        ModelEditorShowModel.OnScrollWheel(Event.current.delta.y);
                    }
                    break;
            }

            if (_drag)
            {
                Vector2 dt = Event.current.mousePosition - _mousePos;
                ModelEditorShowModel.OnDrag(dt);
                _mousePos = Event.current.mousePosition;
            }

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("载入", GUILayout.Width(100)))
            {
                ModelDataManager.Load();
                _typeSelect = 0;
                _inputModeID = 0;
                InitModelList();
            }
            if (GUILayout.Button("保存", GUILayout.Width(100)))
            {
                ModelDataManager.Save();
            }
            GUILayout.Label("筛选器", GUILayout.Width(50));
            int newTypeSelect = EditorGUILayout.Popup(_typeSelect, ModelEditorDefine.ModelTypeName, GUILayout.Width(100));
            GUILayout.Label("模型ID", GUILayout.Width(50));
            int newModelID = EditorGUILayout.IntField(_inputModeID, GUILayout.Width(100));
            if (newTypeSelect != _typeSelect || newModelID != _inputModeID)
            {
                _typeSelect = newTypeSelect;
                _inputModeID = newModelID;
                InitModelList();
            }
            if (_showList != null && _showList.Count > 0)
            {
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginVertical();
                _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
                for (int i = _curPage * OnePageCount; i < _showList.Count && i < (_curPage + 1) * OnePageCount; ++i)
                {
                    if (_curSelectModel != null && _curSelectModel.CfgID == _showList[i])
                    {
                        GUI.color = Color.green;
                    }
                    else
                    {
                        GUI.color = Color.white;
                    }
                    if (GUILayout.Button(string.Format("{0}:{1}", ModelDataManager.DataTable[_showList[i]].Name, _showList[i]), GUILayout.Width(200)))
                    {
                        var model = ModelDataManager.DataTable[_showList[i]];
                        if (_curSelectModel != model)
                        {
                            _curSelectModel = model;
                            ModelEditorShowModel.SetModel(_curSelectModel);
                        }
                    }
                }
                GUI.color = Color.white;
                EditorGUILayout.EndScrollView();

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("上页", GUILayout.Width(40)))
                {
                    if (_curPage > 0)
                    {
                        --_curPage;
                    }
                }
                GUILayout.Label(string.Format("{0}/{1}", _curPage, _maxPage), GUILayout.Width(40));
                if (GUILayout.Button("下页", GUILayout.Width(40)))
                {
                    if (_curPage < _maxPage)
                    {
                        ++_curPage;
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                if (_curSelectModel != null)
                {
                    GUILayout.BeginArea(new Rect(210, 30, 770, 200));
                    if (ModelEditorShowModel.AnimList.Count > 0)
                    {
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Label("播放动画", GUILayout.Width(50));
                        var newSelectAnim = EditorGUILayout.Popup(_selectAnim, ModelEditorShowModel.AnimList.ToArray(), GUILayout.Width(100));
                        if (_selectAnim != newSelectAnim)
                        {
                            _selectAnim = newSelectAnim;
                            ModelEditorShowModel.PlayAnim(ModelEditorShowModel.AnimList[_selectAnim]);
                        }
                        EditorGUILayout.EndHorizontal();
                    }

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label("特效", GUILayout.Width(25));
                    for (int i = 0; i < _curSelectModel.VfxList.Count; ++i)
                    {
                        if(i == 3)
                        {
                            EditorGUILayout.EndHorizontal();
                            EditorGUILayout.BeginHorizontal();
                            GUILayout.Space(35);
                        }
                        GUILayout.Label(string.Format("{0}", i + 1), GUILayout.Width(10));
                        var vfxInfo = _curSelectModel.VfxList[i];
                        EditorGUILayout.IntField(vfxInfo.VfxID, GUILayout.Width(30));
                        var newSlot = EditorGUILayout.Popup(vfxInfo.VfxSlot, ModelEditorDefine.SlotTypeName, GUILayout.Width(90));
                        if(vfxInfo.VfxSlot != newSlot)
                        {
                            vfxInfo.VfxSlot = newSlot;
                            ModelEditorShowModel.LoadVfx(_curSelectModel);
                            break;
                        }
                        if (GUILayout.Button("选择", GUILayout.Width(40)))
                        {
                            var tmpVfx = vfxInfo;
                            ModelSelectVfxEditor.Open(_curSelectModel.ModeType, _curSelectModel.ModelID, (id) =>
                            {
                                tmpVfx.VfxID = id;
                                ModelEditorShowModel.LoadVfx(_curSelectModel);
                            });
                        }
                        if (GUILayout.Button("删除", GUILayout.Width(40)))
                            {
                            if (EditorUtility.DisplayDialog("删除特效", string.Format("是否删除特效{0}挂节点{1}", vfxInfo.VfxID, vfxInfo.VfxSlot), "是", "否"))
                            {
                                _curSelectModel.VfxList.RemoveAt(i);
                                ModelEditorShowModel.LoadVfx(_curSelectModel);
                                break;
                            }
                        }
                        GUILayout.Space(20);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal();
                    if (_curSelectModel.VfxList.Count < 5)
                    {
                        if (GUILayout.Button("添加特效", GUILayout.Width(60)))
                        {
                            var newVfx = new ModelData.ModelVFXInfo();
                            newVfx.VfxID = 0;
                            newVfx.VfxSlot = 0;
                            newVfx.VfxModeType = _curSelectModel.VfxModelTypeCode;
                            _curSelectModel.VfxList.Add(newVfx);
                        }
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(50);
                    GUILayout.Label("勾边颜色", GUILayout.Width(50));
                    var newColor = EditorGUILayout.ColorField(_curSelectModel.OutLineColor, GUILayout.Width(100));
                    GUILayout.Label("勾边大小", GUILayout.Width(50));
                    var newSize = EditorGUILayout.Slider(_curSelectModel.OutLineSize, 0f, 0.1f, GUILayout.Width(200));
                    if (newColor != _curSelectModel.OutLineColor || newSize != _curSelectModel.OutLineSize)
                    {
                        _curSelectModel.OutLineColor = newColor;
                        _curSelectModel.OutLineSize = newSize;
                        ModelEditorShowModel.SetOutLine(_curSelectModel);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal();
                    var newShaderType = EditorGUILayout.Popup((int)_curSelectModel.Shader, ModelEditorDefine.ShaderTypeName, GUILayout.Width(100));
                    if (newShaderType != (int)_curSelectModel.Shader)
                    {
                        _curSelectModel.Shader = (FModelEffectCode)newShaderType;

                        //切换了shader重置所有参数
                        _curSelectModel.ShaderParam1 = string.Empty;
                        _curSelectModel.ShaderParam2 = string.Empty;
                        _curSelectModel.ShaderParam3 = string.Empty;
                        _curSelectModel.ShaderParam4 = string.Empty;
                        _curSelectModel.ShaderParam5 = string.Empty;
                        _curSelectModel.SetUPShaderParam();
                        ModelEditorShowModel.SetupShader(_curSelectModel);
                    }

                    if (_curSelectModel.ShaderParam != null && _curSelectModel.ShaderParam.OnGUI())
                    {
                        //重新设置模型shader参数
                        ModelEditorShowModel.SetupShader(_curSelectModel);
                    }
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Label("替换主纹理", GUILayout.Width(80));
                    EditorGUILayout.TextField(_curSelectModel.MainTexture, GUILayout.Width(150));
                    if (GUILayout.Button("选择", GUILayout.Width(40)))
                    {
                        ModelSelectTextureEditor.Open((texName) =>
                        {
                            if (!string.IsNullOrEmpty(texName) && _curSelectModel.MainTexture != texName)
                            {
                                _curSelectModel.MainTexture = texName;
                                ModelEditorShowModel.SetMainTex(_curSelectModel);
                            }
                        });
                    }
                    if (GUILayout.Button("重置", GUILayout.Width(40)))
                    {
                        _curSelectModel.MainTexture = string.Empty;
                        ModelEditorShowModel.SetMainTex(_curSelectModel);
                    }
                    GUILayout.Space(50);
                    GUILayout.Label("替换Mask纹理", GUILayout.Width(80));
                    EditorGUILayout.TextField(_curSelectModel.MaskTexture, GUILayout.Width(150));
                    if (GUILayout.Button("选择", GUILayout.Width(40)))
                    {
                        ModelSelectTextureEditor.Open((texName) =>
                        {
                            if (!string.IsNullOrEmpty(texName) && _curSelectModel.MaskTexture != texName)
                            {
                                _curSelectModel.MaskTexture = texName;
                                ModelEditorShowModel.SetMaskTex(_curSelectModel);
                            }
                        });
                    }
                    if (GUILayout.Button("重置", GUILayout.Width(40)))
                    {
                        _curSelectModel.MaskTexture = string.Empty;
                        ModelEditorShowModel.SetMaskTex(_curSelectModel);
                    }

                    EditorGUILayout.EndHorizontal();

                    GUILayout.EndArea();
                }

                if (_curSelectModel != null && ModelEditorShowModel.CameraTargetTex != null)
                {
                    ModelEditorShowModel.Render();
                    GUI.Box(_drawRect, ModelEditorShowModel.CameraTargetTex);
                }
            }
        }

        private void Update()
        {
            Repaint();
            var dt = Time.realtimeSinceStartup - _startTime;
            ModelEditorShowModel.Update(dt);
            _startTime = Time.realtimeSinceStartup;
            if (!Application.isPlaying)
            {
                Close();
            }
        }

        private void InitModelList()
        {
            if (ModelDataManager.DataTable == null)
                return;
            _scrollPos = Vector2.zero;
            if (_showList != null)
            {
                _showList.Clear();
            }
            else
            {
                _showList = new List<int>(ModelDataManager.DataTable.Count);
            }

            RoleSkinModelType modeType = RoleSkinModelType.PlayerBody;
            switch (_typeSelect)
            {
                case 0://"玩家身体",
                    modeType = RoleSkinModelType.PlayerBody;
                    break;
                case 1://"玩家武器",
                    modeType = RoleSkinModelType.PlayerWeapon;
                    break;
                case 2:// "玩家翅膀",
                    modeType = RoleSkinModelType.PlayerWing;
                    break;
                case 3://"玩家坐骑",
                    modeType = RoleSkinModelType.PlayerMount;
                    break;
                case 4://"怪物",
                    modeType = RoleSkinModelType.MonsterBody;
                    break;
                case 5://"采集物",
                    modeType = RoleSkinModelType.CollectionBody;
                    break;
                case 6://"掉落模型",
                    modeType = RoleSkinModelType.DrapItem;
                    break;
                case 7:// "其他模型"
                    modeType = RoleSkinModelType.Other;
                    break;
            }
            var iter = ModelDataManager.DataTable.GetEnumerator();
            try
            {
                while (iter.MoveNext())
                {
                    if (modeType == iter.Current.Value.ModeType && (_inputModeID <= 0 || iter.Current.Value.ModelID == _inputModeID))
                    {
                        _showList.Add(iter.Current.Value.CfgID);
                    }
                }
            }
            finally
            {
                iter.Dispose();
            }
            _maxPage = _showList.Count / OnePageCount;
            _curPage = 0;
            _curSelectModel = null;
            _selectAnim = 0;
            ModelEditorShowModel.DestoryModel();
        }

        private void OnDestroy()
        {
            ModelDataManager.Clear();
            ModelEditorShowModel.UnInit();
        }
    }
}