namespace Hive.Unity.Editor
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using System.ComponentModel;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    using UnityEngine;

    enum HiveConfigStep
    {
        Step_Hive_Config
    }

    class HiveSdkSettings : EditorWindow
    {
        HiveGUI gui = new HiveGUI(windowWidth);
        private readonly static float windowWidth = 800;
        private readonly static float windowHeight = 890;
        private Rect contentRect;

        HiveStep[] steps;
        HiveConfigStep currentStep;
        HiveStep currentStepClass
        {
            get
            {
                return steps[0];
            }
        }

        public static bool checkChangedUI = false;

        public static void create()
        {
            create(true, Vector2.zero);
        }

        public static void create(bool openNewWindow, Vector2 lastPosition)
        {
            var editor = (HiveSdkSettings)EditorWindow.GetWindow(typeof(HiveSdkSettings), true, "Hive Config");
            editor.Initialize(openNewWindow, lastPosition);
            editor.Show();
        }

        public void Initialize(bool openNewWindow, Vector2 lastPosition)
        {
            // 새롭게 창을 open하는 경우 저장된 변수가 아닌 로컬 데이터를 사용하도록 처리
            if(openNewWindow)
            {
                HiveConfigXML.reload();
            }
            
            // 현재 열려있는 Unity 프로젝트창 위치 획득 후 기준값에 open
            Vector2 startPosition = lastPosition;
            if(openNewWindow)
            {
                var projectWindow = EditorWindow.GetWindow(Type.GetType("UnityEditor.ProjectBrowser,UnityEditor"));
                if(projectWindow != null)
                {
                    Rect projectWindowRect = projectWindow.position;
                    startPosition = new Vector2(projectWindowRect.x, projectWindowRect.y);
                }
            }

            // 팝업 UI의 전체 사이즈
            Vector2 editorMinSize = new Vector2(windowWidth, windowHeight);          // 디자인을 고려해 임의 설정함
            Vector2 editorMaxSize = new Vector2(windowWidth, float.MaxValue);
            this.contentRect = new Rect(startPosition, new Vector2(windowWidth * 0.9f, windowHeight));
            this.position = new Rect(startPosition, editorMinSize);
            this.minSize = editorMinSize;   // 최소
            this.maxSize = editorMaxSize;   // 최대

            this.steps = new HiveStep[] {
                new HiveConfigXmlStep(contentRect),
            };
            this.currentStep = HiveConfigStep.Step_Hive_Config;
        }

        // UI가 오픈된 상태에서 코드변경 감지 시 OnGUI가 재호출됩니다.
        // 이때 클래스 내 객체가 null이 되는 요소는 초기값을 반영해주어야
        // 열려있는 UI가 미노출되는 이슈를 대응할 수 있습니다.
        private void prepareOnGUI()
        {
            if(steps == null)
            {
                this.steps = new HiveStep[] {
                    new HiveConfigXmlStep(contentRect),
                };
            }

            if(currentStep == null)
                this.currentStep = HiveConfigStep.Step_Hive_Config;
        }

        // 새 EditorWindow가 생성될 떄 호출됩니다.
        // OnGUI() 에서 사용되는 객체 중 null 여부를 확인하여 null인 경우 값을 할당해야하는 경우 OnEnable() 에서 진행합니다. (EditorWindow 생명주기 참고)
        private void OnEnable()
        {
            prepareOnGUI();
        }

        void OnGUI()
        {
            gui.Prepare();

            // 팝업 UI 전체 구성 
            try
            {
                gui.Container(()=>{
                    HiveStep step = currentStepClass;

                    currentStep = step.dropdownMenu();
                    step.titleArea();
                    step.selectPlatformArea();
                    step.contentsArea();
                    step.buttonsArea();
                });
            }
            catch (Exception e)
            {
                HiveLogger.Log("HiveSdkSettings OnGUI Exception : " + e);
                Close(true);
            }
        }

        private void OnDestroy()
        {
            if(checkChangedUI == true)
            {
                // Editor 닫을 시 팝업으로 안내
                if (EditorUtility.DisplayDialog("Hive Config", "The option UI has changed.\nAre you sure you want to close this window?\n옵션 변경사항이 있었습니다.\n저장하지 않고 창을 닫습니다.", "Yes", "No"))
                {
                    // 'YES'
                    HiveLogger.Log("Hive Config UI closed.");
                    checkChangedUI = false;
                }
                else
                {
                    // 'NO'

                    // 팝업을 통해 취소했더라도 Unity는 이미 창을 닫는 처리를 진행했기 때문에 여기서 창을 다시 열어야 함
                    HiveLogger.Log("Hive Config UI reopen.");
                    Vector2 lastWindowPosition = position.position; // 창을 닫지 않길 원하는 경우 제자리에 reopen하기 위한 위치 확인

                    EditorApplication.delayCall += () =>
                    {
                        HiveSdkSettings.create(false, lastWindowPosition);  // 로컬 세이브 파일 사용하지 않고 UI 오픈
                    };
                }
            }
        }

        private void Close(bool forcedClose)
        {
            if(forcedClose)
            {
                checkChangedUI = false;
            }
            base.Close();
        }

    }

}