using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using ArtResource;
using Spine.Unity;
using UnityEngine.U2D;

namespace EditorArt_Tools
{
    /// <summary>
    /// 美术资源配置编辑器
    /// 提供三栏布局：配置表预览、Item导航、详细编辑
    /// </summary>
    public class ArtResourceConfigEditor : EditorWindow
    {
        private const string SO_ROOT_PATH = "Assets/Art_SubModule/Art_SO";
        private const string JSON_ROOT_PATH = "Assets/Art_SubModule/Art_Json";

        // ===== 数据 =====
        private List<ArtTableSO> allTables = new List<ArtTableSO>();
        private ArtTableSO selectedTable;
        private ArtItemData selectedItem;
        private Dictionary<string, bool> folderFoldouts = new Dictionary<string, bool>();
        private Dictionary<int, bool> itemFoldouts = new Dictionary<int, bool>();

        // 暂存区（用于编辑但未保存的数据）- 完全独立的数据副本
        private List<ArtItemData> tempItemsList = new List<ArtItemData>();
        private new bool hasUnsavedChanges = false;
        
        // ID编辑临时缓存
        private Dictionary<int, string> editingIdStrings = new Dictionary<int, string>();
        private Dictionary<int, int> originalIds = new Dictionary<int, int>();
        
        // 用于第二栏跳转到第三栏
        private int scrollToItemId = -1;
        
        // 当前正在播放Spine动画的Item ID
        private int currentPlayingSpineItemId = -1;

        // ===== UI滚动 =====
        private Vector2 scrollTableList;
        private Vector2 scrollItemNav;
        private Vector2 scrollEditArea;

        // ===== Spine预览 =====
        private object spinePreviewInstance;
        private System.Type spinePreviewType;

        // ===== Sprite预览缓存 =====
        private Dictionary<Sprite, SpriteAtlasInfo?> spriteAtlasCache = new Dictionary<Sprite, SpriteAtlasInfo?>();

        private struct SpriteAtlasInfo
        {
            public SpriteAtlas atlas;
            public string atlasPath;
        }

        [MenuItem("美术工具/美术资源配置")]
        public static void ShowWindow()
        {
            var window = GetWindow<ArtResourceConfigEditor>("美术资源配置");
            window.minSize = new Vector2(1600, 800);
            window.Show();
        }

        private void OnEnable()
        {
            RefreshTableList();
            InitializeSpinePreview();

            AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
            AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
        }

        private void OnDisable()
        {
            CleanupSpinePreview();
            AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;

            // 检查是否有未保存的更改
            if (hasUnsavedChanges)
            {
                if (EditorUtility.DisplayDialog("未保存的更改",
                    "您有未保存的更改，是否保存？",
                    "保存", "放弃"))
                {
                    SaveCurrentTable();
                }
            }
        }

        private void OnDestroy()
        {
            CleanupSpinePreview();
        }

        #region Spine预览初始化和清理

        private void InitializeSpinePreview()
        {
            try
            {
                var assembly = typeof(Spine.Unity.Editor.SkeletonDataAssetInspector).Assembly;
                spinePreviewType = assembly.GetType("Spine.Unity.Editor.SkeletonInspectorPreview");

                if (spinePreviewType != null)
                {
                    spinePreviewInstance = System.Activator.CreateInstance(spinePreviewType);
                    EditorApplication.update -= HandleSpinePreviewUpdate;
                    EditorApplication.update += HandleSpinePreviewUpdate;
                }
            }
            catch (System.Exception e)
            {
                Debug.LogWarning($"初始化Spine预览失败: {e.Message}");
            }
        }

        private void CleanupSpinePreview()
        {
            EditorApplication.update -= HandleSpinePreviewUpdate;

            if (spinePreviewInstance != null && spinePreviewType != null)
            {
                try
                {
                    var clearMethod = spinePreviewType.GetMethod("Clear");
                    if (clearMethod != null)
                    {
                        clearMethod.Invoke(spinePreviewInstance, null);
                    }

                    var cleanupMethod = spinePreviewType.GetMethod("Cleanup");
                    if (cleanupMethod != null)
                    {
                        cleanupMethod.Invoke(spinePreviewInstance, null);
                    }
                }
                catch (System.Exception e)
                {
                    Debug.LogWarning($"清理Spine预览时出错: {e.Message}");
                }

                spinePreviewInstance = null;
            }
        }

        private void HandleSpinePreviewUpdate()
        {
            if (spinePreviewInstance != null && spinePreviewType != null)
            {
                var updateMethod = spinePreviewType.GetMethod("HandleEditorUpdate");
                if (updateMethod != null)
                {
                    updateMethod.Invoke(spinePreviewInstance, null);
                }
            }
        }

        private void OnBeforeAssemblyReload()
        {
            CleanupSpinePreview();
        }

        #endregion

        #region 主界面绘制

        private void OnGUI()
        {
            DrawToolbar();
            EditorGUILayout.Space(5);

            EditorGUILayout.BeginHorizontal();

            // 第一栏：配置表预览（分级显示）
            DrawTableListPanel();

            // 第二栏：Item导航
            DrawItemNavigatorPanel();

            // 第三栏：详细编辑
            DrawEditPanel();

            EditorGUILayout.EndHorizontal();
        }

        private void DrawToolbar()
        {
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

            if (GUILayout.Button("刷新", EditorStyles.toolbarButton, GUILayout.Width(60)))
            {
                RefreshTableList();
            }

            if (GUILayout.Button("新建配置表", EditorStyles.toolbarButton, GUILayout.Width(100)))
            {
                CreateNewTable();
            }

            GUILayout.FlexibleSpace();

            // 未保存提示
            if (hasUnsavedChanges)
            {
                GUI.color = Color.yellow;
                GUILayout.Label("● 有未保存的更改", EditorStyles.boldLabel);
                GUI.color = Color.white;
            }

            if (selectedTable != null)
            {
                EditorGUILayout.LabelField($"当前表: {selectedTable.TableName}", EditorStyles.boldLabel);

                if (GUILayout.Button("保存", EditorStyles.toolbarButton, GUILayout.Width(60)))
                {
                    SaveCurrentTable();
                }
                
                GUI.backgroundColor = Color.red;
                if (GUILayout.Button("删除配置表", EditorStyles.toolbarButton, GUILayout.Width(80)))
                {
                    DeleteCurrentTable();
                }
                GUI.backgroundColor = Color.white;
            }

            EditorGUILayout.EndHorizontal();
        }

