using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine.Events;
using System.IO;

public class NoMarkAbTreeView : TreeView
{
    public UnityAction<string> SelectChanged;
    private ShowNoMarkAbResource m_parent;
    public NoMarkAbTreeView(TreeViewState state, ShowNoMarkAbResource _parent) : base(state)
    {
        m_parent = _parent;
        showBorder = true;
    }

    protected override void SelectionChanged(IList<int> selectedIds)
    {
        string _key = string.Empty;

        if (selectedIds != null)
        {
            foreach (var id in selectedIds)
            {
                var item = FindItem(id, rootItem);
                if (item != null)
                {
                    _key = item.displayName;
                }
            }
        }
        if(null != SelectChanged)
        {
            SelectChanged.Invoke(_key);
        }
        
    }

    protected override TreeViewItem BuildRoot()
    {
        int depth = -1;
        var result = new TreeViewItem(0, depth, "");
        var dic = m_parent.GetDic();
        depth++;
        int i = 1;
        result.AddChild(new TreeViewItem(i, depth, "全部"));
        depth++;
        foreach (var child in dic)
        {
            i++;
            result.AddChild(new TreeViewItem(i, depth,child.Key));
        }
        return result;
    }
}

public class NoMarkAbResourceTreeView : TreeView
{

    internal static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
    {
        return new MultiColumnHeaderState(GetColumns());
    }
    private static MultiColumnHeaderState.Column[] GetColumns()
    {
        var retVal = new MultiColumnHeaderState.Column[] {
                new MultiColumnHeaderState.Column(),
                new MultiColumnHeaderState.Column(),
                new MultiColumnHeaderState.Column()
            };
        retVal[0].headerContent = new GUIContent("Asset", "Short name of asset. For full name select asset and see message below");
        retVal[0].minWidth = 50;
        retVal[0].width = 300;
        retVal[0].maxWidth = 400;
        retVal[0].headerTextAlignment = TextAlignment.Left;
        retVal[0].canSort = false;
        retVal[0].autoResize = true;

        retVal[1].headerContent = new GUIContent("Path", "Bundle name. 'auto' means asset was pulled in due to dependency");
        retVal[1].minWidth = 50;
        retVal[1].width = 300;
        retVal[1].maxWidth = 400;
        retVal[1].headerTextAlignment = TextAlignment.Left;
        retVal[1].canSort = false;
        retVal[1].autoResize = true;

        retVal[2].headerContent = new GUIContent("Size", "Size on disk");
        retVal[2].minWidth = 30;
        retVal[2].width = 100;
        retVal[2].maxWidth = 200;
        retVal[2].headerTextAlignment = TextAlignment.Left;
        retVal[2].canSort = false;
        retVal[2].autoResize = true;


        return retVal;
    }

    private ShowNoMarkAbResource m_parent;
    private string m_CurrentSelectKey = string.Empty;
    public NoMarkAbResourceTreeView(TreeViewState state, ShowNoMarkAbResource _parent) : base(state, new MultiColumnHeader(CreateDefaultMultiColumnHeaderState()))
    {
        m_parent = _parent;
        showBorder = true;
        showAlternatingRowBackgrounds = true;
    }

    public void SetCurrentSelectKey(string _key)
    {
        m_CurrentSelectKey = _key;
        Reload();
    }

    protected override void SelectionChanged(IList<int> selectedIds)
    {
        if (selectedIds == null)
            return;

        List<Object> selectedObjects = new List<Object>();
  
        foreach (var id in selectedIds)
        {
            var assetItem = FindItem(id, rootItem);
            if (assetItem != null)
            {
                Object o = AssetDatabase.LoadAssetAtPath<Object>(assetItem.displayName);
                selectedObjects.Add(o);
                Selection.activeObject = o;
            }
        }
        Selection.objects = selectedObjects.ToArray();
    }

