using System.Windows.Forms;
using Microsoft.Maps.MapControl.WPF;
using System;
using System.Text;
using System.IO;
using System.Xml;


namespace BingMapsWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //Set Credentials for map
            MyMapUserControl.Map.CredentialsProvider = new ApplicationIdCredentialsProvider("An8632Lv21mKI0BZtoryHceunnPYHI6Vy-qFlVDz0bQdm-UJxQdYW2A7z1Dv-2Bd");
            MyMapUserControl.Map.MouseEnter +=new System.Windows.Input.MouseEventHandler(Map_MouseEnter);
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
            this.Text = "AIXM Viewer";
        }

        private void ExpandAll()
        {
            treeView1.ExpandAll();
        }

        private void CollapseAll()
        {
            treeView1.CollapseAll();
        }

        private void AppExit()
        {
            Application.Exit();
        }

        private void VisibleTrue()
        {
            elementHost1.Visible = true;
            splitter2.Visible = true;
            treeView2.Visible = true;
            showAllToolStripMenuItem1.Visible = true;
            clearToolStripMenuItem1.Visible = true;
            resetToolStripMenuItem.Visible = true;
            listBox1.Visible = false;
        }

        private void VisibleFalse()
        {
            elementHost1.Visible = false;
            splitter2.Visible = false;
            treeView2.Visible = false;
            showAllToolStripMenuItem1.Visible = false;
            clearToolStripMenuItem1.Visible = false;
            resetToolStripMenuItem.Visible = false;
            listBox1.Visible = true;
        }

        private void MapClear()
        {
            MyMapUserControl.Map.Children.Clear();
            foreach (TreeNode tn in treeView2.Nodes)
            {
                tn.Checked = false;
                tn.ForeColor = System.Drawing.Color.Black;
            }
        }

        private void MapShowAll()
        {
            MapClear();
            foreach (TreeNode tn in treeView2.Nodes)
            {
                tn.Checked = true;
                tn.ForeColor = System.Drawing.Color.Black;
            }
        }

        private void loadToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            VisibleFalse();
            openFileDialog1.ShowDialog(this);
        }

        private void expandToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            ExpandAll();
        }

        private void collapseToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            CollapseAll();
        }

        private void exitToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            AppExit();
        }

        private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            if (!bFileLoaded) return;

            TreeNode tn;
            tn = (TreeNode)e.Node;
            Object ln = tn.Tag;
            int line = Convert.ToInt32(ln.ToString());
            MoveToLine(line);
        }

        private void treeView2_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            TreeNode tn;
            tn = (TreeNode)e.Node;
            foreach (TreeNode node in treeView2.Nodes)
                node.ForeColor = System.Drawing.Color.Black;
            if (tn.IsSelected)
                tn.ForeColor = System.Drawing.Color.OrangeRed;
            tn.Checked = true;
        }

        private void treeView2_AfterCheck(object sender, TreeViewEventArgs e)
        {
            TreeNode tn;
            tn = (TreeNode)e.Node;
            try
            {
                if (tn.Checked)
                {
                    string[] locations = tn.LastNode.LastNode.Text.ToString().Split(' ');
                    MyMapUserControl.Map.Center = new Location(Convert.ToDouble(locations[1]), Convert.ToDouble(locations[0]));
                    MyMapUserControl.Map.ZoomLevel = 14;                    
                }
                reloadPolygons();
            }
            catch (Exception)
            {
                tn.ForeColor = System.Drawing.Color.Black;
                MessageBox.Show("Chybí souřadnice pro zobrazení objektu: "+tn.Text);
                tn.Checked = false;
                reloadPolygons();
            }
        }

        private void reloadPolygons()
        {
            MyMapUserControl.Map.Children.Clear();
            bool selected = false;
            foreach (TreeNode tn in treeView2.Nodes)
            {
                if (tn.Checked)
                {
                    if (tn.ForeColor == System.Drawing.Color.OrangeRed)
                    {
                        selected = true;
                    }
                    else
                    {
                        selected = false;                        
                    }
                    string[] locations = tn.LastNode.LastNode.Text.ToString().Split(' ');
                    if (tn.Text.StartsWith("TWY"))
                        addNewPolygonTaxiway(locations,tn, selected);
                    if (tn.Text.StartsWith("RWY"))
                        addNewPolygonRunway(locations,tn, selected);
                }
            }
        }

        private void addNewPolygonRunway(string[] locations,TreeNode tn, bool selected)
        {
            MapPolygon polygon = new MapPolygon();
            System.Windows.Controls.ToolTip tt = new System.Windows.Controls.ToolTip();
            tt.Content = "Runway: "+tn.Text;
            if (tn.FirstNode.Text == "event: CLOSED")
                polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red);
            else
                polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Blue);
            if (selected)
                polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.OrangeRed);
            else
                polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
            polygon.StrokeThickness = 3;
            polygon.Opacity = 0.7;
            

            int i =Convert.ToInt16(locations.Length.ToString());
            LocationCollection collection = new LocationCollection();
            for (int n = i-1; n > 0; n=n-2)
            {
                //MessageBox.Show("cislo  " + Convert.ToDouble(locations[n].ToString()));
                double l1 = Convert.ToDouble(locations[n]);
                double l2 = Convert.ToDouble(locations[n-1]);
                Location loc = new Location(l1,l2);
                collection.Add(loc);             
            }
            polygon.Locations = collection;
            polygon.ToolTip = tt;
            MyMapUserControl.Map.Children.Add(polygon);
        }

        private void addNewPolygonTaxiway(string[] locations, TreeNode tn, bool selected)
        {
            MapPolygon polygon = new MapPolygon();
            System.Windows.Controls.ToolTip tt = new System.Windows.Controls.ToolTip();
            tt.Content = "Taxiway: "+tn.Text;
            if (tn.FirstNode.Text == "event: CLOSED")
                polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red);
            else
                polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.LightBlue);
            if (selected)
                polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.OrangeRed);
            else
                polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
            polygon.StrokeThickness = 3;
            polygon.Opacity = 0.7;


            int i = Convert.ToInt16(locations.Length.ToString());
            LocationCollection collection = new LocationCollection();
            for (int n = i - 1; n > 0; n = n - 2)
            {
                //MessageBox.Show("cislo  " + Convert.ToDouble(locations[n].ToString()));
                double l1 = Convert.ToDouble(locations[n]);
                double l2 = Convert.ToDouble(locations[n - 1]);
                Location loc = new Location(l1, l2);
                collection.Add(loc);
            }
            polygon.Locations = collection;
            polygon.ToolTip = tt;
            MyMapUserControl.Map.Children.Add(polygon);
        }

        private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
        {
            treeView1.Nodes.Clear();
            treeView2.Nodes.Clear();
            treeView3.Nodes.Clear();
            MyMapUserControl.Map.Children.Clear();
            listBox1.Items.Clear();
            TreeNodeArray.Clear();

            bFileLoaded = false;

            XMLInputFile = openFileDialog1.FileName;
            this.Text = OrigFormTitle + " ..." + XMLInputFile;
            openFileDialog1.Dispose();

            LoadFileIntoListBox();

            /*MyDelegate dlg_obj;
            dlg_obj = new MyDelegate(LoadFileIntoTreeView);
            treeView1.Invoke(dlg_obj);*/

            LoadFileIntoTreeView(1);
            CopyToTreeView();
            treeView2.Sort();
        }
        string input = "";
        Int64 platonostStart;
        Int64 platonostEnd;
        Int64 platnost;
        DateTime time = DateTime.Now;
        bool notamLoaded = false;
        string objekt = "";
        private void openFileDialog2_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
        {
            treeView3.Nodes.Clear();

            XMLInputFile = openFileDialog2.FileName;
            openFileDialog2.Dispose();

            LoadFileIntoTreeView(2);
            TreeNodeCollection nodes = treeView3.Nodes;

            try
            {
                LoadToRichBox(nodes);
                CurrentTime();
                if (elementHost1.Visible)
                {
                    trackBar1.Visible = true;
                }
                CheckValidityOfNotam();
                notamLoaded = true;
            }
            catch (Exception)
            {
                MessageBox.Show("Nepovedlo se načíst NOTAM zprávu.");
            }      

        }

        private void CurrentTime()
        {
            //time = DateTime.Now;
            string minuty = "";
            string hodiny = "";
            string den = "";
            string mesiac = "";
            string rok = time.Year.ToString();

            if (time.Day.ToString().Length == 1)
                den = "0" + time.Day.ToString();
            else
                den = time.Day.ToString();

            if (time.Month.ToString().Length == 1)
                mesiac = "0" + time.Month.ToString();
            else
                mesiac = time.Month.ToString();

            if (time.Hour.ToString().Length == 1)
                hodiny = "0" + time.Hour.ToString();
            else
                hodiny = time.Hour.ToString();

            if (time.Minute.ToString().Length == 1)
                minuty = "0" + time.Minute.ToString();
            else
                minuty = time.Minute.ToString();

            string now = rok + mesiac + den + hodiny + minuty;
            textBox1.Text = rok + "-" + mesiac + "-" + den + " " + hodiny + ":" + minuty;
            platnost = Convert.ToInt64(now);
        }

        private void CheckValidityOfNotam()
        {
            if (platnost >= platonostStart && platnost <= platonostEnd)
            {
                //richTextBox1.Visible = true;
                MyMapUserControl.TextBox1.Visibility = System.Windows.Visibility.Visible;
                foreach (TreeNode tn in treeView2.Nodes)
                {
                    if (tn.Text == objekt)
                    {
                        if (tn.FirstNode.Text == "event: CLOSED")
                            return;
                        tn.ForeColor = System.Drawing.Color.Red;
                        tn.Nodes.Add("event: CLOSED");
                        foreach (TreeNode n in tn.Nodes)
                        {
                            n.ForeColor = System.Drawing.Color.Red;
                        }
                        tn.Expand();
                        reloadPolygons();
                    }
                }
            }
            else
            {
                MyMapUserControl.TextBox1.Visibility = System.Windows.Visibility.Hidden;
                //richTextBox1.Visible = false;
                foreach (TreeNode tn in treeView2.Nodes)
                {
                    //tn.ForeColor = System.Drawing.Color.Black;
                    if (tn.FirstNode.Text == "event: CLOSED")
                    {
                        tn.FirstNode.Remove();
                        tn.Collapse();
                    }
                }
                foreach (TreeNode tn in treeView2.Nodes)
                {
                    tn.ForeColor = System.Drawing.Color.Black;
                    foreach (TreeNode n in tn.Nodes)
                    {
                        n.ForeColor = System.Drawing.Color.Black;
                    }
                }
                reloadPolygons();

            }
        }

        private void NotamAttributes(TreeNodeCollection nodes, string keyword)
        {
            foreach (TreeNode n in nodes)
            {
                    if (n.Text == keyword)
                    {
                        this.input = n.LastNode.Text.ToString();
                        //MessageBox.Show(n.LastNode.Text.ToString());
                    }
                    NotamAttributes(n.Nodes, keyword);
            }
        }

        private void LoadToRichBox(TreeNodeCollection nodes)
        {
            richTextBox1.Text = null;
            NotamAttributes(nodes, "event:scenario");
            richTextBox1.Text += ("Notam typu: " + input + "\n");
            NotamAttributes(nodes, "event:issued");
            richTextBox1.Text += ("Vydano: " + input.Substring(0, 10) + " " + input.Substring(11, 8) + "\n");
            NotamAttributes(nodes, "aixm:type");
            richTextBox1.Text += ("Notam pro objekt: " + input + " ");
            objekt = input + " ";
            NotamAttributes(nodes, "aixm:designator");
            richTextBox1.Text += (input + "\n");
            objekt += input;
            NotamAttributes(nodes, "event:effectiveStart");
            richTextBox1.Text += ("Platnost od: 20" + input.Substring(0, 2) + "-" + input.Substring(2, 2) + "-" + input.Substring(4, 2) + " " + input.Substring(6, 2) + ":" + input.Substring(8, 2) + "\n");
            platonostStart = Convert.ToInt64("20" + input);
            //MessageBox.Show(platonostStart.ToString());
            NotamAttributes(nodes, "event:effectiveEnd");
            richTextBox1.Text += ("Platnost do: 20" + input.Substring(0, 2) + "-" + input.Substring(2, 2) + "-" + input.Substring(4, 2) + " " + input.Substring(6, 2) + ":" + input.Substring(8, 2) + "\n");
            platonostEnd = Convert.ToInt64("20" + input);
            //MessageBox.Show(platonostEnd.ToString());
            NotamAttributes(nodes, "event:text");
            richTextBox1.Text += ("Notam: " + input);
            MyMapUserControl.TextBox1.Text = richTextBox1.Text;
        }
        private void LoadFileIntoTreeView(int number)
        {
            //treeview
            try
            {
                XmlTextReader reader = null;
                reader = new XmlTextReader(XMLInputFile);
                reader.WhitespaceHandling = WhitespaceHandling.None;
                string readerName = "";
                bool start_node = false;
                int depth = 0;
                TreeNode WORKINGNODE = null;
                RootNode = null;
                TreeNode AttrNode = null;
                TreeNode newNode = null;
                bool bIsEmpty = false;
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            {
                                readerName = reader.Name;
                                bIsEmpty = reader.IsEmptyElement;

                                if (!start_node)
                                {
                                    start_node = true;
                                    if (number == 1)
                                        RootNode = this.treeView1.Nodes.Add(readerName);
                                    else
                                        RootNode = this.treeView3.Nodes.Add(readerName);
                                    AssociateTag(RootNode, reader.LineNumber);
                                    RootNode.SelectedImageIndex = 0;
                                    RootNode.ImageIndex = 0;
                                    continue;
                                }
                                depth = reader.Depth;

                                if (reader.IsStartElement() && depth == 1)
                                {
                                    WORKINGNODE = RootNode.Nodes.Add(reader.Name);
                                    AssociateTag(WORKINGNODE, reader.LineNumber);
                                }
                                else
                                {
                                    TreeNode parent = WORKINGNODE;
                                    WORKINGNODE = parent.Nodes.Add(reader.Name);
                                    AssociateTag(WORKINGNODE, reader.LineNumber);
                                }

                                WORKINGNODE.SelectedImageIndex = 1;
                                WORKINGNODE.ImageIndex = 1;

                                for (int i = 0; i < reader.AttributeCount; i++)
                                {
                                    reader.MoveToAttribute(i);
                                    string rValue = reader.Value.Replace("\r\n", " ");
                                    AttrNode = WORKINGNODE.Nodes.Add(reader.Name);
                                    //								AttrNode        = WORKINGNODE.Nodes.Add(reader.Name +" = "+rValue);
                                    AssociateTag(AttrNode, reader.LineNumber);

                                    AttrNode.SelectedImageIndex = 1;
                                    AttrNode.ImageIndex = 1;
                                    TreeNode tmp = AttrNode.Nodes.Add(rValue);
                                    tmp.SelectedImageIndex = 2;
                                    tmp.ImageIndex = 2;
                                    AssociateTag(tmp, reader.LineNumber);

                                    AttrNode.SelectedImageIndex = 2;
                                    AttrNode.ImageIndex = 2;

                                }

                                if (bIsEmpty)
                                    WORKINGNODE = WORKINGNODE.Parent;
                            }
                            break;
                        case XmlNodeType.Text:
                            {
                                string rValue = reader.Value.Replace("\r\n", " ");
                                newNode = WORKINGNODE.Nodes.Add(rValue);
                                AssociateTag(newNode, reader.LineNumber);
                                newNode.SelectedImageIndex = 3;
                                newNode.ImageIndex = 3;
                            }
                            break;
                        case XmlNodeType.EndElement:
                            WORKINGNODE = WORKINGNODE.Parent;
                            break;
                    }
                }
                reader.Close();
                RootNode.Expand();

            }
            catch (Exception eee)
            {
                MessageBox.Show(eee.Message);
            }
        }

        private void CopyToTreeView()
        {
            TreeNodeCollection nodes = treeView1.Nodes;
            foreach (TreeNode n in nodes)
            {
                FindRunwayTaxiway(n);
            }
        }

        private void FindRunwayTaxiway(TreeNode treeNode)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                if (tn.Text == "aixm:TaxiwayElement")
                {
                    TreeNode tmp = (TreeNode)tn.Clone();
                    TreeNode rootNode = new TreeNode("TWY");
                    treeView2.Nodes.Add(rootNode);

                    FindPosList(rootNode, tmp);
                }
                if (tn.Text == "aixm:RunwayElement")
                {
                    TreeNode tmp = (TreeNode)tn.Clone();
                    TreeNode rootNode = new TreeNode("RWY");
                    treeView2.Nodes.Add(rootNode);

                    FindPosList(rootNode, tmp);
                }

                FindRunwayTaxiway(tn);
            }
        }

        private void FindPosList(TreeNode parent, TreeNode treeNode)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                if (tn.Text == "aixm:associatedRunway")
                {
                    FindAssociated(tn.LastNode.LastNode.Text.ToString().Substring(30, 36), parent);
                }
                if (tn.Text == "aixm:associatedTaxiway")
                {
                    FindAssociated(tn.LastNode.LastNode.Text.ToString().Substring(30, 36), parent);
                }
                if (tn.Text == "gml:posList")
                {
                    parent.Nodes.Add(tn.Text);
                    parent.LastNode.Nodes.Add(tn.LastNode.Text.ToString());
                }
                FindPosList(parent, tn);
            }
        }

        private void FindAssociated(string associated, TreeNode parent)
        {
            TreeNodeCollection nodes = treeView1.Nodes;
            foreach (TreeNode n in nodes)
            {
                FindDesignator(parent, n, associated);
            }
        }

        private void FindDesignator(TreeNode parent, TreeNode treeNode, string asso)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                if (tn.Text == asso)
                {
                    parent.Nodes.Add(tn.Parent.Text.ToString());
                    parent.LastNode.Nodes.Add(tn.Parent.LastNode.Text.ToString());
                    foreach (TreeNode n in tn.Parent.Parent.LastNode.LastNode.Nodes)
                    {
                        if (n.Text == "aixm:designator")
                        {
                            parent.Text += " " + n.LastNode.Text.ToString();
                        }
                    }
                }
                FindDesignator(parent, tn, asso);
            }
        }

        private void LoadFileIntoListBox()
        {
            // Load the xml file into a listbox.
            try
            {
                StreamReader sr = new StreamReader(XMLInputFile, Encoding.ASCII);
                sr.BaseStream.Seek(0, SeekOrigin.Begin);
                while (sr.Peek() > -1)
                {
                    string str = sr.ReadLine();
                    listBox1.Items.Add(str);
                }
                sr.Close();
                bFileLoaded = true;
                listBox1.SetSelected(1, true);
            }
            catch (Exception ee)
            {
                MessageBox.Show("Nepovedlo se načíst soubor do ListBoxu " + ee.Message);
            }
        }

        private void MoveToLine(int ln)
        {
            // Select the input line from the file in the listbox
            listBox1.SetSelected(ln - 1, true);
        }

        private void  AssociateTag(TreeNode t, int l)
        {
            // Associate a line number Tag with every node in the tree
            NodeTag = new Object();
            NodeTag = l;
            t.Tag = NodeTag;
        }

        private void Map_MouseEnter(object sender, EventArgs e)
        {
            MyMapUserControl.Map.Focus();
        }

        private void showAllToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MapShowAll();
        }

        private void clearToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MapClear();
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MapClear();
            MyMapUserControl.Map.ZoomLevel = 0;
        }

        private void mapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listBox1.Visible)
            {
                VisibleTrue();
                if (notamLoaded)
                {
                    trackBar1.Visible = true;
                }
            }
            else
            {
                VisibleFalse();
                trackBar1.Visible = false;                
            }
        }

        private void closeToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            MapClear();
            MyMapUserControl.Map.ZoomLevel = 0;
            treeView1.Nodes.Clear();
            treeView2.Nodes.Clear();
            MyMapUserControl.Map.Children.Clear();
            listBox1.Items.Clear();
            TreeNodeArray.Clear();
            this.Text = "AIXM Viewer";
            VisibleFalse();
            trackBar1.Visible = false;
        }

        private void loadToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            openFileDialog2.ShowDialog(this);
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            int interval = 30;
            if (trackBar1.Value == 0)
            {
                time = DateTime.Now;
                CurrentTime();
                timer1.Start();
                CheckValidityOfNotam();                        
            }
            for (int i = 1; i < trackBar1.Maximum; i++)
            {
                if (trackBar1.Value == i)
                {
                    timer1.Stop();
                    ChangeTime(interval);                       
                }
                interval += 30;
            }
        }
        private void ChangeTime(double minuty)
        {
            time = DateTime.Now;
            time = time.AddMinutes(minuty);
            CurrentTime();
            CheckValidityOfNotam();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            textBox1.Text = null;
            time = DateTime.Now;
            CurrentTime();
        }

        private void closeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            trackBar1.Visible = false;
            notamLoaded = false;
            richTextBox1.Text = null;
            treeView3.Nodes.Clear();
            platonostStart = 0;
            platonostEnd = 0;
            MyMapUserControl.TextBox1.Text = richTextBox1.Text;
            CheckValidityOfNotam();
        }
    }
}