        #endregion

        #region 第一栏：配置表预览（分级显示）

        private void DrawTableListPanel()
        {
            EditorGUILayout.BeginVertical("box", GUILayout.Width(320));
            EditorGUILayout.LabelField("配置表列表", EditorStyles.boldLabel);

            scrollTableList = EditorGUILayout.BeginScrollView(scrollTableList);

            if (allTables != null && allTables.Count > 0)
            {
                DrawFolderHierarchy();
            }
            else
            {
                EditorGUILayout.HelpBox("暂无配置表\n点击上方「新建配置表」创建", MessageType.Info);
            }

            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
        }

        private void DrawFolderHierarchy()
        {
            // 按文件夹分组
            var tablesByFolder = allTables
                .Select(table => new
                {
                    Table = table,
                    Path = AssetDatabase.GetAssetPath(table),
                    Folder = GetRelativeFolder(AssetDatabase.GetAssetPath(table))
                })
                .GroupBy(x => x.Folder)
                .OrderBy(g => g.Key);

            foreach (var folderGroup in tablesByFolder)
            {
                string folderName = folderGroup.Key;
                if (!folderFoldouts.ContainsKey(folderName))
                {
                    folderFoldouts[folderName] = true;
                }

                // 绘制文件夹
                EditorGUILayout.BeginHorizontal();
                folderFoldouts[folderName] = EditorGUILayout.Foldout(
                    folderFoldouts[folderName],
                    $"📁 {folderName} ({folderGroup.Count()})",
                    true,
                    EditorStyles.foldoutHeader);
                EditorGUILayout.EndHorizontal();

                // 绘制该文件夹下的配置表
                if (folderFoldouts[folderName])
                {
                    EditorGUI.indentLevel++;
                    foreach (var item in folderGroup)
                    {
                        DrawTableButton(item.Table);
                    }
                    EditorGUI.indentLevel--;
                }

                EditorGUILayout.Space(3);
            }
        }

        private void DrawTableButton(ArtTableSO table)
        {
            bool isSelected = table == selectedTable;

            Color originalBg = GUI.backgroundColor;
            if (isSelected)
            {
                GUI.backgroundColor = new Color(0.3f, 0.6f, 1f);
            }

            EditorGUILayout.BeginVertical("box");

            if (GUILayout.Button($"📄 {table.TableName}", GUILayout.Height(30)))
            {
                SelectTable(table);
            }

            GUI.backgroundColor = originalBg;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField($"ID: {table.TableId}", EditorStyles.miniLabel, GUILayout.Width(80));
            EditorGUILayout.LabelField($"资源数: {table.Items.Count}", EditorStyles.miniLabel);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();
        }

        private string GetRelativeFolder(string assetPath)
        {
            string relativePath = assetPath.Replace(SO_ROOT_PATH + "/", "");
            int lastSlash = relativePath.LastIndexOf('/');
            if (lastSlash >= 0)
            {
                return relativePath.Substring(0, lastSlash);
            }
            return "根目录";
        }

        #endregion

        #region 第二栏：Item导航

        private void DrawItemNavigatorPanel()
        {
            EditorGUILayout.BeginVertical("box", GUILayout.Width(280));

            if (selectedTable == null)
            {
                EditorGUILayout.HelpBox("请从左侧选择一个配置表", MessageType.Info);
                EditorGUILayout.EndVertical();
                return;
            }

            EditorGUILayout.LabelField($"{selectedTable.TableName} - 资源项", EditorStyles.boldLabel);

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("+ 添加新项", GUILayout.Height(25)))
            {
                AddNewItem();
            }
            if (GUILayout.Button("📁 批量导入Sprite", GUILayout.Height(25)))
            {
                BatchImportSprites();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space(5);

            scrollItemNav = EditorGUILayout.BeginScrollView(scrollItemNav);

            if (tempItemsList.Count == 0)
            {
                EditorGUILayout.HelpBox("暂无资源项\n点击上方「+ 添加新项」创建", MessageType.Info);
            }
            else
            {
                for (int i = 0; i < tempItemsList.Count; i++)
                {
                    var item = tempItemsList[i];
                    DrawItemNavigatorButton(item, i);
                }
            }

            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
        }

        private void DrawItemNavigatorButton(ArtItemData item, int index)
        {
            bool isSelected = item == selectedItem;

            Color originalBg = GUI.backgroundColor;
            if (isSelected)
            {
                GUI.backgroundColor = new Color(0.3f, 0.8f, 0.3f);
            }

            EditorGUILayout.BeginVertical("box");

            EditorGUILayout.BeginHorizontal();

            // 小缩略图
            if (item.Sprite != null)
            {
                Rect previewRect = GUILayoutUtility.GetRect(40, 40, GUILayout.ExpandWidth(false));
                EditorGUI.DrawRect(previewRect, new Color(0.2f, 0.2f, 0.2f));
                DrawSpritePreview(previewRect, item.Sprite);
            }
            else if (item.SpineAsset != null)
            {
                Rect previewRect = GUILayoutUtility.GetRect(40, 40, GUILayout.ExpandWidth(false));
                EditorGUI.DrawRect(previewRect, new Color(0.2f, 0.2f, 0.2f));
                GUI.Label(previewRect, "🦴", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontSize = 24 });
            }
            else
            {
                GUILayout.Space(40);
            }

            EditorGUILayout.BeginVertical();
            if (GUILayout.Button($"{index + 1}. {item.Name}", GUILayout.Height(40)))
            {
                SelectItem(item);
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.EndHorizontal();

            // 显示基本信息
            EditorGUILayout.LabelField($"ID: {item.Id}", EditorStyles.miniLabel);
            if (!string.IsNullOrEmpty(item.Desc))
            {
                EditorGUILayout.LabelField($"描述: {item.Desc}", EditorStyles.miniLabel);
            }

            EditorGUILayout.EndVertical();

            GUI.backgroundColor = originalBg;
        }

