using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.OleDb;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Markup;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows.Forms;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{

    /// <summary>
    /// 主要用途:存放一些全局量。
    /// </summary>
    internal class Globals
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [静态构造方法]用于初始化相关属性值。
        /// </summary>
        static Globals()
        {
            if (pathOfMyDocuments.EndsWith("\\") == false)
            {
                pathOfMyDocuments += "\\";
            }

            if (installedPath.EndsWith("\\") == false)
            {
                installedPath += "\\";
            }

            fullPathOfApp = installedPath + appName + ".exe";

            defaultWorkspacePath = installedPath + "Workspace\\";
            var oldPathOfUserFolder = PathOfMyDocuments + OldAppName + "\\";
            pathOfUserFolder = pathOfMyDocuments + AppName.Replace(" ", "-") + "\\";

            try
            {
                if (Directory.Exists(pathOfUserFolder) == false)
                {
                    if (Directory.Exists(oldPathOfUserFolder))
                    {
                        Directory.Move(oldPathOfUserFolder, PathOfUserDictionary);
                    }
                    else Directory.CreateDirectory(pathOfUserFolder); 
                }

                pathOfWorkspace = pathOfUserFolder + "Workspace\\";
                if (Directory.Exists(pathOfWorkspace) == false)
                {
                    Directory.CreateDirectory(pathOfWorkspace);
                }
            }
            catch (Exception ex)
            {
                LMessageBox.Show("Globals类构造方法出错:无法初始化用户目录。\r\n" + ex.Message);
            }

            hhwInstalledPath = installedPath + "HHW\\Microsoft HTML Help Workshop.exe";
            hhcInstalledPath = installedPath + "HHW\\hhc.exe";
        }

        #endregion

        private static readonly string appFullPath = System.Reflection.Assembly.GetEntryAssembly().Location;
        /// <summary>
        /// [静态只读]返回应用程序全路径。
        /// </summary>
        public static string AppFullPath
        {
            get { return Globals.appFullPath; }
        }

        /// <summary>
        /// [只读]旧应用程序名。
        /// </summary>
        public static string OldAppName { get; } = "Lunar Markdown Editor";

        /// <summary>
        /// 应用程序名,一般用作消息框的标题或窗口标题。
        /// 还可用下列方法:
        /// appName = System.Reflection.Assembly.GetEntryAssembly().Location;
        /// 上面这行返回:D:\My Documents\Visual Studio 2010\Projects\LunarConcept\LunarConcept\bin\Release\LunarConpect.exe
        /// Path.GetFileName(Assembly.GetEntryAssembly().GetName().CodeBase);//返回:LunarConcept.EXE
        /// </summary>
        private static readonly string appName = ((AssemblyTitleAttribute)Assembly.
            GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false)[0]).Title;
        /// <summary>
        /// [静态只读]返回应用程序(.exe文件)的短名,不含后缀名。
        /// </summary>
        public static string AppName
        {
            get { return Globals.appName; }
        }

        private static string appFormatedName = null;
        /// <summary>
        /// [只读]返回格式化的应用程序名。
        /// 格式化规则:在应用程序名中所有大写字母前面加上空格(首字母例外)。
        /// 例如:LunarConcept。格式化后为:Lunar Concept。
        /// </summary>
        public static string AppFormatedName
        {
            get
            {
                if (appFormatedName != null) return appFormatedName;

                StringBuilder sb = new StringBuilder();
                foreach (char c in appName)
                {
                    if (c >= 'A' && c <= 'Z')
                    {
                        sb.Append(' ');
                    }
                    sb.Append(c);
                }

                appFormatedName = sb.ToString().TrimStart(new char[] { ' ' });//移除首空格。
                return appFormatedName;
            }
        }

        public static string[] args;

        private static string cmdParameterString = null;
        /// <summary>
        /// 静态属性,表示命令行参数中的第一个值。
        /// App.xmal.cs文件中Application_Startup事件处理器会写这个属性的值。
        /// 
        /// 程序启动时判断有没有传入这个属性的值,如果这个值指向一个磁盘上存在的合法文档,就以此文档初始化。
        /// </summary>
        internal static string CmdParameterString
        {
            get
            {
                if (cmdParameterString.Contains(" ") == false)
                {
                    if (cmdParameterString.StartsWith("\""))
                    {
                        cmdParameterString = cmdParameterString.Substring(1);
                    }

                    if (cmdParameterString.EndsWith("\""))
                    {
                        cmdParameterString = cmdParameterString.Substring(0, cmdParameterString.Length - 1);
                    }
                }
                else
                {
                    if (cmdParameterString.StartsWith("\"") == false)
                    {
                        cmdParameterString = "\"" + cmdParameterString;
                    }

                    if (cmdParameterString.EndsWith("\"") == false)
                    {
                        cmdParameterString += "\"";
                    }
                }

                return cmdParameterString;
            }
            set
            {
                cmdParameterString = value;
            }
        }


        /// <summary>
        /// 终于解决了输入法的问题。
        /// 原先使用WinForm的输入法控制库终究不行——取不出当前输入法名称。
        /// </summary>
        /// <param name="enable">开、关。</param>
        public static void SwitchInputMethod(bool enable)
        {
            if (MainWindow == null) return;

            if (enable)
            {
                var typeOfLanguage = new System.Globalization.CultureInfo("zh-cn");
                InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(typeOfLanguage);

                InputMethod.SetIsInputMethodEnabled(MainWindow, enable);
                InputMethod.Current.ImeState = enable ? InputMethodState.On : InputMethodState.Off;
            }
            else
            {
                var typeOfLanguage = new System.Globalization.CultureInfo("en-us");
                InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(typeOfLanguage);
            }
        }

        private static readonly string documentName = "MarkDown文件";
        /// <summary>
        /// [只读]返回程序自定义的文档类别的描述性(短)文本。
        /// ——值为“MarkDown文件”。
        /// </summary>
        public static string DocumentName
        {
            get { return Globals.documentName; }
        }

        private static readonly string extensionName = "md";
        /// <summary>
        /// [只读]返回程序自定义文档类别的后缀名。★不含“.”。
        /// ——值为“txt”。
        /// </summary>
        public static string ExtensionName
        {
            get { return Globals.extensionName; }
        }

        private static string fullPathOfApp;
        /// <summary>
        /// [只读]返回应用程序运行时的全路径。
        /// </summary>
        public static string FullPathOfApp
        {
            get { return Globals.fullPathOfApp; }
        }

        private static string installedPath = System.AppDomain.CurrentDomain.BaseDirectory;
        /// <summary>
        /// [只读]取程序“安装(运行)目录”。
        /// 不要轻易使用这个目录,因为账户安全控制的原因——可能根本无法向此目录中写入任何文件。
        /// 所以配置文件什么的都不应该放在这个目录中。
        /// </summary>
        public static string InstalledPath
        {
            get { return Globals.installedPath; }
        }

        /// <summary>
        /// InstalledPath的别名。
        /// </summary>
        public static string RunningPath
        {
            get { return Globals.installedPath; }
        }

        /// <summary>
        /// 表示当前应用程序的主窗口。
        /// </summary>
        public static MainWindow MainWindow
        {
            get
            {
                MainWindow mainWindow = App.Current.MainWindow as MainWindow;
                return mainWindow;
            }
        }

        private static string defaultWorkspacePath;
        /// <summary>
        /// 默认工作区目录路径。在程序运行目录下的“Workspace”子目录下。不可更改。
        /// </summary>
        public static string DefaultWorkspacePath
        {
            get { return Globals.defaultWorkspacePath; }
        }

        private static string pathOfWorkspace;
        /// <summary>
        /// 当前工作区目录的路径。可以更改。
        /// </summary>
        public static string PathOfWorkspace
        {
            get
            {
                if (string.IsNullOrEmpty(Globals.pathOfWorkspace))
                {
                    pathOfWorkspace = Globals.defaultWorkspacePath;
                }

                if (string.IsNullOrEmpty(pathOfWorkspace) == false && pathOfWorkspace.EndsWith("\\") == false)
                {
                    pathOfWorkspace += "\\";
                }

                return Globals.pathOfWorkspace;
            }
            set { Globals.pathOfWorkspace = value; }
        }

        /// <summary>
        /// 当前工作区目录的短名。
        /// </summary>
        public static string WorkspaceShortName
        {
            get
            {
                if (string.IsNullOrEmpty(Globals.PathOfWorkspace)) return "";

                if (Directory.Exists(Globals.PathOfWorkspace) == false) return "";

                DirectoryInfo di = new DirectoryInfo(Globals.PathOfWorkspace);
                return di.Name;
            }
        }

        private static readonly string pathOfMyDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        /// <summary>
        /// [只读]返回Windows操作系统中定义的“我的文档”这个特殊文件夹所指向的实际路径。
        /// </summary>
        public static string PathOfMyDocuments
        {
            get { return Globals.pathOfMyDocuments; }
        }

        private static string pathOfUserFolder;
        /// <summary>
        /// [只读]用户目录。
        /// </summary>
        public static string PathOfUserFolder
        {
            get { return pathOfUserFolder; }
        }

        /// <summary>
        /// 用户词典文件的完整路径名。位置在:PathOfUserFolder + "Dict.txt";
        /// </summary>
        public static string PathOfUserDictionary
        {
            get { return PathOfUserFolder + "Dict.txt"; }
        }

        /// <summary>
        /// 工作区词典文件的完整路径名。位置在:PathOfWorkspace + "Dict.txt";
        /// </summary>
        public static string PathOfWorkspaceDictionary
        {
            get { return PathOfWorkspace + "Dict.txt"; }
        }

        /// <summary>
        /// [只读]记载历史导出目录信息的文件的路径。
        /// </summary>
        public static string PathOfHistoryOutputFileFullName
        {
            get { return PathOfUserFolder + "HistoryOutport.txt"; }
        }

        /// <summary>
        /// [只读]记载历史工作区目录信息的文件的路径。
        /// </summary>
        public static string PathOfHistoryWorkspaceFileFullName
        {
            get { return PathOfUserFolder + "HistoryWorkspaces.txt"; }
        }

        /// <summary>
        /// html help workshop的安装路径。
        /// </summary>
        internal static string hhwInstalledPath;
        /// <summary>
        /// Html Help Compiler(hhc.exe)安装路径。
        /// </summary>
        internal static string hhcInstalledPath;

        private static string sysFontFamily = "SimSun";
        /// <summary>
        /// 默认系统字体名称。
        /// </summary>
        public static string SysFontFamily
        {
            get { return sysFontFamily; }
            set { sysFontFamily = value; }
        }

        /// <summary>
        /// 用于开启模拟 Vim 移动模式的按键。半秒之内连续点击两次这个键就可以开启此模式。
        /// 在此模式下,按下键盘上的部分按钮(例如:i),会返回正常编辑模式。
        /// 这个按键可以改变为Key.RightShift。
        /// </summary>
        public static Key VimKey { get; set; } = Key.LeftShift;

        /// <summary>
        /// 终于解决了输入法的问题。
        /// 原先使用WinForm的输入法控制库终究不行——取不出当前输入法名称。
        /// </summary>
        /// <param name="enable">开、关。</param>
        //public static void SwitchInputMethod(bool enable)
        //{
        //    if (MainWindow == null) return;

        //    InputMethod.SetIsInputMethodEnabled(MainWindow, false);

        //    InputMethod.Current.ImeState = enable ? InputMethodState.On : InputMethodState.Off;
        //}

    }
}