using DevExpress.Xpf.Core;
using DevExpress.Xpf.Docking;
using Gma.System.MouseKeyHook;
using log4net;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Shapes;
using VIZ.Framework.Common;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Plugin;
using VIZ.Package.Storage;

namespace VIZ.Package.Module
{
    /// <summary>
    /// 主视图模型
    /// </summary>
    public class MainViewModel : ViewModelBase, IMainViewService
    {
        /// <summary>
        /// 日志
        /// </summary>
        private readonly static ILog log = LogManager.GetLogger(typeof(MainViewModel));

        public MainViewModel()
        {
            // 初始化命令
            this.InitCommand();

            // 初始化消息
            this.InitMessage();

            // 初始化控制器
            this.InitController();

            // 初始化热键
            this.InitHotkey();

            // 注册服务
            ApplicationDomainEx.ServiceManager.AddService(ViewServiceKeys.MAIN_VIEW_SERVICE, this);
        }

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitCommand()
        {
            this.LoadedCommand = new VCommand(this.Loaded);
        }

        /// <summary>
        /// 初始化消息
        /// </summary>
        private void InitMessage()
        {
            ApplicationDomainEx.MessageManager.Register<ApplicationClosedMessage>(this, this.OnApplicationClosedMessage);
        }

        /// <summary>
        /// 初始化控制器
        /// </summary>
        private void InitController()
        {
            this.HotkeyController = new HotkeyController(this);
        }

        /// <summary>
        /// 初始化热键
        /// </summary>
        private void InitHotkey()
        {
            // 注册键盘钩子
            this.KeyboardMouseEvents = Hook.AppEvents();

            this.KeyboardMouseEvents.KeyDown -= KeyboardMouseEvents_KeyDown;
            this.KeyboardMouseEvents.KeyDown += KeyboardMouseEvents_KeyDown;
        }

        // ============================================================
        // Field
        // ============================================================

        /// <summary>
        /// 鼠标键盘钩子
        /// </summary>
        private IKeyboardMouseEvents KeyboardMouseEvents;

        // ============================================================
        // Service & Controller
        // ============================================================

        /// <summary>
        /// 热键控制器
        /// </summary>
        private HotkeyController HotkeyController;

        // ============================================================
        // Property
        // ============================================================

        #region ItemsSource -- 视图项

        private ObservableCollection<PluginInfo> itemsSource;
        /// <summary>
        /// 视图项
        /// </summary>
        public ObservableCollection<PluginInfo> ItemsSource
        {
            get { return itemsSource; }
            set { itemsSource = value; this.RaisePropertyChanged(nameof(ItemsSource)); }
        }

        #endregion

        #region IsEnabled -- 是否可用

        private bool isEnabled = true;
        /// <summary>
        /// 是否可用
        /// </summary>
        public bool IsEnabled
        {
            get { return isEnabled; }
            set { isEnabled = value; this.RaisePropertyChanged(nameof(IsEnabled)); }
        }

        #endregion

        // ============================================================
        // Command
        // ============================================================

        #region LoadedCommand -- 加载命令

        /// <summary>
        /// 加载命令
        /// </summary>
        public VCommand LoadedCommand { get; set; }

        /// <summary>
        /// 加载
        /// </summary>
        private void Loaded()
        {
            if (this.IsAlreadyLoaded)
                return;

            this.IsAlreadyLoaded = true;

            this.ItemsSource = ApplicationDomainEx.PluginInfos.Where(p => (p.Group == ApplicationConstants.APPLICATION_GROUP_NAME ||
                                                                           p.Group == ApplicationDomainEx.VizConfig.PluginGroup) &&
                                                                           p.PluginType == PluginType.Module).ToObservableCollection();

            // 加载布局
            this.LoadLayout();

            // 创建VizCommand窗口
            ApplicationDomainEx.VizCommandLogWindow = new VizCommandWindow();
            ApplicationDomainEx.VizCommandLogWindow.Owner = ApplicationDomainEx.MainWindow;

            // 创建Error窗口
            ApplicationDomainEx.ErrorLogWindow = new ErrorLogWindow();
            ApplicationDomainEx.ErrorLogWindow.Owner = ApplicationDomainEx.MainWindow;
        }

        #endregion

        // ============================================================
        // Message
        // ============================================================

        /// <summary>
        /// 系统关闭消息
        /// </summary>
        /// <param name="msg">消息</param>
        private void OnApplicationClosedMessage(ApplicationClosedMessage msg)
        {
            // 保存布局
            //this.SaveLayout();
        }

        // ============================================================
        // Public Function
        // ============================================================

