using System;
using System.Collections.Generic;
using System.IO;

using UnityEditor;
using UnityEngine;

using Codice.Client.Common;
using Codice.Client.Common.EventTracking;
using Codice.Client.Common.WebApi;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.CloudDrive;
using PlasticGui.CloudDrive.Workspaces;
using PlasticGui.WorkspaceWindow.Items;
using Unity.PlasticSCM.Editor.AssetUtils;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace;
using Unity.PlasticSCM.Editor.CloudDrive.Workspaces.DirectoryContent;
using Unity.PlasticSCM.Editor.CloudDrive.Workspaces.DragAndDrop;
using Unity.PlasticSCM.Editor.CloudDrive.Workspaces.Tree;
using Unity.PlasticSCM.Editor.UI.Errors;
using Unity.PlasticSCM.Editor.UI.Progress;

#if !UNITY_6000_3_OR_NEWER
using SplitterGUILayout = Unity.PlasticSCM.Editor.UnityInternals.UnityEditor.SplitterGUILayout;
using SplitterState = Unity.PlasticSCM.Editor.UnityInternals.UnityEditor.SplitterState;
#endif

namespace Unity.PlasticSCM.Editor.CloudDrive.Workspaces
{
    internal interface IDragAndDrop
    {
        List<string> GetDragSourcePaths();

        void ClearDragTargetPath();

        void SetDragTargetPath(string path);

        void ExecuteDropAction(string[] paths);
    }

