using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        System.Threading.Mutex mutex;

        public App()
        {
            this.Startup += new StartupEventHandler(App_Startup);
        }

        static App()
        {
            configManager = new XmlConfigManager(Globals.PathOfUserFolder + "config.xml");
            //workspaceConfigManager 是可以变化的,不需要在这里初始化。
        }

        /// <summary>
        /// 这个事件用于处理 WPF 4.0版在对剪贴板操作时存在的 Bug。
        /// 当剪贴板被其它程序占用(监视)时,WPF 4.0 就会出现异常。微软在.net 4.5中修正了这个问题。
        /// 但为了 Windows XP 中也能使用本程序,我只能将.net 版本锁定在 4.0——这是WinXP最后能支持一个.net 版本。
        /// 
        /// 事实上,这个办法的原理是反复尝试向剪贴板进行操作,仍然可能造成UI假死,并不是个完美的解决方案。
        /// 另,有人实测使用Clipboard.SetData()方法取代Clipboard.SetText()方法比较好用。
        /// 这个还需要进一步测试。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            var comException = e.Exception as System.Runtime.InteropServices.COMException;
            if (comException != null && comException.ErrorCode == -2147221040)///OpenClipboard HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN))
                e.Handled = true;
        }

        void App_Startup(object sender, StartupEventArgs e)
        {
            var unableDoubleInstanceText = App.ConfigManager.Get("UnableDoubleInstance");
            if (string.IsNullOrWhiteSpace(unableDoubleInstanceText) || unableDoubleInstanceText.ToLower() == "true")
            {
                bool ret;
                mutex = new System.Threading.Mutex(true, Globals.AppName, out ret);

                if (!ret)
                {
                    MessageBox.Show("  已有一个程序实例运行!双开应用程序较容易造成正在编辑的文件版本混乱。\r\n  实在需要双开,请点击主界面【偏好】→【禁止双开应用程序】菜单项来解除限制。", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    //这里不能用LMessageBox.Show()方法。因为该方法对主窗口有依赖性。

                    Environment.Exit(0);
                }
            }
        }

        private static bool unableDoubleInstance = false;
        /// <summary>
        /// 禁止应用程序双开。
        /// 2017年9月9日,早就没有什么必要了。默认关闭就好。
        /// </summary>
        public static bool UnableDoubleInstance
        {
            get { return unableDoubleInstance; }
            set { unableDoubleInstance = value; }
        }

        private static XmlConfigManager configManager;
        /// <summary>
        /// 用于保存配置的Xml配置管理器。
        /// </summary>
        public static XmlConfigManager ConfigManager
        {
            get { return configManager; }
        }

        private static XmlConfigManager workspaceConfigManager = null;
        /// <summary>
        /// 工作区配置文件管理器。
        /// </summary>
        public static XmlConfigManager WorkspaceConfigManager
        {
            get
            {
                if (workspaceConfigManager == null)
                {
                    workspaceConfigManager = new XmlConfigManager(Globals.PathOfWorkspace + "Configure.xml");
                }

                return workspaceConfigManager;
            }
            set { workspaceConfigManager = value; }
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            //★,注意,以后不能开发带多参数的功能;实在必须开发这样的功能,须别作处理。

            Globals.args = e.Args;

            if (e.Args.Length > 0)
            {
                if (e.Args.Length > 1) {
                    //if (e.Args[0].Contains(' '))
                    //{
                    //    Globals.CmdParameterString = "\"" + e.Args[0] + "\"";
                    //}
                    //else Globals.CmdParameterString = e.Args[0];
                    //这个方案解决不了带空格的路径的问题。

                    StringBuilder sb = new StringBuilder();
                    foreach (var arg in e.Args)
                    {
                        sb.Append(arg);
                        sb.Append(" ");
                    }

                    Globals.CmdParameterString = sb.ToString().Trim(new char[] { ' ' });
                    if(Globals.CmdParameterString.Contains(" "))
                    {
                        Globals.CmdParameterString = "\"" + Globals.CmdParameterString + "\"";
                    }
                } else Globals.CmdParameterString = e.Args[0];
            }
            else Globals.CmdParameterString = "";
        }
    }
}