        /// <summary>
        /// 保存布局
        /// </summary>
        public void SaveLayout()
        {
            MainView view = this.GetView<MainView>();
            if (view == null)
                return;

            string path = this.GetLayoutPath();

            // 创建布局文件文件夹
            string dir = System.IO.Path.GetDirectoryName(path);
            if (!System.IO.Directory.Exists(dir))
            {
                System.IO.Directory.CreateDirectory(dir);
            }

            view.dockLayoutManager.SaveLayoutToXml(path);
        }

        /// <summary>
        /// 加载布局
        /// </summary>
        public void LoadLayout()
        {
            MainView view = this.GetView<MainView>();
            if (view == null)
                return;

            // 获取当前布局文件路径
            string path = this.GetLayoutPath();

            if (string.IsNullOrEmpty(ApplicationDomainEx.SaveLayoutField.Path)||!File.Exists(ApplicationDomainEx.SaveLayoutField.Path))
            {
                // 如果没有布局文件，那么尝试使用默认布局文件
                if (string.IsNullOrWhiteSpace(path) || !System.IO.File.Exists(path))
                {
                    path = this.GetDefaultLayoutPath();
                }

                // 如果没有对应插件布局文件，那么尝试使用系统默认布局文件
                if (string.IsNullOrWhiteSpace(path) || !System.IO.File.Exists(path))
                {
                    path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "layout", "default_layout.xml");
                }

                // 如果布局文件不存在，那么不加载布局
                if (!System.IO.File.Exists(path))
                {
                    return;
                }
            }
            else
            {
                path = ApplicationDomainEx.SaveLayoutField.Path;
            }


            view.dockLayoutManager.RestoreLayoutFromXml(path);


        }

        /// <summary>
        /// 设置主视图是否可用
        /// </summary>
        /// <param name="isEnabled">是否可用</param>
        public void SetIsEnabled(bool isEnabled)
        {
            this.IsEnabled = isEnabled;
        }

        // ============================================================
        // Private Function
        // ============================================================

        /// <summary>
        /// 获取布局文件路径
        /// </summary>
        /// <returns>布局文件路径</returns>
        private string GetLayoutPath()
        {
            string path;

            if (string.IsNullOrWhiteSpace(ApplicationDomainEx.VizConfig.PluginGroup))
            {
                path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "layout", "layout.xml");
            }
            else
            {
                path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "layout", ApplicationDomainEx.VizConfig.PluginGroup, "layout.xml");
            }

            return path;
        }

        /// <summary>
        /// 获取默认布局文件路径
        /// </summary>
        /// <returns>默认布局文件路径</returns>
        private string GetDefaultLayoutPath()
        {
            string path;

            if (string.IsNullOrWhiteSpace(ApplicationDomainEx.VizConfig.PluginGroup))
            {
                path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "layout", "default_layout.xml");
            }
            else
            {
                path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "layout", ApplicationDomainEx.VizConfig.PluginGroup, "default_layout.xml");
            }

            return path;
        }

        /// <summary>
        /// 键盘钩子事件
        /// </summary>
        private void KeyboardMouseEvents_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            try
            {
                string key = HotkeyHelper.GetHotkey(e);

                this.HotkeyController.BeginExecute(key);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }


        // const string filter = "Configuration (*.xml)|*.xml|All files (*.*)|*.*";

        /// <summary>
        /// 导出窗口布局
        /// </summary>
        /// <param name="param"></param>
        public void ExportLayout(string param)
        {
            MainView view = this.GetView<MainView>();
            if (view == null)
                return;
            //SaveFileDialog saveFileDialog = new SaveFileDialog() { Filter = filter }; //RestoreLayoutFromXml
            //var saveResult = saveFileDialog.ShowDialog();
            //if (saveResult.HasValue && saveResult.Value)
            //    view.dockLayoutManager.SaveLayoutToXml(saveFileDialog.FileName);

            SaveLayoutView saveLayout = new SaveLayoutView();

            SaveLayoutViewModel vm = saveLayout.DataContext as SaveLayoutViewModel;

            vm.TitleName = "保存窗口布局";
            vm.view = view;

            // string createPath = "";

            //createPath = System.IO.Path.Combine(param, vm.FolderName + ".xml");

            vm.createPath = param;

            saveLayout.ShowDialog();

        }




        /// <summary>
        /// 导入窗体布局
        /// </summary>
        /// <param name="param"></param>
        public void ImportLayout(string param)
        {
            MainView view = this.GetView<MainView>();
            if (view == null)
                return;

            if (File.Exists(param))
            {
               view.dockLayoutManager.RestoreLayoutFromXml(param);
            }

        }
    }
}