        #endregion

        #region 第三栏：详细编辑（显示所有Item）

        private void DrawEditPanel()
        {
            EditorGUILayout.BeginVertical("box", GUILayout.ExpandWidth(true));

            if (selectedTable == null)
            {
                EditorGUILayout.HelpBox("请从左侧选择一个配置表", MessageType.Info);
                EditorGUILayout.EndVertical();
                return;
            }

            // 表格信息编辑区域
            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.LabelField("配置表信息", EditorStyles.boldLabel);
            
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("表格ID", GUILayout.Width(80));
            selectedTable.TableId = EditorGUILayout.IntField(selectedTable.TableId);
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("表格名称", GUILayout.Width(80));
            selectedTable.TableName = EditorGUILayout.TextField(selectedTable.TableName);
            EditorGUILayout.EndHorizontal();
            
            if (EditorGUI.EndChangeCheck())
            {
                MarkAsChanged();
            }
            EditorGUILayout.EndVertical();
            
            EditorGUILayout.Space(5);

            scrollEditArea = EditorGUILayout.BeginScrollView(scrollEditArea);

            if (tempItemsList.Count == 0)
            {
                EditorGUILayout.HelpBox("暂无资源项\n点击中间栏上方「+ 添加新项」创建", MessageType.Info);
            }
            else
            {
                // 显示所有Item
                for (int i = 0; i < tempItemsList.Count; i++)
                {
                    var item = tempItemsList[i];
                    
                    // 如果需要跳转到这个Item
                    if (scrollToItemId == item.Id)
                    {
                        // 展开这个Item
                        itemFoldouts[item.Id] = true;
                        
                        // 计算滚动位置：前面的item都是折叠状态，高度约60像素
                        float collapsedItemHeight = 44f; // 折叠状态的实际高度（只有标题行）
                        scrollEditArea.y = Mathf.Max(0, i * collapsedItemHeight);
                        
                        // 重置跳转标记
                        scrollToItemId = -1;
                        
                        // 让GUI重绘以应用折叠状态
                        Repaint();
                    }
                    
                    DrawItemEditSection(item, i);
                    EditorGUILayout.Space(10);
                }
            }

            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();
        }

        private void DrawItemEditSection(ArtItemData item, int index)
        {
            // 整个Item的大面板
            bool isSelected = item == selectedItem;
            Color originalBg = GUI.backgroundColor;
            
            if (isSelected)
            {
                GUI.backgroundColor = new Color(0.4f, 0.7f, 1f, 0.3f);
            }

            EditorGUILayout.BeginVertical("box");
            GUI.backgroundColor = originalBg;

            // 标题行
            EditorGUILayout.BeginHorizontal();
            
            string title = $"{index + 1}. {item.Name} (ID: {item.Id})";
            if (!itemFoldouts.ContainsKey(item.Id))
            {
                itemFoldouts[item.Id] = false;
            }
            
            itemFoldouts[item.Id] = EditorGUILayout.Foldout(
                itemFoldouts[item.Id], 
                title, 
                true, 
                EditorStyles.foldoutHeader);

            GUILayout.FlexibleSpace();

            GUI.backgroundColor = Color.red;
            if (GUILayout.Button("删除", GUILayout.Width(60), GUILayout.Height(20)))
            {
                if (EditorUtility.DisplayDialog("确认删除",
                    $"确定要删除资源项「{item.Name}」吗？\n此操作不可恢复！",
                    "删除", "取消"))
                {
                    DeleteItem(item);
                }
            }
            GUI.backgroundColor = Color.white;

            EditorGUILayout.EndHorizontal();

            // 展开内容
            if (itemFoldouts[item.Id])
            {
                EditorGUI.indentLevel++;

                // 基本信息
                DrawBasicInfoSection(item);

                EditorGUILayout.Space(5);

                // Sprite资源
                DrawSpriteSection(item);

                EditorGUILayout.Space(5);

                // Spine资源
                DrawSpineSection(item);

                EditorGUI.indentLevel--;
            }

            EditorGUILayout.EndVertical();
        }

        private void DrawBasicInfoSection(ArtItemData editingData)
        {
            EditorGUILayout.BeginVertical("box");

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.LabelField("资源ID", EditorStyles.boldLabel);
            
            // 初始化编辑字符串
            int itemHashCode = editingData.GetHashCode();
            if (!editingIdStrings.ContainsKey(itemHashCode))
            {
                editingIdStrings[itemHashCode] = editingData.Id.ToString();
                originalIds[itemHashCode] = editingData.Id;
            }
            
            // 使用TextField进行编辑
            GUI.SetNextControlName($"IdField_{itemHashCode}");
            string newIdString = EditorGUILayout.TextField(editingIdStrings[itemHashCode]);
            
            // 如果字符串改变，更新缓存
            if (newIdString != editingIdStrings[itemHashCode])
            {
                editingIdStrings[itemHashCode] = newIdString;
            }
            
            // 检查是否失去焦点
            string currentFocus = GUI.GetNameOfFocusedControl();
            if (currentFocus != $"IdField_{itemHashCode}" && editingIdStrings.ContainsKey(itemHashCode))
            {
                // 尝试解析ID
                if (int.TryParse(editingIdStrings[itemHashCode], out int newId))
                {
                    // 检查是否有重复ID（排除自己）
                    bool hasDuplicate = tempItemsList.Any(item => item != editingData && item.Id == newId);
                    
                    if (hasDuplicate)
                    {
                        // 有重复，恢复原值并提示
                        EditorUtility.DisplayDialog("ID重复", 
                            $"ID {newId} 已被其他资源项使用，请使用不同的ID。", 
                            "确定");
                        editingIdStrings[itemHashCode] = originalIds[itemHashCode].ToString();
                        editingData.Id = originalIds[itemHashCode];
                    }
                    else if (newId != editingData.Id)
                    {
                        // 没有重复，更新ID
                        int oldId = editingData.Id;
                        editingData.Id = newId;
                        originalIds[itemHashCode] = newId;
                        
                        // 更新itemFoldouts字典的key
                        if (itemFoldouts.ContainsKey(oldId))
                        {
                            bool wasFoldout = itemFoldouts[oldId];
                            itemFoldouts.Remove(oldId);
                            itemFoldouts[newId] = wasFoldout;
                        }
                    }
                }
                else
                {
                    // 解析失败，恢复原值
                    editingIdStrings[itemHashCode] = originalIds[itemHashCode].ToString();
                    editingData.Id = originalIds[itemHashCode];
                }
            }

            EditorGUILayout.Space(5);

            EditorGUILayout.LabelField("资源名称", EditorStyles.boldLabel);
            editingData.Name = EditorGUILayout.TextField(editingData.Name);

            EditorGUILayout.Space(5);

            EditorGUILayout.LabelField("资源描述", EditorStyles.boldLabel);
            editingData.Desc = EditorGUILayout.TextArea(editingData.Desc, GUILayout.Height(60));

            if (EditorGUI.EndChangeCheck())
            {
                MarkAsChanged();
            }

            EditorGUILayout.EndVertical();
        }