    protected override void RowGUI(RowGUIArgs args)
    {
        for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
            CellGUI(args.GetCellRect(i), args.item , args.GetColumn(i), ref args);
    }

    private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
    {
        Color oldColor = GUI.color;
        CenterRectUsingSingleLineHeight(ref cellRect);

        switch (column)
        {
            case 0:
                {
                    string _name = Path.GetFileNameWithoutExtension(item.displayName);
                    var iconRect = new Rect(cellRect.x + 1, cellRect.y + 1, cellRect.height - 2, cellRect.height - 2);

                    Texture2D icon = AssetDatabase.GetCachedIcon(item.displayName) as Texture2D;
                    if (icon != null)
                        GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit);
                    DefaultGUI.Label(
                        new Rect(cellRect.x + iconRect.xMax + 1, cellRect.y, cellRect.width - iconRect.width, cellRect.height),
                        _name,
                        args.selected,
                        args.focused);
                }
                break;
            case 1:
                DefaultGUI.Label(cellRect, item.displayName, args.selected, args.focused);
                break;
            case 2:
                string strLen = string.Empty;
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(item.displayName);
                if (fileInfo.Exists)
                    strLen = EditorUtility.FormatBytes(fileInfo.Length);
                else
                    strLen = "--";
                DefaultGUI.Label(cellRect, strLen, args.selected, args.focused);
                break;
        }
        GUI.color = oldColor;
    }

    protected override TreeViewItem BuildRoot()
    {
        int depth = -1;
        var result = new TreeViewItem(0, depth, "");
        int len = 0;
        if (!string.IsNullOrEmpty(m_CurrentSelectKey))
        {
            Dictionary<string, List<string>> dic = m_parent.GetDic();
            depth++;
            if(m_CurrentSelectKey=="全部")
            {
                foreach (var kv in dic)
                {
                    for (int i = 0; i < kv.Value.Count; i++)
                    {
                        len++;
                        result.AddChild(new TreeViewItem(len, depth, kv.Value[i]));
                    }
                }
            }
            else
            {
                List<string> _value;
                if (dic.TryGetValue(m_CurrentSelectKey, out _value))
                {
                    if(_value.Count>0)
                    {
                        for (int i = 0; i < _value.Count; i++)
                        {
                            len++;
                            result.AddChild(new TreeViewItem(len, depth, _value[i]));
                            
                        }
                    }

                }

            }

        }

        if(len == 0)
        {
            result.AddChild(new TreeViewItem(0, 1, "空"));
        }
        return result;
    }
}

public class ShowNoMarkAbResource : EditorWindow
{
    NoMarkAbTreeView m_FloderTree;
    NoMarkAbResourceTreeView m_ResourceTree;
    bool m_ResizingHorizontalSplitter = false;
    bool m_ResizingVerticalSplitterLeft = false;
    Rect m_HorizontalSplitterRect, m_VerticalSplitterRectLeft;

    Rect m_Position;
    const float k_SplitterWidth = 3f;
    private static BuildTarget NoMarkAbBt;

    public Dictionary<string, List<string>> GetDic()
    {

        return Exporter.ShowNoABMarkResource(NoMarkAbBt, true);
    }

    
    public static void Open(BuildTarget bt)
    {

        NoMarkAbBt = bt;
        ShowNoMarkAbResource window = EditorWindow.CreateWindow<ShowNoMarkAbResource>();
        window.Init();
        window.Show();
    }
    public void Init()
    {
        m_Position = new Rect(k_SplitterWidth,
            50,
            300,
            400);

        m_HorizontalSplitterRect = new Rect(
            (int)(m_Position.x + m_Position.width ),
            m_Position.y,
            k_SplitterWidth,
            m_Position.height);

        m_VerticalSplitterRectLeft = new Rect(
            m_Position.x,
            (int)(m_Position.y + m_HorizontalSplitterRect.height ),
            position.width,
            k_SplitterWidth);
    }