    internal class CloudWorkspacesView :
        IRefreshableView,
        INotifyUpdatePaths,
        FillOrganizationsAndProjects.INotify,
        ICloudWorkspacesOperations,
        IDragAndDrop
    {
        internal const float MIN_WIDTH =
            TREE_VIEW_MIN_SIZE +
            SPLITTER_WIDTH +
            DIRECTORY_CONTENT_MIN_SIZE;

        internal CloudWorkspacesView(
            string proposedCloudServer,
            string proposedProject,
            WorkspaceInfo workspaceToSelect,
            IPlasticWebRestApi restApi,
            IPlasticAPI plasticApi,
            IProgressControls progressControls,
            EditorWindow parentWindow)
        {
            mRestApi = restApi;
            mPlasticApi = plasticApi;
            mProgressControls = progressControls;
            mParentWindow = parentWindow;

            mFillCloudWorkspacesView = new FillCloudWorkspaces();

            InitializeProposedOrganizationProject(proposedCloudServer, proposedProject);
            BuildComponents(workspaceToSelect, parentWindow);

            mSplitterState = new SplitterState(
                SplitterSettings.Load(
                    UnityConstants.CLOUD_WORKSPACES_SPLITTER_SETTINGS_NAME,
                    new float[] { 0.25f, 0.75f }),
                new int[] { TREE_VIEW_MIN_SIZE, DIRECTORY_CONTENT_MIN_SIZE },
                new int[] { 100000, 100000 }
            );

#if UNITY_6000_3_OR_NEWER
            UnityEditor.DragAndDrop.AddDropHandlerV2(ProjectBrowserDropHandler);
#else
            UnityEditor.DragAndDrop.AddDropHandler(ProjectBrowserDropHandler);
#endif

            Refresh();
        }

        internal void SelectWorkspaceAndCopyPaths(
            string organization,
            string project,
            WorkspaceInfo wkInfo,
            string[] assetPaths,
            string dstRelativePath)
        {
            OnOrganizationSelected(organization);
            OnProjectSelected(project);
            mCloudWorkspacesTreeView.WorkspaceToSelect = wkInfo;
            mCloudWorkspacesTreeView.Reload();

            TrackFeatureUseEvent.For(
                PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
                TrackFeatureUseEvent.Features.UnityPackage.AddAssetsToCloudDrive);

            CopyPaths(
                assetPaths,
                AssetsPath.GetFullPath.ForPath(string.Concat(wkInfo.ClientPath, dstRelativePath)),
                mCloudWorkspacesTreeView,
                wkInfo,
                mParentWindow,
                this,
                beforeStartingOperationDelegate: null,
                endOperationDelegate: null,
                shouldRefreshView: true);
        }

        internal bool IsOperationRunning()
        {
            return mCloudWorkspacesTreeView.IsOperationRunning();
        }

        internal void AutoRefresh()
        {
            Refresh();
        }

        internal void OnGUI(Rect rect, bool hasFocus)
        {
            Event e = Event.current;

            if (ProcessTabKeyActionIfNeeded(e, mCloudWorkspacesTreeView))
                e.Use();

            if (ProcessF5KeyActionIfNeeded(e, this))
                e.Use();

            UpdateDirectoryContentFocusIfNeeded(
                e, mCloudWorkspacesTreeView, mDirectoryContentPanel.Rect);

            DoContentArea(
                mCloudWorkspacesTreeView,
                mDirectoryContentPanel,
                mSplitterState,
                rect.width,
                rect.height - EditorStyles.toolbar.fixedHeight,
                hasFocus);

            DoToolbar(
                GetToolbarRect(rect),
                mCloudWorkspacesTreeView.Width,
                mOrganizations,
                mProjects,
                this);
        }

        internal void OnEnable()
        {
#if UNITY_6000_3_OR_NEWER
            UnityEditor.DragAndDrop.AddDropHandlerV2(ProjectBrowserDropHandler);
#else
            UnityEditor.DragAndDrop.AddDropHandler(ProjectBrowserDropHandler);
#endif
        }

        internal void OnDisable()
        {
#if UNITY_6000_3_OR_NEWER
            UnityEditor.DragAndDrop.RemoveDropHandlerV2(ProjectBrowserDropHandler);
#else
            UnityEditor.DragAndDrop.RemoveDropHandler(ProjectBrowserDropHandler);
#endif

            SplitterSettings.Save(
                mSplitterState,
                UnityConstants.CLOUD_WORKSPACES_SPLITTER_SETTINGS_NAME);
        }

        internal void Update(EditorWindow parentWindow)
        {
            mCloudWorkspacesTreeView.Update(parentWindow);
        }

        void IRefreshableView.Refresh()
        {
            Refresh();
        }

        void INotifyUpdatePaths.RefreshViewSilently()
        {
            mFillCloudWorkspacesView.LoadExpandedTrees(
                mSelectedOrganization,
                mSelectedProject,
                mCloudWorkspacesTreeView,
                progressControls: null);
        }

        void INotifyUpdatePaths.ShowErrors(string wkName, List<ErrorMessage> errors)
        {
            ErrorsDialog.ShowDialog(
                PlasticLocalization.Name.CopyFileErrorsTitle.GetString(),
                PlasticLocalization.Name.CopyFileErrorsMessage.GetString(wkName),
                errors,
                mParentWindow);
        }

        void FillOrganizationsAndProjects.INotify.OrganizationsRetrieved(List<string> organizations)
        {
            mOrganizations = organizations;

            mSelectedOrganization = GetDefaultValue(mProposedOrganization, mOrganizations);

            if (mSelectedOrganization == null)
                return;

            OnOrganizationSelected(mSelectedOrganization);
        }

        void FillOrganizationsAndProjects.INotify.ProjectsRetrieved(List<string> projects)
        {
            mProjects = projects;
            mProjects.Insert(0, PlasticLocalization.Name.AllProjects.GetString());
            mProjects.Insert(1, string.Empty);

            mSelectedProject = GetDefaultValue(mProposedProject, mProjects);

            if (mSelectedProject == null)
                return;

            OnProjectSelected(mSelectedProject);
        }

        List<string> IDragAndDrop.GetDragSourcePaths()
        {
            return mDirectoryContentPanel.ItemsGridView.GetSelectedItemsPaths();
        }

        void IDragAndDrop.ClearDragTargetPath()
        {
            mDragTargetPath = null;
        }

        void IDragAndDrop.SetDragTargetPath(string path)
        {
            mDragTargetPath = path;
        }

        void IDragAndDrop.ExecuteDropAction(string[] paths)
        {
            WorkspaceInfo wkInfo = mCloudWorkspacesTreeView.GetSelectedWorkspaceInfo();

            TrackFeatureUseEvent.For(
                PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
                TrackFeatureUseEvent.Features.UnityPackage.CloudDriveDragToWindow);

            CopyPaths(
                paths,
                mDragTargetPath,
                mCloudWorkspacesTreeView,
                wkInfo,
                mParentWindow,
                this,
                beforeStartingOperationDelegate: null,
                endOperationDelegate: null,
                shouldRefreshView: true);
        }

        void ICloudWorkspacesOperations.DeleteItems(List<string> paths)
        {
            WorkspaceInfo wkInfo = mCloudWorkspacesTreeView.GetSelectedWorkspaceInfo();

            ProgressControlsForViews workspaceProgressControls =
                mCloudWorkspacesTreeView.GetWorkspaceProgressControls(wkInfo);

            if (workspaceProgressControls.IsOperationRunning())
            {
                GuiMessage.ShowInformation(PlasticLocalization.Name.OperationInProgress.GetString());
                return;
            }

            DeletePathsOperation.DeleteRecursively(
                paths.ToArray(),
                Path.GetFileName(wkInfo.ClientPath),
                this,
                workspaceProgressControls);
        }

        void ICloudWorkspacesOperations.ImportInProject(string[] paths, string projectPath)
        {
            WorkspaceInfo wkInfo = mCloudWorkspacesTreeView.GetSelectedWorkspaceInfo();

            TrackFeatureUseEvent.For(
                PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
                TrackFeatureUseEvent.Features.UnityPackage.CloudDriveImportToProject);

            CopyPaths(
                paths,
                AssetsPath.GetFullPath.ForPath(string.Join(ProjectPath.Get(), projectPath)),
                mCloudWorkspacesTreeView,
                wkInfo,
                mParentWindow,
                this,
                BeforeCopyPathsForProjectBrowserDropAction,
                AfterCopyPathsForProjectBrowserDropAction,
                shouldRefreshView: false);
        }

        void Refresh()
        {
            FillOrganizationsAndProjects.LoadOrganizations(
                mRestApi, mPlasticApi, mProgressControls, this);

            RefreshTree();
        }

        void RefreshTree()
        {
            mFillCloudWorkspacesView.LoadExpandedTrees(
                mSelectedOrganization,
                mSelectedProject,
                mCloudWorkspacesTreeView,
                mProgressControls);
        }

        void OnTreeViewSelectionChanged()
        {
            List<ExpandedTreeNode> selectedNodes = CloudWorkspacesSelection.
                GetSelectedNodes(mCloudWorkspacesTreeView);

            if (selectedNodes.Count != 1)
            {
                mDirectoryContentPanel.CleanItems();
                return;
            }

            mDirectoryContentPanel.UpdateItemsForDirectory(selectedNodes[0]);
        }

        DragAndDropVisualMode ProjectBrowserDropHandler(
#if UNITY_6000_3_OR_NEWER
            EntityId dragEntityId, string dropUponPath, bool perform)
#else
            int dragInstanceId, string dropUponPath, bool perform)
#endif
        {
            if (perform == false)
                return DragAndDropVisualMode.None;

            if (UnityEditor.DragAndDrop.objectReferences.Length == 0 ||
                UnityEditor.DragAndDrop.objectReferences[0] != mParentWindow)
                return DragAndDropVisualMode.None;

            WorkspaceInfo wkInfo = mCloudWorkspacesTreeView.GetSelectedWorkspaceInfo();

            TrackFeatureUseEvent.For(
                PlasticGui.Plastic.API.GetRepositorySpec(wkInfo),
                TrackFeatureUseEvent.Features.UnityPackage.CloudDriveDragToProjectView);

            CopyPaths(
                UnityEditor.DragAndDrop.paths,
                AssetsPath.GetFullPath.ForPath(dropUponPath),
                mCloudWorkspacesTreeView,
                wkInfo,
                mParentWindow,
                this,
                BeforeCopyPathsForProjectBrowserDropAction,
                AfterCopyPathsForProjectBrowserDropAction,
                shouldRefreshView: false);

            return DragAndDropVisualMode.Copy;
        }

