using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Thousandto.Editor.Excel;

public class CheckInvalidAtlasSpriteEditor : EditorWindow
{
    [MenuItem("Ares/检查Atlas上无用的Sprite")]
    static void DoIt()
    {
        var win = (CheckInvalidAtlasSpriteEditor)EditorWindow.GetWindow(typeof(CheckInvalidAtlasSpriteEditor));
        win.Show();
    }

    private string _prefabPath = string.Empty;
    private Dictionary<string, List<string>> allAtlsInfo = new Dictionary<string, List<string>>();
    private Vector2 _scrollPos = Vector2.zero;
    void OnGUI()
    {
        EditorGUILayout.BeginVertical();
        EditorGUILayout.LabelField("选择路径");
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("需要检测的UIForm路径");
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("浏览", GUILayout.Width(100)))
        {
            _prefabPath = EditorUtility.OpenFolderPanel("Check UIForm Prefab Path", _prefabPath, "");
        }
        if (string.IsNullOrEmpty(_prefabPath))
        {
            EditorGUILayout.LabelField("null...");
        }
        else
        {
            EditorGUILayout.LabelField(_prefabPath);
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();

        EditorGUILayout.BeginVertical();
        EditorGUILayout.BeginHorizontal();

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();

        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();

        if (GUILayout.Button("检测并导出", GUILayout.Width(100)))
        {
            if (string.IsNullOrEmpty(_prefabPath))
                return;
            if (Directory.Exists(_prefabPath))
            {
                string excelPath = EditorUtility.SaveFilePanel("Export Excel", "", "InvalidAtlasSprite", "xlsx");
                if (string.IsNullOrEmpty(excelPath))
                    return;

                allAtlsInfo.Clear();
                DirectoryInfo direction = new DirectoryInfo(_prefabPath);
                FileInfo[] files = direction.GetFiles("*.prefab", SearchOption.AllDirectories);
                for (int i = 0; i < files.Length; ++i)
                {
                    var path = files[i].FullName.Replace('\\', '/');
                    var starIndex = path.IndexOf("/Assets/", 0);
                    path = path.Remove(0, starIndex + 1);
                    var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                    if (go != null)
                    {
                        var sprites = go.GetComponentsInChildren<UISprite>(true);
                        for (int j = 0; j < sprites.Length; ++j)
                        {
                            if (sprites[j].atlas != null)
                            {
                                var atlasName = sprites[j].atlas.name;
                                var cIndex = atlasName.LastIndexOf("/");
                                if (cIndex >= 0)
                                {
                                    atlasName = atlasName.Remove(0, cIndex + 1);
                                }

                                if(!atlasName.StartsWith("UIIconAtlas") && !atlasName.StartsWith("UIExpressionAtlas"))
                                {
                                    List<string> sprNameList = null;
                                    if (!allAtlsInfo.TryGetValue(atlasName, out sprNameList))
                                    {
                                        //读取所有sprite信息
                                        var sprList = sprites[j].atlas.spriteList;
                                        sprNameList = new List<string>(sprList.Count);
                                        for (int k = 0; k < sprList.Count; ++k)
                                        {
                                            sprNameList.Add(sprList[k].name);
                                        }
                                        allAtlsInfo.Add(atlasName, sprNameList);
                                    }
                                    sprNameList.Remove(sprites[j].spriteName);
                                }
                            }
                        }
                    }
                }

                //查找cs代码和lua代码
                var starIndex2 = _prefabPath.IndexOf("/Assets/", 0);
                var csCodePath = _prefabPath.Remove(starIndex2);
                csCodePath = csCodePath + "/Assets/GameAssets/Resources/GameUI/Form";
                var luaCodePath = _prefabPath.Remove(starIndex2);
                luaCodePath = luaCodePath + "/Assets/GameAssets/Resources/Lua/UI/Forms";
                var strDefPath = _prefabPath.Remove(starIndex2);
                strDefPath = strDefPath + "/Assets/GameAssets/Resources/Lua/Config/Data/StringDefines.lua";

                List<string> codeTexts = new List<string>(64);
                codeTexts.Add(File.ReadAllText(strDefPath));
                if (Directory.Exists(csCodePath))
                {
                    DirectoryInfo csdirection = new DirectoryInfo(csCodePath);
                    FileInfo[] csFiles = csdirection.GetFiles("*.cs", SearchOption.AllDirectories);
                    for (int j = 0; j < csFiles.Length; ++j)
                    {
                        codeTexts.Add(File.ReadAllText(csFiles[j].FullName));
                    }
                }

                if (Directory.Exists(luaCodePath))
                {
                    DirectoryInfo luadirection = new DirectoryInfo(luaCodePath);
                    FileInfo[] luaFiles = luadirection.GetFiles("*.lua", SearchOption.AllDirectories);
                    for (int j = 0; j < luaFiles.Length; ++j)
                    {
                        codeTexts.Add(File.ReadAllText(luaFiles[j].FullName));
                    }
                }

                int rowCount = 0;
                {
                    var iter = allAtlsInfo.GetEnumerator();
                    try
                    {
                        while (iter.MoveNext())
                        {
                            ++rowCount;
                            for (int i = iter.Current.Value.Count - 1; i >= 0; --i)
                            {
                                if (IsUsedSprite(iter.Current.Value[i], codeTexts))
                                {
                                    iter.Current.Value.RemoveAt(i);
                                }
                            }
                            rowCount += iter.Current.Value.Count;
                        }
                    }
                    finally
                    {
                        iter.Dispose();
                    }
                }

                {
                    NormalExcelInfo excelInfo = new NormalExcelInfo();
                    excelInfo.Name = "InvalidAtlasSprite";
                    excelInfo.Values = new string[rowCount, 2];
                    var iter = allAtlsInfo.GetEnumerator();
                    int curRow = 0;
                    while (iter.MoveNext())
                    {
                        excelInfo.Values[curRow++, 0] = iter.Current.Key;
                        for (int i = 0; i < iter.Current.Value.Count; ++i)
                        {
                            excelInfo.Values[curRow++, 1] = iter.Current.Value[i];
                        }
                    }
                    ExcelWriter.Write(excelPath, excelInfo);
                }
            }
        }

        //_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
        //{
        //    var iter = allAtlsInfo.GetEnumerator();
        //    try
        //    {
        //        while (iter.MoveNext())
        //        {
        //            GUI.color = Color.red;
        //            EditorGUILayout.LabelField(iter.Current.Key);
        //            GUI.color = Color.white;
        //            for (int i = 0; i < iter.Current.Value.Count; ++i)
        //            {
        //                EditorGUILayout.BeginHorizontal();
        //                GUILayout.Space(30);
        //                EditorGUILayout.TextField(iter.Current.Value[i]);
        //                EditorGUILayout.EndHorizontal();
        //            }
        //        }
        //    }
        //    finally
        //    {
        //        iter.Dispose();
        //    }
        //}
        //EditorGUILayout.EndScrollView();
    }

