using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;

namespace gay.lilyy.TextureAtlasGenerator
{
    [CreateAssetMenu(fileName = "TextureAtlasSettings", menuName = "Texture Atlas/Settings")]
    public class TextureAtlasSettings : ScriptableObject
    {
        public Texture2D[] textures;
        public int atlasSize = 1024;
        public int columns = 4;
        public int rows = 4;
        public string savePath = "Assets/Atlas.png";
    }

    [CustomEditor(typeof(TextureAtlasSettings))]
    public class TextureAtlasEditor : Editor
    {
        private SerializedProperty texturesProp;
        private SerializedProperty columnsProp;
        private SerializedProperty rowsProp;

        private void OnEnable()
        {
            texturesProp = serializedObject.FindProperty("textures");
            columnsProp = serializedObject.FindProperty("columns");
            rowsProp = serializedObject.FindProperty("rows");
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.LabelField("Texture Atlas Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("atlasSize"));
            EditorGUILayout.PropertyField(columnsProp);
            EditorGUILayout.PropertyField(rowsProp);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("savePath"));

            DrawTextureGrid();

            if (GUILayout.Button("Generate Atlas"))
            {
                GenerateAtlas();
            }

            serializedObject.ApplyModifiedProperties();
        }

        private void DrawTextureGrid()
        {
            int totalSlots = columnsProp.intValue * rowsProp.intValue;
            if (texturesProp.arraySize != totalSlots)
                texturesProp.arraySize = totalSlots;

            EditorGUILayout.LabelField("Textures Grid", EditorStyles.boldLabel);
            int gridWidth = 80;
            int gridHeight = 80;

            for (int y = 0; y < rowsProp.intValue; y++)
            {
                EditorGUILayout.BeginHorizontal();
                for (int x = 0; x < columnsProp.intValue; x++)
                {
                    int index = y * columnsProp.intValue + x;
                    SerializedProperty textureProp = texturesProp.GetArrayElementAtIndex(index);
                    textureProp.objectReferenceValue = (Texture2D)EditorGUILayout.ObjectField(
                        textureProp.objectReferenceValue, typeof(Texture2D), false,
                        GUILayout.Width(gridWidth), GUILayout.Height(gridHeight));
                }
                EditorGUILayout.EndHorizontal();
            }
        }

        private void GenerateAtlas()
        {
            TextureAtlasSettings settings = (TextureAtlasSettings)target;
            if (settings.textures == null || settings.textures.Length == 0)
            {
                Debug.LogError("No textures assigned!");
                return;
            }

            Texture2D atlas = new Texture2D(settings.atlasSize, settings.atlasSize);
            Color[] blackPixels = new Color[settings.atlasSize * settings.atlasSize];
            for (int i = 0; i < blackPixels.Length; i++) blackPixels[i] = Color.black;
            atlas.SetPixels(blackPixels);

            int cellWidth = settings.atlasSize / settings.columns;
            int cellHeight = settings.atlasSize / settings.rows;

            for (int i = 0; i < settings.textures.Length; i++)
            {
                if (settings.textures[i] == null) continue;
                int x = (i % settings.columns) * cellWidth;
                int y = (settings.rows - 1 - (i / settings.columns)) * cellHeight;
                Texture2D resized = ResizeTexture(settings.textures[i], cellWidth, cellHeight);
                atlas.SetPixels(x, y, cellWidth, cellHeight, resized.GetPixels(), 0);
            }

            atlas.Apply();
            byte[] bytes = atlas.EncodeToPNG();
            File.WriteAllBytes(settings.savePath, bytes);
            AssetDatabase.Refresh();
            Debug.Log("Atlas saved at: " + settings.savePath);
        }


        private Texture2D ResizeTexture(Texture2D texture, int width, int height)
        {
            RenderTexture rt = new RenderTexture(width, height, 32);
            Graphics.Blit(texture, rt);
            Texture2D result = new Texture2D(width, height);
            RenderTexture.active = rt;
            result.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            result.Apply();
            RenderTexture.active = null;
            return result;
        }
    }
}
