using Sirenix.OdinInspector;
using UnityEngine;
using UnityEditor;

namespace mGame
{
    [CreateAssetMenu(fileName ="Level",menuName ="Level/LevelSO")]
    public class LevelSO : SerializedScriptableObject
    {
        public string levelName;
        public int initEconomy;
        public Vector2Int mapSize;
        

        [FoldoutGroup("BlockMap")]
        [TableMatrix(DrawElementMethod = "DrawCell", SquareCells = true)]
        public Block[,] map;
        [FoldoutGroup("WindMap")]
        [TableMatrix(DrawElementMethod = "DrawWind", SquareCells = true)]
        public Wind[,] mapWind;

        #region Editor
#if UNITY_EDITOR
        private Rect lastRect;
        private Rect lastWind;
        private Block DrawCell(Rect rect,Block value)
        {
            if (map == null) return Block.None;
            //if (!rect.Contains(Event.current.mousePosition)) return value;
            if (
                rect.Contains(Event.current.mousePosition) &&
                (Event.current.type == EventType.MouseDown
                || (Event.current.type == EventType.MouseDrag && lastRect != rect)
                ))
                {
                value = drawType;
                GUI.changed = true;
                Event.current.Use();
            }

            EditorGUI.DrawRect(
                rect,
                DrawRectColor(value)
                );

            return value;
        }
        private Wind DrawWind(Rect rect,Wind value)
        {
            if (mapWind == null) return Wind.None;
            if (
                rect.Contains(Event.current.mousePosition) &&
                (Event.current.type == EventType.MouseDown
                || (Event.current.type == EventType.MouseDrag && lastWind != rect)
                ))
            {
                value = drawWind;
                GUI.changed = true;
                Event.current.Use();
            }
            EditorGUI.DrawRect(
                rect,
                DrawWindColor(value)
                );

            return value;
        }
        private Color DrawRectColor(Block type)
        {
            return type switch
            {
                Block.Grass => Color.green,
                Block.Desert => Color.yellow,
                Block.Mountain => Color.grey,
                Block.Water=>Color.blue,
                Block.Dirt=>new Color(62f/255,44f/255,25f/255),
                Block.DryTown =>new Color(.8f,.8f,0),
                Block.GreenTown => new Color(0,.8f,0),
                _ => Color.clear
            };
        }
        private Color DrawWindColor(Wind type)
        {
            return type switch
            {
                Wind.Height => Color.red,
                Wind.Low => Color.blue,
                _=>Color.clear
            };
        }
        
        [FoldoutGroup("Tool")] public Block drawType;
        [FoldoutGroup("Tool")] public Wind drawWind;
        [FoldoutGroup("Tool")] public bool doShowCreate;
        [FoldoutGroup("Tool"),ShowIf("doShowCreate"),Button("CreateMap")]
        private void CreateMap()
        {
            map = new Block[mapSize.x, mapSize.y];
            mapWind = new Wind[mapSize.x, mapSize.y];
            for(int i = 0; i<mapSize.x;i++)
                for(int j = 0; j < mapSize.y; j++)
                {
                    map[i, j] = drawType;
                    mapWind[i, j] = Wind.None;
                }
        }
        [FoldoutGroup("Tool")] public ExtDir extDir;
        [FoldoutGroup("Tool")] public int extendSize = 2;
        [FoldoutGroup("Tool"),Button("ExtendMap")]
        private void ExtendMap()
        {
            if (extDir == ExtDir.None) return;
            int newX = mapSize.x + ((extDir == ExtDir.West || extDir == ExtDir.East) ?
                extendSize : 0);
            int newY = mapSize.y + ((extDir == ExtDir.South || extDir == ExtDir.North) ?
                extendSize : 0);

            Block[,] temp = new Block[newX, newY];
            Wind[,] tempW = new Wind[newX, newY];

            int biasX = extDir == ExtDir.West ? extendSize : 0;
            int biasY = extDir == ExtDir.North ? extendSize : 0;

            for (int i = 0; i < mapSize.x; i++)
                for (int j = 0; j < mapSize.y; j++)
                {
                    temp[i + biasX, j + biasY] = map[i,j];
                    tempW[i + biasX, j + biasY] = mapWind[i, j];
                }

            map = temp;
            mapWind = tempW;
            mapSize.x = newX;
            mapSize.y = newY;
        }

        [OnInspectorInit]
        private void DoInit()
        {
            extDir = ExtDir.None;
            mapWind ??= new Wind[mapSize.x, mapSize.y];
        }

        [OnInspectorDispose]
        private void DoSave() { mAssetTool.Save(this); }


        public enum ExtDir
        {
            None,
            East,
            West,
            North,
            South
        }
#endif
        #endregion

    }
}



#region 
#if UNITY_EDITOR

public static class mAssetTool
{
    public static void SaveScene()
    {
        UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();
    }
    public static void Save(UnityEngine.Object obj)
    {
        EditorUtility.SetDirty(obj);
        UnityEditor.AssetDatabase.SaveAssetIfDirty(obj);
        AssetDatabase.Refresh();
    }
}
#endif
#endregion

