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 HaloObjects;
using HaloMap;

namespace Mutation
{
    public partial class Main : RibbonForm
    {
        string[] Arguments;

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

        #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);
            }

            // Set Output
            textBox1.Text = "Welcome To Mutation\r\n";
            this.Text = "Mutation - " + Global.Globals.UserName;

            #region Parse Arguments
#if (Debug)
            for (int i = 0; i < Arguments.Length; i++)
            {
                //Parse
                switch (Arguments[i])
                {
                    //Open Tag
                    case "-tag":
                    {
                        // Create new Tab Page
                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        GrimTabPage tab = new GrimTabPage(Arguments[i + 1], this.xtraTabControl1);
                        this.xtraTabControl1.TabPages.Add(tab);
                        this.xtraTabControl1.SelectedTabPageIndex = this.xtraTabControl1.TabPages.Count - 1;

                        // Output
                        watch.Stop();
                        MessageBox.Show(watch.Elapsed.Seconds.ToString() + "." + watch.Elapsed.Milliseconds.ToString());
                        textBox1.Text += rguments[i + 1] + " Opened\r\n";
                        break;
                    }
                }
            }
#endif
            #endregion
        }

        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)
        {
            xtraTabControl1.SelectedTabPage.Dispose();
            try { xtraTabControl1.SelectedTabPageIndex = xtraTabControl1.TabPages.Count - 1; }
            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)
        {
            // Create the Project
            NewProjectDialog newProject = new NewProjectDialog(ProjectType.Decompile);
            newProject.ShowInTaskbar = false;
            newProject.Show();

            // Idle
            while (newProject.Visible)
                Application.DoEvents();

            // Open it?
            if (MessageBox.Show("Would you like to open your new project?", "Project Explorer", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // Check for an existing open project
                if (Globals.p != null)
                {
                    MessageBox.Show("Please close the already opened project.");
                    return;
                }
                else
                {
                    // Create a new Project
                    Global.Globals.p = new Project(Global.Globals.RecentProj);
                    Global.Globals.p.Read();
                    Global.Globals.p.IntoTreeView(treeView1);

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

        private void btnNewProject_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            NewProjectDialog newProject = new NewProjectDialog(ProjectType.None);
            newProject.ShowInTaskbar = false;
            newProject.Show();
        }

        private void btnOpenTag_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Create new Tab Page
                Stopwatch watch = new Stopwatch();
                watch.Start();
                GrimTabPage tab = new GrimTabPage(ofd.FileName, this.xtraTabControl1);
                this.xtraTabControl1.TabPages.Add(tab);
                this.xtraTabControl1.SelectedTabPageIndex = this.xtraTabControl1.TabPages.Count - 1;

                // Output
                watch.Stop();
                MessageBox.Show(watch.Elapsed.Seconds.ToString() + "." + watch.Elapsed.Milliseconds.ToString());
                textBox1.Text += ofd.FileName + " Opened\r\n";
            }
        }

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

            // Open
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Halo 2 Projects (*.h2project)|*.h2project";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                // Create a new Project
                Global.Globals.p = new Project(ofd.FileName);
                Global.Globals.p.Read();
                Global.Globals.p.IntoTreeView(treeView1);

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

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

        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))
                    {
                        ((GrimTabPage)xtraTabControl1.TabPages[1]).Dispose();
                    }
                    else
                    {
                        ((GrimTabPage)xtraTabControl1.TabPages[0]).Dispose();
                    }
                }
                catch { }
            }
        }

        private void btnCloseProject_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            // Close Tabs
            btnCloseAll_ItemClick(null, null);

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

        private void btnCompile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (Global.Globals.p != null)
            {
                //Updater u = new Updater(Global.Globals.p, Globals.p.Directory + Globals.p.Name + ".map");
                //u.ShowInTaskbar = false;
                //u.ShowDialog();

                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = "(*.map)|*.map";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    Map map = new Map(Globals.p, ofd.FileName);
                }
            }
        }

        private void btnAnalyze_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            //CompareDialog c = new CompareDialog();
            //c.Show();

            string[] Classes = new string[] { "+!#$", "nec*", "pae*", "ihe*", "hgi*", "dpi*", "piq*", "aer*", "ecs*", "/**/", ">xf<", "MooB", "PCED", "RCED", "2SGM", "MTRP", "glda", "**ia", "!tna", "dpib", "mtib", "colb", "tdsb", "rahc", "*nic", "*ulc", "dwlc", "lloc", "nloc", "oloc", "tnoc", "aerc", "lrtc", "s*cd", "*ced", "aced", "ived", "oved", "*rgd", "cbod", "effe", "roge", "piqe", " gof", "toof", "hcpf", "brag", "fdlg", "foog", "ihrg", "tmlh", " tmh", "*csh", "#duh", "gduh", "meti", "cmti", "damj", "!tpj", "snel", "ifil", "hgil", "dnsl", "pmtl", "hcam", "gtam", "gldm", "rtem", "edom", "tdpm", "ylpm", "glum", "tdhn", "ejbo", "omhp", "syhp", "vomp", "yhpp", "jorp", "3trp", "psbs", "necs", "rncs", "+xfs", "dahs", "ylis", "niks", " yks", "tils", "lcns", "!dns", "edns", "xmns", "saps", "!kps", "ecss", "tlss", "mets", "lyts", "ltdt", "kart", "*grt", "gldu", "!hgu", "ihnu", "cinu", "tinu", "chev", "ihev", "xtrv", "paew", "taew", "tigw", "ztgw", "pihw", "lgiw", "dniw", "ihpw" };

            for (int i = 0; i < Classes.Length; i++)
            {
                Handler.GetPlugin(Microsoft.VisualBasic.Strings.StrReverse(Classes[i]));
                if (Handler.DefaultName != "null")
                {
                    Plugin p = new Plugin(Handler.DefaultName, null);

                    if (p.Layout != null)
                    {
                        for (int x = 0; x < p.Layout.Fields.Length; x++)
                        {
                            if (p.Layout.Fields[x].GetType() == typeof(HaloObjects.Reflexive))
                            {
                                CheckReflexive((HaloObjects.Reflexive)p.Layout.Fields[x]);
                            }
                        }
                    }
                }
            }
            MessageBox.Show("Done!");
        }

        void CheckReflexive(HaloObjects.Reflexive r)
        {
            r.AddChunk();

            r.ChangeIndex(0);
            MetaNode[] nodes = r.DeepClone();

            int Size = 0;
            for (int i = 0; i < nodes.Length; i++)
            {
                Size += nodes[i].GetSize();

                if (nodes[i].GetType() == typeof(HaloObjects.Reflexive))
                    CheckReflexive((HaloObjects.Reflexive)nodes[i]);
            }

            if (Size != r.ChunkSize)
            {
                MessageBox.Show(r.GetName());
            }
        }

        #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.Globals.p.Directory + treeView1.SelectedNode.FullPath;
                Stopwatch watch = new Stopwatch();
                watch.Start();
                GrimTabPage tab = new GrimTabPage(Path, this.xtraTabControl1);
                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
                watch.Stop();
                //MessageBox.Show(watch.Elapsed.Seconds.ToString() + "." + watch.Elapsed.Milliseconds.ToString());
                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();
        }
    }
}