    private void OnEnable()
    {

    }
    //private Dictionary<string, bool> toggle = new Dictionary<string, bool>();
     private void HandleHorizontalResize()
     { 
         EditorGUIUtility.AddCursorRect(m_HorizontalSplitterRect, MouseCursor.ResizeHorizontal);
         if (Event.current.type == EventType.MouseDown && m_HorizontalSplitterRect.Contains(Event.current.mousePosition))
             m_ResizingHorizontalSplitter = true;
 
         if (m_ResizingHorizontalSplitter)
         {
            // m_HorizontalSplitterPercent = Mathf.Clamp(Event.current.mousePosition.x / m_Position.width, 0.1f, 0.9f);
             m_HorizontalSplitterRect.x = (int)(Event.current.mousePosition.x);//m_Position.width * m_HorizontalSplitterPercent);
         }
 
         if (Event.current.type == EventType.MouseUp)
             m_ResizingHorizontalSplitter = false;
     }
 
     private void HandleVerticalResize()
     {
        m_VerticalSplitterRectLeft.width = position.width;
         EditorGUIUtility.AddCursorRect(m_VerticalSplitterRectLeft, MouseCursor.ResizeVertical);
         if (Event.current.type == EventType.MouseDown && m_VerticalSplitterRectLeft.Contains(Event.current.mousePosition))
             m_ResizingVerticalSplitterLeft = true;
 
         if (m_ResizingVerticalSplitterLeft)
         {
           //  m_VerticalSplitterPercentLeft = Mathf.Clamp(Event.current.mousePosition.y / m_HorizontalSplitterRect.height, 0.25f, 0.98f);
            m_VerticalSplitterRectLeft.y = (int)(Event.current.mousePosition.y);
            m_HorizontalSplitterRect.height = m_VerticalSplitterRectLeft.y - m_Position.y;
         }
 
 
         if (Event.current.type == EventType.MouseUp)
         {
             m_ResizingVerticalSplitterLeft = false;
         }
     }

    private void ReloadFloderTree()
    {
        if(null != m_FloderTree)
        {
            m_FloderTree.Reload();

            var selection = new List<int>();
            selection.Add(1);
            m_FloderTree.SetSelection(selection, TreeViewSelectionOptions.FireSelectionChanged);
        }
    }

    private void OnGUI()
    {
        if (null == m_FloderTree)
        {
            m_ResourceTree = new NoMarkAbResourceTreeView(new TreeViewState(), this);
            m_ResourceTree.SetCurrentSelectKey("");


            m_FloderTree = new NoMarkAbTreeView(new TreeViewState(), this);
            m_FloderTree.SelectChanged += (string _key) =>
            {
                m_ResourceTree.SetCurrentSelectKey(_key);
            };
            ReloadFloderTree();
        }
        HandleHorizontalResize();
        HandleVerticalResize();

        var bundleTreeRect = new Rect(
             m_Position.x,
                    m_Position.y,
                    m_HorizontalSplitterRect.x,
                    m_VerticalSplitterRectLeft.y - m_Position.y);

            m_FloderTree.OnGUI(bundleTreeRect);

        float panelLeft = m_HorizontalSplitterRect.x + k_SplitterWidth + k_SplitterWidth;
        float panelWidth = position.width - (m_HorizontalSplitterRect.x + k_SplitterWidth + k_SplitterWidth + k_SplitterWidth);
        float panelTop = m_Position.y;
        float panelHeight = m_VerticalSplitterRectLeft.y - panelTop;


        m_ResourceTree.OnGUI(new Rect(
            panelLeft,
            panelTop,
            panelWidth,
            panelHeight));


        EditorGUILayout.Space(5);
        EditorGUILayout.BeginVertical();
        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("刷新", GUILayout.Height(36), GUILayout.Width(120)))
        {
            ReloadFloderTree();
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.EndVertical();

        if (m_ResizingHorizontalSplitter || m_ResizingVerticalSplitterLeft)
            Repaint();

    }
}
