using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress;
using DevExpress.XtraBars.Ribbon;
using DevExpress.LookAndFeel;
using DevExpress.XtraBars.Docking;
using HaloControls;
using DevExpress.XtraTab;
using Global;
using System.Diagnostics;
using System.IO;
//using Portal;
using System.Threading;
using HaloPlugins;
using HaloMap;

namespace Mutation
{
    public partial class Main : RibbonForm
    {
        Project project;
        CopyStruct copydata;

        public Updater Updater { get; set; }

        public Main(string[] Arguments)
        {
            InitializeComponent();
        }

        #region Form Button Code

        private void Main_Load(object sender, EventArgs e)
        {
            // Get the Date for Easter Eggs :)
            if (DateTime.Today.Month == 12 && DateTime.Today.Day == 25)
            {
                // X-mas
                this.defaultLookAndFeel1.LookAndFeel.SkinName = "Xmas 2008 Blue";
                this.defaultLookAndFeel1.LookAndFeel.SetStyle(LookAndFeelStyle.Skin, false, false);
            }
            else if (DateTime.Today.Month == 10 && DateTime.Today.Day == 31)
            {
                // Halloween
                this.defaultLookAndFeel1.LookAndFeel.SkinName = "Pumpkin";
                this.defaultLookAndFeel1.LookAndFeel.SetStyle(LookAndFeelStyle.Skin, false, false);
            }
            else if (DateTime.Today.Month == 2 && DateTime.Today.Day == 14)
            {
                // Valintines
                this.defaultLookAndFeel1.LookAndFeel.SkinName = "Valentine";
                this.defaultLookAndFeel1.LookAndFeel.SetStyle(LookAndFeelStyle.Skin, false, false);
            }

            // Init event handlers
            Global.EventHandler.OutputMessage_Event += new Global.EventHandler.OutputMessage_Handler(OutputMessage);
            Global.EventHandler.OpenTag_Event += new Global.EventHandler.OpenTag_Handler(OpenTag);
            Global.EventHandler.GetCopyData_Event += new Global.EventHandler.GetCopyData_Handler(EventHandler_GetCopyData_Event);
            Global.EventHandler.SetCopyData_Event += new Global.EventHandler.SetCopyData_Handler(EventHandler_SetCopyData_Event);

            // Create our engines
            EngineManager.Create();

            // Set Output
            textBox1.Text = "Welcome To Mutation\r\n";
            this.Text = "Mutation - " + Global.User.Alias;
        }

        private void btnQuickNewTag_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            /*
            // Quick New Tag Method
            NewTag t = new NewTag();
            t.ShowInTaskbar = false;
            t.Show();

            // Get the New Class
            string Class = t.GetTag();
            if (Class == "NONE")
                return;
            t.Close();

            // Create new Tab Page
            Stopwatch watch = new Stopwatch();
            watch.Start();
            GrimTabPage tab = new GrimTabPage(Class, true, this.xtraTabControl1);
            this.xtraTabControl1.TabPages.Add(tab);
            this.xtraTabControl1.SelectedTabPageIndex = this.xtraTabControl1.TabPages.Count - 1;

            // Output
            watch.Stop();
            MessageBox.Show(watch.Elapsed.ToString());
            textBox1.Text += Class + " Tag Created\r\n";
             * */
        }

        private void xtraTabControl1_CloseButtonClick(object sender, EventArgs e)
        {
            try { xtraTabControl1.SelectedTabPage.Dispose(); } catch { }
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Double Check our Tags are Saved
            //for (int i = 0; i < xtraTabControl1.TabPages.Count; i++)
            //{
            //    xtraTabControl1.TabPages[i].Dispose();
            //}
        }

        private void barButtonItem2_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            // Check for Open Project
            if (project != null)
            {
                MessageBox.Show("Please close the already opened project.");
                return;
            }

            // Create the new project dialog
            NewProjectDialog newProject = new NewProjectDialog(ProjectType.Decompile);
            newProject.ShowInTaskbar = false;
            newProject.ShowDialog(this);

            // Check if the project was created
            if (Global.ProjectManager.WasCreated)
            {
                // Handle project types
                if (Global.ProjectManager.Type == ProjectType.Decompile)
                {
                    // Setup project
                    project = ProjectManager.GetOpenedProject();
                    string Path = project.Files[0];
                    project.Files.Clear();

                    // Initialize progress bar
                    Updater = new Updater("Initializing...", 0, Path);
                    if (Updater.ShowDialog() == DialogResult.OK)
                    {
                        if (MessageBox.Show("Would you like to open your new project?", "Project Explorer", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            // Load
                            LoadProject();
                        }
                    }
                }
            }
        }