        void BeforeCopyPathsForProjectBrowserDropAction()
        {
            if (mCopyPathsForProjectBrowserDropCount == 0)
                RefreshAsset.BeforeLongAssetOperation();

            mCopyPathsForProjectBrowserDropCount++;
        }

        void AfterCopyPathsForProjectBrowserDropAction()
        {
            if (mCopyPathsForProjectBrowserDropCount == 1)
                RefreshAsset.AfterLongAssetOperation();

            mCopyPathsForProjectBrowserDropCount--;
        }

        void OnOrganizationSelected(object organization)
        {
            mSelectedOrganization = organization.ToString();
            mProposedOrganization = mSelectedOrganization;
            mSelectedProject = null;

            PlasticGuiConfig.Get().Configuration.LastUsedCloudDriveServer = mSelectedOrganization;
            PlasticGuiConfig.Get().Save();

            mProjects.Clear();

            if (!CloudServer.IsUnityOrganization(mSelectedOrganization))
            {
                OnProjectSelected(string.Empty);
                return;
            }

            FillOrganizationsAndProjects.LoadProjects(
                mSelectedOrganization, mPlasticApi, mProgressControls, this);
        }

        void OnProjectSelected(object project)
        {
            mSelectedProject = project.ToString();
            mProposedProject = mSelectedProject;

            PlasticGuiConfig.Get().Configuration.LastUsedCloudDriveProject = mSelectedProject;
            PlasticGuiConfig.Get().Save();

            RefreshTree();
        }