        private void DrawSpriteSection(ArtItemData editingData)
        {
            EditorGUILayout.LabelField("Sprite 图片资源", EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical("box");

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Sprite引用", GUILayout.Width(80));
            var newSprite = (Sprite)EditorGUILayout.ObjectField(
                editingData.Sprite,
                typeof(Sprite),
                false);
            EditorGUILayout.EndHorizontal();

            if (EditorGUI.EndChangeCheck())
            {
                editingData.Sprite = newSprite;
                MarkAsChanged();
            }

            // 预览
            if (editingData.Sprite != null)
            {
                EditorGUILayout.Space(10);
                EditorGUILayout.LabelField("预览", EditorStyles.boldLabel);

                Rect previewRect = GUILayoutUtility.GetRect(150, 150, GUILayout.Width(150), GUILayout.Height(150));
                EditorGUI.DrawRect(previewRect, new Color(0.2f, 0.2f, 0.2f));
                DrawSpritePreview(previewRect, editingData.Sprite);

                // 显示信息
                var atlas = GetSpriteAtlas(editingData.Sprite);
                if (atlas.HasValue)
                {
                    EditorGUILayout.LabelField($"图集: {atlas.Value.atlas.name}");
                }

                EditorGUILayout.LabelField($"尺寸: {editingData.Sprite.rect.width} x {editingData.Sprite.rect.height}");
            }

            EditorGUILayout.EndVertical();
        }

        private void DrawSpineSection(ArtItemData editingData)
        {
            EditorGUILayout.LabelField("Spine 骨骼资源", EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical("box");

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("SkeletonDataAsset引用", GUILayout.Width(150));
            var newSpineAsset = (SkeletonDataAsset)EditorGUILayout.ObjectField(
                editingData.SpineAsset,
                typeof(SkeletonDataAsset),
                false);
            EditorGUILayout.EndHorizontal();

            bool spineAssetChanged = EditorGUI.EndChangeCheck();
            
            if (spineAssetChanged)
            {
                editingData.SpineAsset = newSpineAsset;
                
                // 自动选择第一个动画
                if (newSpineAsset != null)
                {
                    var animations = GetSpineAnimations(newSpineAsset);
                    if (animations != null && animations.Length > 0)
                    {
                        editingData.SpineAnimName = animations[0];
                        // 暂停其他正在播放的动画
                        StopAllSpineAnimations();
                        currentPlayingSpineItemId = editingData.Id;
                    }
                }
                
                MarkAsChanged();
            }

            if (editingData.SpineAsset != null)
            {
                EditorGUILayout.Space(5);

                // 获取所有动画名称
                var animations = GetSpineAnimations(editingData.SpineAsset);
                if (animations != null && animations.Length > 0)
                {
                    EditorGUI.BeginChangeCheck();
                    
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("动画名称", GUILayout.Width(80));
                    
                    int currentIndex = System.Array.IndexOf(animations, editingData.SpineAnimName);
                    if (currentIndex < 0) currentIndex = 0;
                    
                    int newIndex = EditorGUILayout.Popup(currentIndex, animations);
                    EditorGUILayout.EndHorizontal();
                    
                    if (EditorGUI.EndChangeCheck())
                    {
                        editingData.SpineAnimName = animations[newIndex];
                        MarkAsChanged();
                        
                        // 切换动画时自动播放
                        StopAllSpineAnimations();
                        currentPlayingSpineItemId = editingData.Id;
                        PlaySpineAnimation(editingData.SpineAsset, editingData.SpineAnimName);
                    }
                }
                else
                {
                    EditorGUILayout.HelpBox("该Spine资源没有动画", MessageType.Warning);
                }

                // 预览
                EditorGUILayout.Space(10);
                
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("预览", EditorStyles.boldLabel);
                
                bool isPlaying = (currentPlayingSpineItemId == editingData.Id);
                GUI.backgroundColor = isPlaying ? Color.green : Color.white;
                if (GUILayout.Button(isPlaying ? "⏸ 暂停" : "▶ 播放", GUILayout.Width(80)))
                {
                    if (isPlaying)
                    {
                        currentPlayingSpineItemId = -1;
                        StopSpineAnimation();
                    }
                    else
                    {
                        StopAllSpineAnimations();
                        currentPlayingSpineItemId = editingData.Id;
                        PlaySpineAnimation(editingData.SpineAsset, editingData.SpineAnimName);
                    }
                }
                GUI.backgroundColor = Color.white;
                EditorGUILayout.EndHorizontal();

                Rect previewRect = GUILayoutUtility.GetRect(150, 150, GUILayout.Width(150), GUILayout.Height(150));
                DrawSpinePreview(previewRect, editingData.SpineAsset, editingData.SpineAnimName, isPlaying);
            }

            EditorGUILayout.EndVertical();
        }

        #endregion

        #region 数据操作

        // 找到所有的SO文件展示在列表中
        private void RefreshTableList()
        {
            allTables.Clear();

            // 搜索所有ScriptableObject，然后手动过滤ArtTableSO类型
            string[] allSOGuids = AssetDatabase.FindAssets("t:ScriptableObject");
            int checkedCount = 0;
            
            foreach (string guid in allSOGuids)
            {
                string path = AssetDatabase.GUIDToAssetPath(guid);
                
                // 只检查在SO_ROOT_PATH路径下的文件
                if (path.StartsWith(SO_ROOT_PATH))
                {
                    checkedCount++;
                    var asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
                    
                    // 检查是否是ArtTableSO类型
                    if (asset is ArtTableSO table)
                    {
                        allTables.Add(table);
                        // Debug.Log($"[ArtResourceConfig] 找到配置表: {table.TableName} - {path}");
                    }
                }
            }

            allTables = allTables.OrderBy(t => t.TableName).ToList();
            // Debug.Log($"[ArtResourceConfig] 在 {SO_ROOT_PATH} 下检查了 {checkedCount} 个SO文件，找到 {allTables.Count} 个配置表");

            // 清除缓存
            tempItemsList.Clear();
            hasUnsavedChanges = false;
            
            Repaint();
        }

        private void SelectTable(ArtTableSO table)
        {
            // 如果有未保存的更改，提示用户
            if (hasUnsavedChanges && selectedTable != null && selectedTable != table)
            {
                if (!EditorUtility.DisplayDialog("切换配置表",
                    "当前有未保存的更改，切换将丢失这些更改。\n确定要切换吗？",
                    "切换", "取消"))
                {
                    return;
                }
            }

            selectedTable = table;
            selectedItem = null;
            hasUnsavedChanges = false;
            itemFoldouts.Clear();
            
            // 加载数据到暂存区
            LoadToTempData();
        }

        private void LoadToTempData()
        {
            tempItemsList.Clear();

            if (selectedTable == null) return;

            // 创建完全独立的副本
            foreach (var item in selectedTable.Items)
            {
                var copy = new ArtItemData
                {
                    Id = item.Id,
                    Name = item.Name,
                    Desc = item.Desc,
                    Sprite = item.Sprite,
                    SpineAsset = item.SpineAsset,
                    SpineAnimName = item.SpineAnimName
                };
                tempItemsList.Add(copy);
            }
        }

        private void SelectItem(ArtItemData item)
        {
            selectedItem = item;

            // 清除当前焦点，避免显示旧的编辑内容
            GUI.FocusControl(null);
            GUIUtility.keyboardControl = 0;
            EditorGUIUtility.editingTextField = false;

            // 折叠所有其他项，只展开当前项
            foreach (var tempItem in tempItemsList)
            {
                itemFoldouts[tempItem.Id] = (tempItem == item);
            }

            // 设置跳转标记，让第三栏滚动到这个Item
            scrollToItemId = item.Id;
            
            // 如果有Spine资源，自动播放动画
            if (item.SpineAsset != null && !string.IsNullOrEmpty(item.SpineAnimName))
            {
                StopAllSpineAnimations();
                currentPlayingSpineItemId = item.Id;
                PlaySpineAnimation(item.SpineAsset, item.SpineAnimName);
            }
            else
            {
                // 如果没有Spine资源，停止所有播放
                StopAllSpineAnimations();
            }
            
            Repaint();
        }

        private void MarkAsChanged()
        {
            hasUnsavedChanges = true;
        }

        private void CreateNewTable()
        {
            string path = EditorUtility.SaveFilePanelInProject(
                "创建新配置表",
                "NewArtTable",
                "asset",
                "请选择配置表保存位置",
                SO_ROOT_PATH);

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            // 检查是否直接放在Art_SO根目录
            string relativePath = path.Replace(SO_ROOT_PATH + "/", "");
            if (!relativePath.Contains("/"))
            {
                EditorUtility.DisplayDialog("路径错误",
                    "配置表不能直接放在 Art_SO 根目录下！\n请在 Art_SO 下创建子文件夹，然后将配置表放在子文件夹中。",
                    "确定");
                return;
            }

            var newTable = ScriptableObject.CreateInstance<ArtTableSO>();
            newTable.TableName = Path.GetFileNameWithoutExtension(path);
            newTable.TableId = GenerateUniqueTableId();
            newTable.Items = new List<ArtItemData>();

            AssetDatabase.CreateAsset(newTable, path);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            
            // 同步创建JSON文件
            SyncToJson(newTable);
            
            // 更新manifest文件
            UpdateManifest();

            RefreshTableList();
            SelectTable(newTable);

            Debug.Log($"创建配置表成功: {path}");
        }

        private int GenerateUniqueTableId()
        {
            if (allTables.Count == 0) return 1;
            return allTables.Max(t => t.TableId) + 1;
        }

        private void AddNewItem()
        {
            if (selectedTable == null) return;

            int newId = tempItemsList.Count > 0
                ? tempItemsList.Max(i => i.Id) + 1
                : 1;

            var newItem = new ArtItemData
            {
                Id = newId,
                Name = $"新资源项_{newId}",
                Desc = ""
            };

            tempItemsList.Add(newItem);
            hasUnsavedChanges = true;

            SelectItem(newItem);
        }

        private void DeleteItem(ArtItemData item)
        {
            if (item == null) return;

            tempItemsList.Remove(item);
            hasUnsavedChanges = true;

            if (selectedItem == item)
            {
                selectedItem = tempItemsList.FirstOrDefault();
            }

            Repaint();
        }

        private void DeleteCurrentTable()
        {
            if (selectedTable == null) return;

            if (!EditorUtility.DisplayDialog("确认删除",
                $"确定要删除配置表「{selectedTable.TableName}」吗？\n这将同时删除SO文件和对应的JSON文件！\n此操作不可恢复！",
                "删除", "取消"))
            {
                return;
            }

            string tableName = selectedTable.TableName;
            string soPath = AssetDatabase.GetAssetPath(selectedTable);
            
            // 计算JSON路径
            string relativePath = soPath.Replace(SO_ROOT_PATH, "").Replace(".asset", ".json");
            string jsonPath = JSON_ROOT_PATH + relativePath;

            // 删除SO文件
            AssetDatabase.DeleteAsset(soPath);
            
            // 删除JSON文件（如果存在）
            if (File.Exists(jsonPath))
            {
                File.Delete(jsonPath);
                // 同时删除.meta文件
                if (File.Exists(jsonPath + ".meta"))
                {
                    File.Delete(jsonPath + ".meta");
                }
            }

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            
            // 更新manifest文件
            UpdateManifest();

            Debug.Log($"已删除配置表: {tableName}");
            Debug.Log($"SO路径: {soPath}");
            if (File.Exists(jsonPath))
            {
                Debug.Log($"JSON路径: {jsonPath}");
            }

            // 清空选择
            selectedTable = null;
            selectedItem = null;
            tempItemsList.Clear();
            hasUnsavedChanges = false;

            // 刷新列表
            RefreshTableList();

            EditorUtility.DisplayDialog("删除成功", $"配置表「{tableName}」已删除", "确定");
        }

        private void BatchImportSprites()
        {
            if (selectedTable == null)
            {
                EditorUtility.DisplayDialog("错误", "请先选择一个配置表", "确定");
                return;
            }

            string folderPath = EditorUtility.OpenFolderPanel("选择Sprite文件夹", "Assets", "");
            if (string.IsNullOrEmpty(folderPath))
            {
                return;
            }

            // 转换为相对路径
            if (!folderPath.StartsWith(Application.dataPath))
            {
                EditorUtility.DisplayDialog("错误", "请选择项目内的文件夹", "确定");
                return;
            }

            string relativePath = "Assets" + folderPath.Substring(Application.dataPath.Length);

            // 查找所有Sprite
            string[] guids = AssetDatabase.FindAssets("t:Sprite", new[] { relativePath });
            
            if (guids.Length == 0)
            {
                EditorUtility.DisplayDialog("提示", "该文件夹中没有找到Sprite资源", "确定");
                return;
            }

            int startId = tempItemsList.Count > 0 ? tempItemsList.Max(i => i.Id) + 1 : 1;
            int importCount = 0;

            foreach (string guid in guids)
            {
                string assetPath = AssetDatabase.GUIDToAssetPath(guid);
                Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);

                if (sprite != null)
                {
                    var newItem = new ArtItemData
                    {
                        Id = startId + importCount,
                        Name = sprite.name,
                        Desc = "",
                        Sprite = sprite
                    };

                    tempItemsList.Add(newItem);
                    importCount++;
                }
            }

            if (importCount > 0)
            {
                hasUnsavedChanges = true;
                EditorUtility.DisplayDialog("导入成功", 
                    $"成功导入 {importCount} 个Sprite资源\n记得点击保存按钮！", 
                    "确定");
            }
        }

        private void SaveCurrentTable()
        {
            if (selectedTable == null)
            {
                EditorUtility.DisplayDialog("保存失败", "没有选中的配置表", "确定");
                return;
            }

            // 检查表格ID和名称的唯一性
            foreach (var table in allTables)
            {
                if (table == selectedTable) continue;
                
                if (table.TableId == selectedTable.TableId)
                {
                    EditorUtility.DisplayDialog("保存失败", 
                        $"表格ID {selectedTable.TableId} 已被表格「{table.TableName}」使用！\n请使用不同的ID。", 
                        "确定");
                    return;
                }
                
                if (table.TableName == selectedTable.TableName)
                {
                    EditorUtility.DisplayDialog("保存失败", 
                        $"表格名称「{selectedTable.TableName}」已被使用！\n请使用不同的名称。", 
                        "确定");
                    return;
                }
            }

            // 检查资源项名称的唯一性
            var nameGroups = tempItemsList.GroupBy(item => item.Name).Where(g => g.Count() > 1).ToList();
            if (nameGroups.Any())
            {
                string duplicateNames = string.Join(", ", nameGroups.Select(g => $"'{g.Key}'"));
                EditorUtility.DisplayDialog("保存失败", 
                    $"资源项名称重复！\n以下名称出现了多次: {duplicateNames}\n请确保每个资源项的名称唯一。", 
                    "确定");
                return;
            }

            // 检查资源项ID的唯一性
            var idGroups = tempItemsList.GroupBy(item => item.Id).Where(g => g.Count() > 1).ToList();
            if (idGroups.Any())
            {
                string duplicateIds = string.Join(", ", idGroups.Select(g => g.Key.ToString()));
                EditorUtility.DisplayDialog("保存失败", 
                    $"资源项ID重复！\n以下ID出现了多次: {duplicateIds}\n请确保每个资源项的ID唯一。", 
                    "确定");
                return;
            }

            // 检查是否有资源项既没有Sprite又没有Spine
            var emptyItems = tempItemsList.Where(item => item.Sprite == null && item.SpineAsset == null).ToList();
            if (emptyItems.Any())
            {
                string emptyItemNames = string.Join(", ", emptyItems.Select(item => $"'{item.Name}' (ID: {item.Id})"));
                EditorUtility.DisplayDialog("保存失败", 
                    $"以下资源项既没有Sprite也没有Spine资源！\n{emptyItemNames}\n请至少为每个资源项配置一种资源。", 
                    "确定");
                return;
            }

            // 清空原始列表
            selectedTable.Items.Clear();

            // 将暂存区的数据复制到原始数据
            foreach (var tempItem in tempItemsList)
            {
                var newItem = new ArtItemData
                {
                    Id = tempItem.Id,
                    Name = tempItem.Name,
                    Desc = tempItem.Desc,
                    Sprite = tempItem.Sprite,
                    SpineAsset = tempItem.SpineAsset,
                    SpineAnimName = tempItem.SpineAnimName
                };
                selectedTable.Items.Add(newItem);
            }

            // 保存SO
            EditorUtility.SetDirty(selectedTable);
            AssetDatabase.SaveAssets();

            // 同步JSON
            SyncToJson(selectedTable);
            
            // 更新manifest文件
            UpdateManifest();

            hasUnsavedChanges = false;

            Debug.Log($"配置表保存成功: {selectedTable.TableName}");
            EditorUtility.DisplayDialog("保存成功", $"配置表「{selectedTable.TableName}」已保存\n共 {selectedTable.Items.Count} 项", "确定");
        }

        #endregion

        #region JSON同步

        private void SyncToJson(ArtTableSO table)
        {
            string soPath = AssetDatabase.GetAssetPath(table);
            string relativePath = soPath.Replace(SO_ROOT_PATH, "").Replace(".asset", ".json");
            string jsonPath = JSON_ROOT_PATH + relativePath;

            // 确保目录存在
            string directory = Path.GetDirectoryName(jsonPath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            // 创建JSON数据
            var jsonData = new ArtTableJsonData
            {
                TableId = table.TableId,
                TableName = table.TableName,
                Items = table.Items.Select(item => new ArtItemJsonData
                {
                    Id = item.Id,
                    Name = item.Name,
                    Desc = item.Desc,
                    SpritePath = item.Sprite != null ? AssetDatabase.GetAssetPath(item.Sprite) : "",
                    SpineAssetPath = item.SpineAsset != null ? AssetDatabase.GetAssetPath(item.SpineAsset) : "",
                    SpineAnimName = item.SpineAnimName
                }).ToList()
            };

            string json = JsonUtility.ToJson(jsonData, true);
            File.WriteAllText(jsonPath, json);

            AssetDatabase.Refresh();

            Debug.Log($"JSON同步成功: {jsonPath}");
        }
        
        private void UpdateManifest()
        {
            const string MANIFEST_PATH = "Assets/Art_SubModule/Art_SO/art_table_manifest.json";
            
            try
            {
                // 查找所有ArtTableSO文件
                string[] guids = AssetDatabase.FindAssets("t:ArtTableSO", new[] { SO_ROOT_PATH });
                List<string> tablePaths = new List<string>();
                
                foreach (string guid in guids)
                {
                    string path = AssetDatabase.GUIDToAssetPath(guid);
                    if (!string.IsNullOrEmpty(path))
                    {
                        tablePaths.Add(path);
                    }
                }
                
                // 排序路径
                tablePaths.Sort();
                
                // 创建或更新manifest
                ArtTableManifest manifest;
                
                // 如果文件存在，读取现有的预加载配置
                if (File.Exists(MANIFEST_PATH))
                {
                    string existingJson = File.ReadAllText(MANIFEST_PATH);
                    manifest = JsonUtility.FromJson<ArtTableManifest>(existingJson);
                    
                    // 确保字段不为null
                    if (manifest == null)
                    {
                        manifest = new ArtTableManifest();
                    }
                    if (manifest.preloadTableIds == null)
                    {
                        manifest.preloadTableIds = new int[0];
                    }
                }
                else
                {
                    // 创建新的manifest
                    manifest = new ArtTableManifest
                    {
                        preloadTableIds = new int[0]
                    };
                }
                
                // 更新路径列表
                manifest.tablePaths = tablePaths.ToArray();
                
                // 清理预加载配置：移除已删除表的ID
                // 获取所有当前存在的表的ID
                List<int> validTableIds = new List<int>();
                foreach (string guid in guids)
                {
                    string path = AssetDatabase.GUIDToAssetPath(guid);
                    var table = AssetDatabase.LoadAssetAtPath<ArtTableSO>(path);
                    if (table != null)
                    {
                        validTableIds.Add(table.TableId);
                    }
                }
                
                // 过滤掉已删除表的ID
                if (manifest.preloadTableIds != null && manifest.preloadTableIds.Length > 0)
                {
                    var cleanedPreloadIds = manifest.preloadTableIds.Where(id => validTableIds.Contains(id)).ToArray();
                    int removedCount = manifest.preloadTableIds.Length - cleanedPreloadIds.Length;
                    
                    manifest.preloadTableIds = cleanedPreloadIds;
                    
                    if (removedCount > 0)
                    {
                        Debug.Log($"[ArtResourceConfigEditor] 从预加载配置中移除了 {removedCount} 个已删除表的ID");
                    }
                }
                
                // 序列化为JSON
                string json = JsonUtility.ToJson(manifest, true);
                
                // 确保目录存在
                string directory = Path.GetDirectoryName(MANIFEST_PATH);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                
                // 写入文件
                File.WriteAllText(MANIFEST_PATH, json);
                AssetDatabase.ImportAsset(MANIFEST_PATH);
                
                Debug.Log($"[ArtResourceConfigEditor] Manifest文件已更新: {MANIFEST_PATH}, 共 {tablePaths.Count} 个表");
            }
            catch (System.Exception ex)
            {
                Debug.LogError($"[ArtResourceConfigEditor] 更新Manifest文件失败: {ex.Message}");
            }
        }

        [System.Serializable]
        public class ArtTableManifest
        {
            public string[] tablePaths;
            public int[] preloadTableIds;
        }

        [System.Serializable]
        public class ArtTableJsonData
        {
            public int TableId;
            public string TableName;
            public List<ArtItemJsonData> Items;
        }

        [System.Serializable]
        public class ArtItemJsonData
        {
            public int Id;
            public string Name;
            public string Desc;
            public string SpritePath;
            public string SpineAssetPath;
            public string SpineAnimName;
        }

        #endregion

        #region 预览功能

        private void DrawSpritePreview(Rect rect, Sprite sprite)
        {
            if (sprite == null || sprite.texture == null) return;

            Rect texCoords = sprite.textureRect;
            Texture2D tex = sprite.texture;

            Rect normalizedCoords = new Rect(
                texCoords.x / tex.width,
                texCoords.y / tex.height,
                texCoords.width / tex.width,
                texCoords.height / tex.height
            );

            // 计算适配矩形（保持长宽比）
            float aspect = texCoords.width / texCoords.height;
            Rect drawRect = rect;
            if (aspect > 1f)
            {
                float height = drawRect.width / aspect;
                drawRect.y += (drawRect.height - height) * 0.5f;
                drawRect.height = height;
            }
            else
            {
                float width = drawRect.height * aspect;
                drawRect.x += (drawRect.width - width) * 0.5f;
                drawRect.width = width;
            }

            GUI.DrawTextureWithTexCoords(drawRect, tex, normalizedCoords, true);
        }

        private string[] GetSpineAnimations(SkeletonDataAsset spineAsset)
        {
            if (spineAsset == null || spineAsset.GetSkeletonData(false) == null)
                return new string[0];

            var skeletonData = spineAsset.GetSkeletonData(false);
            var animations = skeletonData.Animations;
            
            if (animations == null || animations.Count == 0)
                return new string[0];

            string[] animNames = new string[animations.Count];
            for (int i = 0; i < animations.Count; i++)
            {
                animNames[i] = animations.Items[i].Name;
            }
            
            return animNames;
        }

        private void PlaySpineAnimation(SkeletonDataAsset spineAsset, string animName)
        {
            if (spineAsset == null || spinePreviewInstance == null || spinePreviewType == null)
                return;

            try
            {
                // 先清理旧的预览
                var clearMethod = spinePreviewType.GetMethod("Clear");
                if (clearMethod != null)
                {
                    clearMethod.Invoke(spinePreviewInstance, null);
                }

                // 初始化预览（传入Repaint回调、SkeletonDataAsset和空字符串）
                var initMethod = spinePreviewType.GetMethod("Initialize", new System.Type[] { typeof(System.Action), typeof(SkeletonDataAsset), typeof(string) });
                if (initMethod != null)
                {
                    initMethod.Invoke(spinePreviewInstance, new object[] { new System.Action(Repaint), spineAsset, "" });
                    
                    // 延迟设置动画，确保skeleton已完全初始化
                    if (!string.IsNullOrEmpty(animName))
                    {
                        EditorApplication.delayCall += () =>
                        {
                            try
                            {
                                if (spinePreviewInstance != null && spinePreviewType != null)
                                {
                                    var skeletonAnimField = spinePreviewType.GetField("skeletonAnimation", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                                    if (skeletonAnimField != null)
                                    {
                                        var skeletonAnim = skeletonAnimField.GetValue(spinePreviewInstance) as SkeletonAnimation;
                                        if (skeletonAnim != null && skeletonAnim.valid && skeletonAnim.AnimationState != null)
                                        {
                                            skeletonAnim.AnimationState.SetAnimation(0, animName, true);
                                        }
                                    }
                                }
                            }
                            catch { }
                        };
                    }
                }
                
                Repaint();
            }
            catch (System.Exception e)
            {
                Debug.LogWarning($"播放Spine动画失败: {e.Message}");
            }
        }

        private void StopSpineAnimation()
        {
            if (spinePreviewInstance == null || spinePreviewType == null)
                return;

            try
            {
                var clearMethod = spinePreviewType.GetMethod("Clear");
                if (clearMethod != null)
                {
                    clearMethod.Invoke(spinePreviewInstance, null);
                }
                
                Repaint();
            }
            catch (System.Exception e)
            {
                Debug.LogWarning($"停止Spine动画失败: {e.Message}");
            }
        }

        private void StopAllSpineAnimations()
        {
            currentPlayingSpineItemId = -1;
            StopSpineAnimation();
        }

        private void DrawSpinePreview(Rect rect, SkeletonDataAsset spineAsset, string animName, bool isPlaying)
        {
            if (spineAsset == null || spinePreviewInstance == null || spinePreviewType == null)
            {
                EditorGUI.HelpBox(rect, "Spine预览不可用", MessageType.Info);
                return;
            }

            try
            {
                // 只有在播放状态时才绘制预览
                if (isPlaying)
                {
                    // 检查预览是否有效
                    var isValidProperty = spinePreviewType.GetProperty("IsValid");
                    bool isValid = isValidProperty != null && (bool)isValidProperty.GetValue(spinePreviewInstance, null);
                    
                    if (isValid)
                    {
                        // 绘制预览 - 使用HandleInteractivePreviewGUI方法
                        var handleMethod = spinePreviewType.GetMethod("HandleInteractivePreviewGUI");
                        if (handleMethod != null)
                        {
                            handleMethod.Invoke(spinePreviewInstance, new object[] { rect, EditorStyles.helpBox });
                        }
                    }
                    else
                    {
                        EditorGUI.DrawRect(rect, new Color(0.2f, 0.2f, 0.2f));
                        GUI.Label(rect, "Spine预览初始化中...", new GUIStyle(GUI.skin.label) 
                        { 
                            alignment = TextAnchor.MiddleCenter,
                            normal = new GUIStyleState { textColor = Color.gray }
                        });
                    }
                }
                else
                {
                    // 不播放时显示静态提示
                    EditorGUI.DrawRect(rect, new Color(0.2f, 0.2f, 0.2f));
                    GUI.Label(rect, "点击播放按钮查看动画", new GUIStyle(GUI.skin.label) 
                    { 
                        alignment = TextAnchor.MiddleCenter,
                        normal = new GUIStyleState { textColor = Color.gray }
                    });
                }
            }
            catch (System.Exception e)
            {
                EditorGUI.HelpBox(rect, $"Spine预览错误: {e.Message}", MessageType.Warning);
            }
        }

        private SpriteAtlasInfo? GetSpriteAtlas(Sprite sprite)
        {
            if (sprite == null) return null;

            if (spriteAtlasCache.TryGetValue(sprite, out var cached))
            {
                return cached;
            }

            string[] atlasGuids = AssetDatabase.FindAssets("t:SpriteAtlas");
            foreach (string guid in atlasGuids)
            {
                string atlasPath = AssetDatabase.GUIDToAssetPath(guid);
                SpriteAtlas atlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(atlasPath);

                if (atlas != null && atlas.CanBindTo(sprite))
                {
                    var info = new SpriteAtlasInfo
                    {
                        atlas = atlas,
                        atlasPath = atlasPath
                    };
                    spriteAtlasCache[sprite] = info;
                    return info;
                }
            }

            spriteAtlasCache[sprite] = null;
            return null;
        }

        #endregion
    }
}
