using Microsoft.Win32;
using ryCommon;
using ryCommonDb;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using WeifenLuo.WinFormsUI.Docking;
using 开发辅助工具.Manager;

namespace 开发辅助工具.Tools
{
    public partial class FrmProject : DockContent
    {
        public FrmProject(string ProjectPath)
        {
            _ProjectPath = ProjectPath;
            InitializeComponent();
            try
            {
                if (_ProjectPath == "") {  return; }
                System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
                xml.Load(_ProjectPath);
                var xmlnsm = new XmlNamespaceManager(xml.NameTable);
                xmlnsm.AddNamespace("d", xml.DocumentElement.NamespaceURI);
                var root = @"d:Project//d:PropertyGroup//d:";
                var project_name = GetValue("AssemblyName");
                if (project_name != "") { Text = project_name; }
                #region 读取图标
                var ApplicationIcon = GetValue("ApplicationIcon");
                ApplicationIcon = System.IO.Path.GetDirectoryName(_ProjectPath) + "\\" + ApplicationIcon;
                if (System.IO.File.Exists(ApplicationIcon))
                {
                    try
                    {
                        Icon = new Icon(ApplicationIcon);
                    }
                    catch
                    {
                    }
                }
                #endregion
                LoadPath();
                string GetValue(string name)
                {
                    var node = xml.SelectSingleNode(root + name, xmlnsm);
                    if (node != null)
                    {
                        return node.InnerText;
                    }
                    return "";
                }
            }
            catch { }
        }
        /// <summary>
        /// 获取毕方标准项目根路径
        /// </summary>
        /// <returns></returns>
        private string GetBFFolderPath()
        {
            var _path = _ProjectPath;
            while (true)
            {
                _path = System.IO.Path.GetDirectoryName(_path.TrimEnd('\\')).TrimEnd('\\');
                if (System.IO.File.Exists(_path + "\\查看项目.ryp"))
                {
                    return _path;
                }
                else
                {
                    if (_path.Length < 4) { break; }
                }
            }
            return "";
        }
        private void LoadPath()
        {
            var _path = GetBFFolderPath();
            if (_path!="")
            {
                var folder = _path;
                AddPath(true,"Debug输出目录", "Bin\\Debug","包含调试信息的输出目录");
                AddPath(true, "Release输出目录", "Bin\\Release", "不包含调试信息的输出目录");
                AddPath(true,"源代码目录", "Source", "含有项目源码");
                AddPath(true, "安装包目录", "Publish", "对外发布的安装文件");
                AddPath(false, " - 免安装输出包目录", "Publish\\Green", "绿色免安装版本目录,通常为zip压缩包");
                AddPath(false, " - 安装输出包目录", "Publish\\Install", "需要安装的版本目录,通常为exe压缩包");
                AddPath(false, " - 输出底包目录", "Publish\\OriginalFiles", "输出底包,保留完整的文件结构,绿色版、安装包都以此来制作");
                AddPath(false, " - 升级输出包目录", "Publish\\UpdateFile", "升级包目录,通常为zip压缩包,非完整输出包");
                AddPath(true, "帮助文件目录", "Help", "帮助文档");
                AddPath(true, "外部资源目录", "Res", "项目用到的资源备份,例外图标、图片、第三方项目");
                AddPath(false, " - 第三方组件项目", "Res\\ThirdParty", "包含第三方组件的项目");
                AddPath(false, " - 图片文件夹", "Res\\Images", "含下载的项目图片");
                AddPath(true, "更新日志", "更新日志.txt", "当前项目更新日志文件");
                AddPath(true, "更新日志", "更新日志.md", "当前项目更新日志文件");
                AddPath(true, "更新日志", "CHANGELOG.md", "当前项目更新日志文件");
                AddPath(true, "自述文件", "README.md", "当前项目自述文件");
                void AddPath(bool bold,string name,string path,string des)
                {
                    if (System.IO.File.Exists(folder + "\\" + path) || System.IO.Directory.Exists(folder + "\\" + path))
                    {
                        XPTable.Models.Row itemList = new XPTable.Models.Row
                        {
                            Tag = folder + "\\" + path
                        };
                        var cell_name = new XPTable.Models.Cell(name);
                        if(bold)
                        cell_name.ForeColor=Color.Blue;
                        else
                        { cell_name.ForeColor = Color.Tomato; }
                        itemList.Cells.Add(cell_name);
                        itemList.Cells.Add(new XPTable.Models.Cell(path));
                        var cell = new XPTable.Models.Cell(des);
                        cell.ForeColor = Color.Gray;
                        itemList.Cells.Add(cell);
                        table1.TableModel.Rows.Add(itemList);
                    }
                }
            }
        }
        string _ProjectPath = "";
        private string GetPath(string _path)
        {
            string tmp_path = _path;
            if (_path.IndexOf("..") == 0)
            {
                tmp_path = System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(_ProjectPath).Trim('\\'));
                tmp_path = tmp_path + "\\" + _path.Substring(2);
            }
            else if (_path.IndexOf(".") == 0)
            {
                tmp_path = System.IO.Path.GetDirectoryName(_ProjectPath);
                tmp_path = tmp_path + "\\" + _path.Substring(1);
            }
            else if (_path.IndexOf(":") < 0)
            {
                tmp_path = System.IO.Path.GetDirectoryName(_ProjectPath);
                tmp_path = tmp_path + "\\" + _path;
            }
            return tmp_path.Replace("\\\\", "\\");
        }
        private string GetDebugPath()
        {
            if (_ProjectPath.Length==0) { return ""; }
            if (!System.IO.File.Exists(_ProjectPath)) { return ""; }
            System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
            xml.Load(_ProjectPath);
            var xmlnsm = new XmlNamespaceManager(xml.NameTable);
            xmlnsm.AddNamespace("d", xml.DocumentElement.NamespaceURI);
            var node = xml.SelectSingleNode(@"d:Project//d:PropertyGroup//d:OutputPath", xmlnsm);
            if (node != null)
            {
                string path = node.InnerText;
                path = GetPath(path);
                return path;
            }
            return "";
        }