        static void CopyPaths(
            string[] paths,
            string targetPath,
            CloudWorkspacesTreeView cloudWorkspacesTreeView,
            WorkspaceInfo wkInfo,
            EditorWindow parentWindow,
            INotifyUpdatePaths notify,
            Action beforeStartingOperationDelegate,
            Action endOperationDelegate,
            bool shouldRefreshView)
        {
            ProgressControlsForViews workspaceProgressControls =
                cloudWorkspacesTreeView.GetWorkspaceProgressControls(wkInfo);

            if (workspaceProgressControls.IsOperationRunning())
            {
                GuiMessage.ShowInformation(PlasticLocalization.Name.OperationInProgress.GetString());
                return;
            }

            CopyPathsOperation.CopyRecursivelyTo(
                paths,
                targetPath,
                Path.GetFileName(wkInfo.ClientPath),
                new AskUserForExistingFile(parentWindow),
                notify,
                workspaceProgressControls,
                beforeStartingOperationDelegate,
                endOperationDelegate,
                shouldRefreshView);
        }

        static bool ProcessTabKeyActionIfNeeded(
            Event e,
            CloudWorkspacesTreeView treeView)
        {
            if (!Keyboard.IsTabPressed(e))
                return false;

            if (!treeView.HasFocus())
            {
                treeView.SetFocus();
                return true;
            }

            GUI.FocusControl(null);
            return true;
        }

        static bool ProcessF5KeyActionIfNeeded(
            Event e,
            IRefreshableView view)
        {
            if (!Keyboard.IsKeyPressed(e, KeyCode.F5))
                return false;

            view.Refresh();
            return true;
        }

        static void UpdateDirectoryContentFocusIfNeeded(
            Event e,
            CloudWorkspacesTreeView treeView,
            Rect directoryContentRect)
        {
            if (e.type != EventType.MouseDown)
                return;

            if (!directoryContentRect.Contains(e.mousePosition))
                return;

            if (!treeView.HasFocus())
                return;

            GUI.FocusControl(null);
        }

        void DoContentArea(
            CloudWorkspacesTreeView cloudWorkspacesTreeView,
            DirectoryContentPanel directoryContentPanel,
            SplitterState splitterState,
            float width,
            float height,
            bool hasFocus)
        {
            SplitterGUILayout.BeginHorizontalSplit(splitterState);
            Rect treeAreaRect = GetTreeRect(width, height);
            Rect directoryContentPanelRect = GetDirectoryContentPanelRect(width, height);
            SplitterGUILayout.EndHorizontalSplit();

            DoTreeArea(cloudWorkspacesTreeView, treeAreaRect);

            directoryContentPanel.OnGUI(
                directoryContentPanelRect,
                hasFocus && !cloudWorkspacesTreeView.HasFocus());

            EditorGUI.DrawRect(
                GetSplitterRect(directoryContentPanel.Rect),
                UnityStyles.Colors.BarBorder);
        }