    private bool IsUsedSprite(string name, List<string> codeText)
    {
        if (name.StartsWith("bag_back_"))
            return true;
        string number = string.Empty;
        bool findNumber = false;
        for (int i = 0; i < name.Length; ++i)
        {
            if (name[i] >= '0' && name[i] <= '9')
            {
                number += name[i];
                findNumber = true;
            }
            else if (findNumber)
            {
                break;
            }
        }
        var findText1 = "\"" + name + "\"";
        var findText2 = string.Empty;
        var findText3 = string.Empty;
        if (!string.IsNullOrEmpty(number))
        {
            findText2 = "\"" + name.Replace(number, "{0}") + "\"";
            findText3 = "\"" + name.Replace(number, "%d") + "\"";
        }
        //需要检测是否代码有调用
        bool isFind = false;
        for (int k = 0; k < codeText.Count; ++k)
        {
            if (codeText[k].IndexOf(findText1) >= 0)
            {
                isFind = true;
                break;
            }
            if (!string.IsNullOrEmpty(findText2) && codeText[k].IndexOf(findText2) >= 0)
            {
                isFind = true;
                break;
            }
            if (!string.IsNullOrEmpty(findText3) && codeText[k].IndexOf(findText3) >= 0)
            {
                isFind = true;
                break;
            }
        }
        return isFind;
    }
}