        private void BtnCopyCMD_Click(object sender, EventArgs e)
        {
            ryCommon.RyFiles.CopyToClip("\"" + Application.ExecutablePath + "\" ver \"$(ProjectDir)\"");
            if (_ProjectPath == "") { MessageBox.Show("当前项目无效,无法设置", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; }
            System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
            xml.Load(_ProjectPath);
            var xmlnsm = new XmlNamespaceManager(xml.NameTable);
            xmlnsm.AddNamespace("d", xml.DocumentElement.NamespaceURI);
            var node = xml.SelectSingleNode(@"d:Project//d:PropertyGroup//d:PreBuildEvent", xmlnsm);
            if (node != null)
            {
                if (node.InnerText == "")
                {
                    node.InnerText = "\"" + Application.ExecutablePath + "\" ver \"$(ProjectDir)\"";
                    xml.Save(_ProjectPath);
                }
                else
                {
                    MessageBox.Show("当前项目已经存在生成动作,为防止误删,请手工操作。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            else
            {
                XmlElement ww = xml.CreateElement("PropertyGroup", xml.DocumentElement.NamespaceURI);
                XmlElement ww2 = xml.CreateElement("PreBuildEvent", xml.DocumentElement.NamespaceURI);
                //ww.("xmlns");
                ww2.InnerText = "\"" + Application.ExecutablePath + "\" ver \"$(ProjectDir)\"";
                xml.DocumentElement.AppendChild(ww);
                ww.AppendChild(ww2);
                xml.Save(_ProjectPath);
            }
            MessageBox.Show("写入成功。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private void CloseApp()
        {
            Itrycn_Db.IsCloseConfirm = false;
            this.DockPanel.FindForm().Close();
        }
        private void BtnOpenOutput_Click(object sender, EventArgs e)
        {
            var debug_path = GetDebugPath();
            if (System.IO.Directory.Exists(debug_path))
            {
                ryCommon.RyFiles.OpenFile(debug_path);
                CloseApp();
            }
            else
            {
                MessageBox.Show("打开输出目录失败。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        /// <summary>
        /// 获取Notepad++路径
        /// </summary>
        /// <returns></returns>
        private string GetNotepadPlusPath()
        {
            var path = "";
            try
            {
                RegistryKey LMach = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
                RegistryKey softwareRun = LMach.OpenSubKey(@"SOFTWARE\Notepad++", true);
                if (softwareRun.GetValue("") != null)
                {
                    string notepad_plus_path = softwareRun.GetValue("").ToString() + "\\notepad++.exe";
                    if (System.IO.File.Exists(notepad_plus_path))
                    {
                        path = notepad_plus_path;
                    }
                }
                softwareRun.Close();
                LMach.Close();
            }
            catch
            {
            }
            return path;
        }

        private void BtnMessageBox_Click(object sender, EventArgs e)
        {
            ryCommon.RyFiles.CopyToClip("MessageBox.Show(\"这是一个测试\",\"提示\",MessageBoxButtons.OK,MessageBoxIcon.Information);");
            CloseApp();
        }

        private void BtnCustomMessageBox_Click(object sender, EventArgs e)
        {
            FrmMessageBox frm = new FrmMessageBox
            {
                Icon = Icon
            };
            if (frm.ShowDialog() == DialogResult.OK)
            {
                CloseApp();
            }
        }

        private void FrmProject_Load(object sender, EventArgs e)
        {

        }

        private void table1_DoubleClick(object sender, EventArgs e)
        {
            if (table1.SelectedItems.Length == 0) { return; }
            var path = table1.SelectedItems[0].Tag.ToString();
            if (System.IO.Directory.Exists(path))
            {
                ryCommon.RyFiles.OpenFile(path);
            }
            else if (System.IO.File.Exists(path))
            {
                if (System.IO.Path.GetExtension(path).ToLower() == ".txt")
                {
                    string notepad_plus_path = GetNotepadPlusPath();
                    if (System.IO.File.Exists(notepad_plus_path))
                    {
                        ryCommon.RyFiles.RunFile(notepad_plus_path, "\"" + path + "\"");
                    }
                    else
                    {
                        ryCommon.RyFiles.OpenFile(path);
                    }
                }
                else if (System.IO.Path.GetExtension(path).ToLower() == ".md")
                {
                    ryCommon.RyFiles.OpenFile(path);
                }
                else
                {
                    ryCommon.RyFiles.OpenFolderGotoFile(path);
                }
            }
        }
        

        private void BtnClean_Click(object sender, EventArgs e)
        {
            switch (MessageBox.Show("是否要进行清理不必要的文件,例如*.pdb", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information))
            {
                case DialogResult.No:
                    return;
            }
            var debug_path = GetDebugPath();
            if (System.IO.Directory.Exists(debug_path))
            {
                Itrycn_Db.DeleteFiles(debug_path, "*.pdb");
                Itrycn_Db.DeleteFiles(debug_path, "*.dcu");
            }
            var folder = GetBFFolderPath();
            if(folder!="")
            {
                if(System.IO.Directory.Exists(folder + "\\Bin\\Release"))
                {
                    Itrycn_Db.DeleteFiles(folder + "\\Bin\\Release", "*.pdb");
                    Itrycn_Db.DeleteFiles(folder + "\\Bin\\Release", "*.dcu");
                }
            }
            MessageBox.Show("清理完成。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        /// <summary>
        /// 等待进程执行完毕
        /// </summary>
        /// <param name="cmd_text"></param>
        /// <returns></returns>
        public static string Read_Prog(string exe,string cmd_text)
        {
            String cmd = exe;
            Process p = new Process
            {
                StartInfo = new System.Diagnostics.ProcessStartInfo
                {
                    FileName = cmd,//设定程序名
                    Arguments = cmd_text,
                    UseShellExecute = false, //关闭shell的使用
                    RedirectStandardInput = true, //重定向标准输入
                    RedirectStandardOutput = true, //重定向标准输出
                    RedirectStandardError = false, //重定向错误输出
                    CreateNoWindow = true//设置不显示窗口
                }
            };
            p.Start();           
            string result = p.StandardOutput.ReadToEnd();
            p.WaitForExit(20000);
            p.Close();
            return result;
        }
        private void BtnBatchZip_Click(object sender, EventArgs e)
        {
            BtnBatchZip.Enabled = false;
            Thread th = new Thread(Start);
            th.Start();
            void Start()
            {
                RyProject project = new RyProject();
                project.OnStateChanged += Project_OnStateChanged;
                project.Pack(GetBFFolderPath());
                this.Invoke(new Action(() =>
                {
                    BtnBatchZip.Enabled = true;
                }));
            }
        }
        private void Project_OnStateChanged(object sender, string e)
        {
            this.Invoke(new Action(() =>
            {
                LblState.Text = "状态:" + e;
            }));
        }
        private void GetVersBySln(string path)
        {
            var _bf_path = GetBFFolderPath();
            RyProject project = new RyProject();
            string update_logs_text = "";
            if (System.IO.File.Exists(path))
            {
                ryCommon.Ini ini = new Ini(_bf_path + "\\查看项目.ryp");
                var sln_text = ryCommon.RyFiles.ReadAllLines(path);
                for (int i = 0; i < sln_text.Length; i++)
                {
                    if(sln_text[i].StartsWith("Project"))
                    {
                        var item = sln_text[i].Replace(" = ",",").Split(',');
                        if (item.Length>=3)
                        {
                            var project_name = item[1].Trim().Trim('"');
                            var project_path =System.IO.Path.GetDirectoryName(path).TrimEnd('\\')+"\\"+item[2].Trim().Trim('"');
                            var ver = project.GetAssemblyVersion(project_path);
                            if (ver != "")
                            {
                                if(ini.ReadIni("NoVerMD", project_name,0) == 1) { continue; }
                                if (update_logs_text != "") { update_logs_text += "\r\n"; }
                                update_logs_text +="#### "+ project_name + "    V" + ver+ "\r\n暂无\r\n";
                            }
                        }
                    }
                }
            }
            if (update_logs_text != "")
            {
                if (_bf_path != "")
                {
                    var update_text = ryCommon.RyFiles.ReadAllText(_bf_path + "\\CHANGELOG.md");
                    RyFiles.WriteAllText(_bf_path+ "\\CHANGELOG.md", "### " + DateTime.Now.ToString("yyyy-MM-dd") + "更新\r\n------\r\n"+ update_logs_text + update_text, Encoding.UTF8);
                    RyFiles.OpenFile(_bf_path + "\\CHANGELOG.md");
                }
            }
        }        
        private void BtnInsertUpdate_Click(object sender, EventArgs e)
        {
            var _path = GetBFFolderPath();
            if (_path.Length>0)
            {
                var files = System.IO.Directory.GetFiles(_path+"\\Source");
                for (int i = 0; i < files.Length; i++)
                {
                    var ext = System.IO.Path.GetExtension(files[i]).ToLower();
                    if(ext==".sln")
                    {
                        GetVersBySln(files[i]);
                        return;
                    }
                }
                var dirs = System.IO.Directory.GetDirectories(_path + "\\Source");
                for (int i = 0; i < dirs.Length; i++)
                {
                    var files2 = System.IO.Directory.GetFiles(dirs[i]);
                    for (int m = 0; m < files2.Length; m++)
                    {
                        var ext = System.IO.Path.GetExtension(files2[m]).ToLower();
                        if (ext == ".sln")
                        {
                            GetVersBySln(files2[m]);
                            return;
                        }
                    }
                }
                //var sln_path = _path + "\\更新日志.md";
            }
        }

        private void BtnUpdateDll_Click(object sender, EventArgs e)
        {
            BtnUpdateDll.Enabled = false;
            var debug_path = GetDebugPath();
            int error = 0;
            var _error_str = "";
            if (System.IO.Directory.Exists(debug_path))
            {
                RyProject project = new RyProject
                {
                    CopyDllToBin = true,
                    ChangedOutputPath = false
                };
                var bf_folder = GetBFFolderPath();
                if(bf_folder!="")
                {
                    error+= project.UpdateCSproj(bf_folder+"\\Source");
                }
                else
                {
                    project.SetCSproj(_ProjectPath, "");
                }
                error +=project.UpdateDlls(debug_path,out _error_str);
            }
            BtnUpdateDll.Enabled = true;
            if (error == 0)
            {
                MessageBox.Show("更新dll完成。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("更新dll完成,共失败"+error+"项。\r\n\r\n"+ _error_str, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void BtnUpdateVer_Click(object sender, EventArgs e)
        {
            var folder = System.IO.Path.GetDirectoryName(_ProjectPath);
            Manager.RyProject.UpdateVer(folder + "\\Properties\\AssemblyInfo.cs");
            CloseApp();
        }

        private void BtnUpdateDllVer_Click(object sender, EventArgs e)
        {
            BtnUpdateDllVer.Enabled = false;
            int error = 0;
            RyProject project = new RyProject
            {
                CopyDllToBin = true,
                ChangedOutputPath = false
            };
            var bf_folder = GetBFFolderPath();
            var _error_str = "";
            if (bf_folder != "")
            {
                error += project.UpdateDlls(bf_folder + "\\Bin",out _error_str);
            }
            BtnUpdateDllVer.Enabled = true;
            if (error == 0)
            {
                MessageBox.Show("更新dll完成。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("更新dll完成,共失败" + error + "项。\r\n\r\n"+ _error_str, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void BtnRepairFolder_Click(object sender, EventArgs e)
        {
            var _path = GetBFFolderPath();
            if (_path.Length > 0)
            {
                if (!System.IO.File.Exists(_path + "\\CHANGELOG.md"))
                {
                    BtnInsertUpdate.PerformClick();
                }
                ryCommon.Ini ini = new Ini(_path + "\\查看项目.ryp");
                FrmCreateProject frm = new FrmCreateProject();
                frm.TxtFolder.Text = _path;
                frm.ChkUnCreateProject.Checked = true;
                frm.TxtProjectEngName.Text = ini.ReadIni("project", "engname");
                frm.TxtProjectName.Text = ini.ReadIni("project", "name");
                frm.StartPosition = FormStartPosition.CenterParent;
                frm.ShowDialog();
            }
        }
    }
}