        void DoTreeArea(
            CloudWorkspacesTreeView cloudWorkspacesTreeView,
            Rect treeAreaRect)
        {
            Rect newDriveButtonRect = new Rect(
                treeAreaRect.x + NEW_DRIVE_BUTTON_MARGIN,
                treeAreaRect.y + NEW_DRIVE_BUTTON_MARGIN,
                treeAreaRect.width - 2 * NEW_DRIVE_BUTTON_MARGIN,
                EditorStyles.miniButton.fixedHeight + NEW_DRIVE_BUTTON_MARGIN);

            if (GUI.Button(
                newDriveButtonRect,
                PlasticLocalization.Name.NewDriveButton.GetString(),
                EditorStyles.miniButton))
            {
                WorkspaceCreationData wkCreationData = CreateWorkspaceDialog.CreateWorkspace(
                    mSelectedOrganization,
                    mSelectedProject,
                    mRestApi,
                    mPlasticApi,
                    mParentWindow);

                CreateWorkspaceOperation.CreateWorkspace(
                    wkCreationData, mPlasticApi, mProgressControls,
                    (createdWorkspace) =>
                    {
                        TrackFeatureUseEvent.For(
                            PlasticGui.Plastic.API.GetRepositorySpec(createdWorkspace),
                            TrackFeatureUseEvent.Features.UnityPackage.CloudDriveCreateWorkspaceFromNewDriveButton);

                        OnOrganizationSelected(wkCreationData.CloudServer);

                        mProposedProject = CloudProjectRepository.GetProjectName(
                            wkCreationData.WorkspaceName);

                        mCloudWorkspacesTreeView.WorkspaceToSelect = createdWorkspace;
                        mCloudWorkspacesTreeView.Reload();
                    });
            }

            Rect treeRect = new Rect(
                treeAreaRect.x,
                treeAreaRect.y + EditorStyles.miniButton.fixedHeight + 2 * NEW_DRIVE_BUTTON_MARGIN,
                treeAreaRect.width,
                treeAreaRect.height - EditorStyles.miniButton.fixedHeight - 2 * NEW_DRIVE_BUTTON_MARGIN);

            cloudWorkspacesTreeView.OnGUI(treeRect);
        }

        void DoToolbar(
            Rect rect,
            float combosAreaWidth,
            List<string> organizations,
            List<string> projects,
            IRefreshableView view)
        {
            GUILayout.BeginArea(rect);

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

            DoCombosArea(combosAreaWidth, organizations, projects);

            GUILayout.FlexibleSpace();

            DoRefreshButton(view);

            EditorGUILayout.EndHorizontal();

            GUILayout.EndArea();
        }

        void DoCombosArea(
            float combosAreaWidth,
            List<string> organizations,
            List<string> projects)
        {
            EditorGUILayout.BeginHorizontal(GUILayout.Width(combosAreaWidth));

            DoOrganizationsCombo(organizations);

            DoProjectsCombo(projects);

            EditorGUILayout.EndHorizontal();
        }

        void DoOrganizationsCombo(List<string> organizations)
        {
            GUIContent content = new GUIContent(
                PlasticLocalization.Name.OrganizationsComboBoxLabel.GetString(
                    mSelectedOrganization));

            Rect rect = GUILayoutUtility.GetRect(content, EditorStyles.toolbarPopup);

            if (GUI.Button(rect, content, EditorStyles.toolbarPopup))
            {
                GenericMenu menu = new GenericMenu();
                foreach (string option in organizations)
                {
                    menu.AddItem(
                        new GUIContent(UnityMenuItem.EscapedText(option)),
                        false,
                        OnOrganizationSelected,
                        option);
                }

                menu.DropDown(rect);
            }
        }

        void DoProjectsCombo(List<string> projects)
        {
            if (projects.Count == 0)
                return;

            GUIContent content = new GUIContent(
                PlasticLocalization.Name.ProjectsComboBoxLabel.GetString(mSelectedProject));

            Rect rect = GUILayoutUtility.GetRect(content, EditorStyles.toolbarPopup);

            if (GUI.Button(rect, content, EditorStyles.toolbarPopup))
            {
                GenericMenu menu = new GenericMenu();
                foreach (string option in projects)
                {
                    menu.AddItem(
                        new GUIContent(UnityMenuItem.EscapedText(option)),
                        false,
                        OnProjectSelected,
                        option);
                }

                menu.DropDown(rect);
            }
        }

        static void DoRefreshButton(IRefreshableView view)
        {
            if (DrawToolbarButton(
                    Images.GetRefreshIcon(),
                    PlasticLocalization.Name.RefreshButton.GetString()))
                view.Refresh();
        }