        void LoadProject()
        {
            // Load Into TreeView
            treeView1.Nodes.Clear();
            for (int i = 0; i < project.Tags.Count; i++)
            {
                string[] Paths = project.Tags[i].Split(new string[] { "\\" }, StringSplitOptions.None);
                int[] Indexes = new int[Paths.Length];

                // Find the Nodes
                TreeNode n = null;
                for (int x = 0; x < Paths.Length; x++)
                {
                    Indexes[x] = FindNode(treeView1, Paths[x], Indexes, x);
                    if (Indexes[x] == -1 && x == 0)
                    {
                        n = treeView1.Nodes.Add(Paths[x]);
                        Indexes[x] = n.Index; // treeView1.Nodes.Count - 1;
                        //n = treeView1.Nodes[treeView1.Nodes.Count - 1];

                        // Image Index Code
                        if (Paths[x].Contains('.'))
                        {
                            n.ImageIndex = 2;
                            n.SelectedImageIndex = 2;
                        }
                        else
                            n.ImageIndex = 0;

                    }
                    else if (Indexes[x] == -1 && x != 0)
                    {
                        n = treeView1.Nodes[Indexes[0]];
                        for (int z = 1; z < x; z++)
                        {
                            n = n.Nodes[Indexes[z]];
                        }
                        n = n.Nodes.Add(Paths[x]);
                        Indexes[x] = n.Index; // n.Nodes.Count - 1;
                        //n = n.Nodes[n.Nodes.Count - 1];

                        // Image Index Code
                        if (Paths[x].Contains('.'))
                        {
                            n.ImageIndex = 2;
                            n.SelectedImageIndex = 2;
                        }
                        else
                            n.ImageIndex = 0;
                    }
                }
            }
            treeView1.Sort();

            // Enable controls
            ToggleControls(true);

            // Output
            textBox1.Text += project.Name + " Opened\r\n";
            this.dckProjectExplorer.Text = "Project Explorer - " + project.Name;
        }

        int FindNode(TreeView tv, string Path, int[] Indexes, int x)
        {
            if (x == 0)
            {
                for (int i = 0; i < tv.Nodes.Count; i++)
                {
                    if (tv.Nodes[i].Text == Path)
                        return i;
                }
            }
            else
            {
                TreeNode n = tv.Nodes[Indexes[0]];
                for (int i = 1; i < x; i++)
                {
                    n = n.Nodes[Indexes[i]];
                }

                for (int i = 0; i < n.Nodes.Count; i++)
                {
                    if (n.Nodes[i].Text == Path)
                        return i;
                }
            }
            return -1;
        }

        void ToggleControls(bool Enabled)
        {
            // Treeview context menu
            btnImportTag.Enabled = Enabled;
        }

        private void btnNewProject_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            // Check for Open Project
            if (project != null)
            {
                MessageBox.Show("Please close the already opened project.");
                return;
            }
            
            // Create the new project dialog
            NewProjectDialog newProject = new NewProjectDialog(ProjectType.None);
            newProject.ShowInTaskbar = false;
            newProject.ShowDialog(this);

            // Check if the project was created
            if (Global.ProjectManager.WasCreated)
            {
                // Handle project types
                if (Global.ProjectManager.Type == ProjectType.Decompile)
                {
                    // Setup project
                    project = ProjectManager.GetOpenedProject();
                    string Path = project.Files[0];
                    project.Files.Clear();

                    // Initialize progress bar
                    Updater = new Updater("Initializing...", 0, Path);
                    if (Updater.ShowDialog() == DialogResult.OK)
                    {
                        if (MessageBox.Show("Would you like to open your new project?", "Project Explorer", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            // Load
                            LoadProject();
                        }
                    }
                }
            }
        }

