﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using JLGames.RocketDriver.Actions.Utils;
using JLGames.RocketDriver.CSharp.Utils;
using UnityEditor;
using UnityEngine;

namespace JLGames.RocketDriver.Actions.AssetIndex
{
    [CustomEditor(typeof(DirFilesIndex))]
    class DirFilesIndexEditor : Editor
    {
        SerializedProperty m_IncludeSelf;
        SerializedProperty m_IncludeSubDir;
        SerializedProperty m_BasePath;
        SerializedProperty m_NameToPath;

        private void OnEnable()
        {
            m_IncludeSelf = serializedObject.FindProperty("m_IncludeSelf");
            m_IncludeSubDir = serializedObject.FindProperty("m_IncludeSubDir");
            m_BasePath = serializedObject.FindProperty("m_BasePath");
            m_NameToPath = serializedObject.FindProperty("m_NameToPath");
        }

        public override void OnInspectorGUI()
        {
            EditorGUILayout.PropertyField(m_IncludeSelf);
            EditorGUILayout.PropertyField(m_IncludeSubDir);
            EditorGUILayout.PropertyField(m_BasePath);
            AddUpdateButton();
            GUI.enabled = false;
            EditorGUILayout.PropertyField(m_NameToPath, new GUIContent("List"));
            GUI.enabled = true;
            serializedObject.ApplyModifiedProperties();
        }

        private void AddUpdateButton()
        {
            if (GUILayout.Button("Update"))
            {
                UpdateIndex();
            }
        }

        private void UpdateIndex()
        {
            m_NameToPath.arraySize = 0;
            var files = GetFiles();
            if (null == files || files.Count == 0) return;
            m_NameToPath.arraySize = files.Count;
            for (var idx = 0; idx < files.Count; idx++)
            {
                var info = files[idx];
                var ele = m_NameToPath.GetArrayElementAtIndex(idx);
                ele.FindPropertyRelative("Name").stringValue = info.Name;
                ele.FindPropertyRelative("Path").stringValue = info.Path;
            }
        }

        private List<NamePathInfo> GetFiles()
        {
            var includeSelf = m_IncludeSelf.boolValue;
            var basePathValue = m_BasePath.stringValue.Trim();
            var basePathLen = basePathValue.Length + 1;
            if (basePathValue.EndsWith("/") || basePathValue.EndsWith("\\")) basePathLen -= 1;
            var filePath = AssetDatabase.GetAssetPath(Selection.activeObject);
            var folderPath = PathUtil.GetParentDirectory(filePath);
            var files = m_IncludeSubDir.boolValue ? DirectoryUtil.GetAllFiles(folderPath) : DirectoryUtil.GetFiles(folderPath);
            if (null == files || files.Length == 0) return null;
            var list = new List<NamePathInfo>();
            foreach (var path in files)
            {
                if (path.EndsWith(".meta")) continue;
                var unityPath = UnityPathUtil.Format2UnityPath(path);
                if (!includeSelf && filePath == unityPath) continue;
                list.Add(GetInfoFromPath(unityPath, basePathLen));
            }

            list.Sort((info1, info2) => String.Compare(info1.Name, info2.Name, StringComparison.Ordinal));
            return list;
        }

        private NamePathInfo GetInfoFromPath(string path, int baseLen)
        {
            var fileInfo = new FileInfo(path);
            var lIdx = fileInfo.Name.LastIndexOf('.');
            if (-1 == lIdx)
            {
                return new NamePathInfo
                {
                    Name = fileInfo.Name,
                    Path = path.Substring(baseLen)
                };
            }

            return new NamePathInfo
            {
                Name = fileInfo.Name.Substring(0, lIdx),
                Path = path.Substring(baseLen)
            };
        }
    }
}
#endif