        static bool DrawToolbarButton(Texture icon, string tooltip)
        {
            return GUILayout.Button(
                new GUIContent(icon, tooltip),
                EditorStyles.toolbarButton,
                GUILayout.Width(26));
        }

        static Rect GetToolbarRect(Rect rect)
        {
            return new Rect(
                rect.x,
                rect.y,
                rect.width,
                EditorStyles.toolbar.fixedHeight);
        }

        static Rect GetSplitterRect(Rect directoryContentRect)
        {
            return new Rect(
                directoryContentRect.x,
                directoryContentRect.y,
                SPLITTER_WIDTH,
                directoryContentRect.height);
        }

        static Rect GetTreeRect(float width, float height)
        {
            Rect result = GUILayoutUtility.GetRect(
                width, height,
                GUILayout.ExpandWidth(true));

            result.y += EditorStyles.toolbar.fixedHeight;

            return result;
        }

        static Rect GetDirectoryContentPanelRect(float width, float height)
        {
            Rect result = GUILayoutUtility.GetRect(
                width, height,
                GUILayout.ExpandWidth(true));

            result.y += EditorStyles.toolbar.fixedHeight;

            return result;
        }

        static string GetDefaultValue(string proposedValue, List<string> values)
        {
            if (values.Count == 0)
                return null;

            if (!string.IsNullOrEmpty(proposedValue) && values.Contains(proposedValue))
                return proposedValue;

            return values[0];
        }

        void BuildComponents(WorkspaceInfo workspaceToSelect, EditorWindow parentWindow)
        {
            mCloudWorkspacesTreeView = new CloudWorkspacesTreeView(
                OnTreeViewSelectionChanged, mProgressControls, parentWindow);
            mCloudWorkspacesTreeView.WorkspaceToSelect = workspaceToSelect;
            mCloudWorkspacesTreeView.Reload();

            mDirectoryContentPanel = new DirectoryContentPanel(
                mCloudWorkspacesTreeView, this, this, parentWindow);
        }

        void InitializeProposedOrganizationProject(
            string proposedCloudServer, string proposedProject)
        {
            if (!string.IsNullOrEmpty(proposedCloudServer) &&
                !string.IsNullOrEmpty(proposedProject))
            {
                mProposedOrganization = proposedCloudServer;
                mProposedProject = proposedProject;
                return;
            }

            string lastUsedServer = PlasticGuiConfig.Get().Configuration.LastUsedCloudDriveServer;
            string lastUsedProject = PlasticGuiConfig.Get().Configuration.LastUsedCloudDriveProject;

            if (!string.IsNullOrEmpty(lastUsedServer) && !string.IsNullOrEmpty(lastUsedProject))
            {
                mProposedOrganization = lastUsedServer;
                mProposedProject = lastUsedProject;
                return;
            }

            GetProposedOrganizationProject.Values proposedOrganizationProject =
                GetProposedOrganizationProject.FromCloudProjectSettings();

            mProposedOrganization = proposedOrganizationProject != null ?
                proposedOrganizationProject.Organization :
                GetDefaultServer.FromConfig(mRestApi);

            mProposedProject = proposedOrganizationProject != null ?
                proposedOrganizationProject.Project :
                Application.productName;
        }

        int mCopyPathsForProjectBrowserDropCount = 0;
        string mDragTargetPath;
        CloudWorkspacesTreeView mCloudWorkspacesTreeView;
        DirectoryContentPanel mDirectoryContentPanel;

        List<string> mOrganizations = new List<string>();
        List<string> mProjects = new List<string>();
        string mProposedOrganization;
        string mProposedProject;
        string mSelectedOrganization;
        string mSelectedProject;

        readonly SplitterState mSplitterState;

        readonly FillCloudWorkspaces mFillCloudWorkspacesView;
        readonly IPlasticWebRestApi mRestApi;
        readonly IPlasticAPI mPlasticApi;
        readonly IProgressControls mProgressControls;
        readonly EditorWindow mParentWindow;

        const float SPLITTER_WIDTH = 1;
        const float NEW_DRIVE_BUTTON_MARGIN = 5;
        const int TREE_VIEW_MIN_SIZE = 139;
        const int DIRECTORY_CONTENT_MIN_SIZE =
            2 * (int)DrawItemsGridView.GRID_AREA_MARGIN +
            (int)DrawExpandedTreeNode.ICON_SIZE;
    }
}