        private void btnOpenTag_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Open
                OpenTag(ofd.FileName);
            }
        }

        private void btnOpenProject_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            // Check for Open Project
            if (project != null)
            {
                MessageBox.Show("Please close the already opened project.");
                return;
            }

            // Open
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Halo 2 Projects (*.hpr)|*.hpr";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Init Project
                project = ProjectManager.OpenProject(ofd.FileName);

                // Load
                LoadProject();

                // Output
                textBox1.Text += ofd.FileName + " Opened\r\n";
                this.dckProjectExplorer.Text = "Project Explorer - " + project.Name;
            }
        }

        private void btnQuickSettings_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Settings s = new Settings();
            s.Show();

            while (s.Visible)
                Application.DoEvents();

            this.Text = "Mutation - " + Global.User.Alias;
        }

        private void btnExit_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            // Double Check our Tags are Saved
            for (int i = 0; i < xtraTabControl1.TabPages.Count; i++)
            {
                xtraTabControl1.TabPages[i].Dispose();
            }

            Application.Exit();
        }

        private void btnClose_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            try
            {
                //((GrimTabPage)xtraTabControl1.SelectedTabPage).Dispose();
                //xtraTabControl1.SelectedTabPageIndex = xtraTabControl1.TabPages.Count - 1;
            }
            catch { }
        }

        private void btnCloseAll_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            //for (int i = 0; i < xtraTabControl1.TabPages.Count; i++)
            //{
            //    try
            //    {
            //        if (xtraTabControl1.TabPages[0].GetType() == typeof(XtraTabPage))
            //        {
            //            //((TagEditorPage)xtraTabControl1.TabPages[1]).Dispose();
            //        }
            //        else
            //        {
            //            //((TagEditorPage)xtraTabControl1.TabPages[0]).Dispose();
            //        }
            //    }
            //    catch { }
            //}
        }

        private void btnCloseProject_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (Global.ProjectManager.GetOpenedProject() != null)
            {
                // Close Tabs
                btnCloseAll_ItemClick(null, null);

                // Disable controls
                ToggleControls(false);

                // Refresh TreeView
                treeView1.Nodes.Clear();
                dckProjectExplorer.Text = "Project Explorer";
                textBox1.Text += project.Name + " Closed\r\n";
                project = null;
            }
        }

        private void btnCompile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (project != null)
            {
                //IHaloMap map = MapFactory.GetMapFromEngine(project.Engine);
                //map.Compile(project);

                // Initialize progress bar
                Updater = new Updater("Initializing...", 0);
                Updater.ShowDialog();
            }
        }

        private void btnImportTag_Click(object sender, EventArgs e)
        {
            // Search for file
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Check if we are adding this recursively
                bool Recursive = MessageBox.Show("Would you like to recusively add this tag?", "Import Tag", MessageBoxButtons.YesNo) == DialogResult.Yes;

                // Get our tag metrics
                TagMetrics metrics = project.ImportTagInit(ofd.FileName, Recursive);

                // Check metrics
                bool Overwrite = false;
                if (metrics.ExistingTags > 0)
                {
                    // Prompt the user
                    if (MessageBox.Show("Would you like to overwrite " + metrics.ExistingTags.ToString() + " tags?", "Overwrite Tags", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        Overwrite = true;
                }

                // Add tags to project
                project.ImportTagContinue(ofd.FileName, Recursive, Overwrite);

                // Save project
                project.Save();

                // Reload tags
                LoadProject();

                // Done
                MessageBox.Show("Successfully added " + metrics.NonExistingTags.ToString() + " tags!");
            }
        }

        #endregion

        #region Treeview Specific Code

        private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
        {
            if (treeView1.SelectedNode == null)
                return;

            treeView1.SelectedNode.ImageIndex = 1;
            treeView1.SelectedNode.SelectedImageIndex = 1;
        }

        private void treeView1_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            if (treeView1.SelectedNode == null)
                return;

            treeView1.SelectedNode.ImageIndex = 0;
            treeView1.SelectedNode.SelectedImageIndex = 0;
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            treeView1.SelectedNode = e.Node;
        }

        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            treeView1.SelectedNode = e.Node;
        }

        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (treeView1.SelectedNode.Text.Contains('.'))
            {
                string Path = Global.ProjectManager.GetOpenedProject().TagFolder + treeView1.SelectedNode.FullPath;
                TagEditorPage tab = new TagEditorPage();
                tab.Open(Path);
                this.xtraTabControl1.TabPages.Add(tab);
                this.xtraTabControl1.SelectedTabPageIndex = this.xtraTabControl1.TabPages.Count - 1;

                // Do we need the Portal
                /*if (treeView1.SelectedNode.FullPath.EndsWith(".render_model") ||
                    treeView1.SelectedNode.FullPath.EndsWith(".decorator") ||
                    treeView1.SelectedNode.FullPath.EndsWith(".cloth") ||
                    treeView1.SelectedNode.FullPath.EndsWith(".collision_model"))
                    LoadPortal();*/

                // Output
                textBox1.Text += Path + " Opened\r\n";
            }
        }

        #endregion

        #region Feedback Code

        private void btnComment_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Feedback f = new Feedback(0);
            f.ShowDialog();
        }

        private void btnSubmitBug_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Feedback f = new Feedback(1);
            f.ShowDialog();
        }

        #endregion

        public void LoadPortal()
        {
            // Add Control
            //controlContainer1.Controls.Clear();
            //controlContainer1.Controls.Add(new PortalPanel(Global.Globals.p.Directory + treeView1.SelectedNode.FullPath, false));

            // Start Rendering
            //((PortalPanel)controlContainer1.Controls[0]).BeginRender();
        }

        #region Event Handlers

        public void OutputMessage(string Message)
        {
            textBox1.Text += Message;
        }

        public void OpenTag(string FileName)
        {
            // Create new Tab Page
            TagEditorPage tab = new TagEditorPage();
            tab.Open(FileName);
            this.xtraTabControl1.TabPages.Add(tab);
            this.xtraTabControl1.SelectedTabPageIndex = this.xtraTabControl1.TabPages.Count - 1;

            // Output
            textBox1.Text += FileName + " Opened\r\n";
        }

        void EventHandler_SetCopyData_Event(CopyStruct CopyData)
        {
            copydata = CopyData;
        }

        CopyStruct EventHandler_GetCopyData_Event()
        {
            return copydata;
        }

        void EventHandler_UpdateProgress_Event(string Status, string Info, int Max, int Step)
        {
            Updater.Update(Status, Info, Max, Step);
        }

        void EventHandler_StepProgress_Event(string Info)
        {
            if (Info != "")
                Updater.Step(Info);
            else
                Updater.Step();
        }

        #endregion

        private void btnSave_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (this.xtraTabControl1.SelectedTabPage != null && this.xtraTabControl1.SelectedTabPage.Text != "Main")
                ((TagEditorPage)this.xtraTabControl1.SelectedTabPage).Save();
        }
    }
}
