using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Resources;
using System.Threading;

namespace EduNetworkBuilder
{
    public partial class BuilderWindow : Form
    {
        public Random GameRandomGen = new Random();
        private int LastPacketID=1;
        public DebugPausePoint DebugSetting = DebugPausePoint.none;
//        public DebugPausePoint DebugSetting = DebugPausePoint.all | DebugPausePoint.dump;
        public Network myNetwork = new Network("");
        private List<Control> Buttons = new List<Control>();
        private string selectedButton = "";
        ToolTip myTooltip = new ToolTip();
        private NetworkDevice ItemClickedOn = null;
        private NetworkDevice MouseHoverOver = null;
        private Point ClickedLocation;
        DateTime LastClick = DateTime.Now;
        private string LastPath = Properties.Settings.Default.LastPath;
        private bool processing = false;
        private List<PuzzleInfo> PuzzleList = new List<PuzzleInfo>();
        private ResourceManager LanguageResources = null;
        private CultureInfo LanguageCulture = null;
        public string ChosenLanguage = "en";  //The language to try to load  
        private List<Control> HelpTopicButtons = new List<Control>();
        private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
        public bool NeedsUpdate = false; //Do we do an update next tick

        public BuilderWindow()
        {
            InitializeComponent();
            if(!Properties.Settings.Default.LanguageHasBeenChosen)
                NB.ChangeLanguage();
            LanguagifyComponents();
            //I never implimented cut/copy/paste/undo.  So we will remove them since they do nothing anyway
            cutToolStripMenuItem.Visible = false;
            copyToolStripMenuItem.Visible = false;
            pasteToolStripMenuItem.Visible = false;
            undoToolStripMenuItem.Visible = false;

            myTooltip.AutoPopDelay = 5000;
            myTooltip.InitialDelay = 1000;
            myTooltip.ReshowDelay = 500;
            // Force the ToolTip text to be displayed whether or not the form is active.
            myTooltip.ShowAlways = true;

            myTooltip.SetToolTip(rbHelp1, NB.Translate("NB_BuildWindNone"));
            myTooltip.SetToolTip(rbHelp2, NB.Translate("NB_BuildWindColor"));
            myTooltip.SetToolTip(rbHelp3, NB.Translate("NB_BuildWindMinor"));
            myTooltip.SetToolTip(rbHelp4, NB.Translate("NB_BuildWindDecent"));
            myTooltip.SetToolTip(btnHelp, NB.Translate("NB_BuildWindMsg"));
            myTooltip.SetToolTip(cbViewTitles, NB.Translate("NB_cbViewTitles"));
            myTooltip.Popup += myTooltip_Popup;
            lblStatus.Text = "";

            myNetwork.RegisterDisplayArea(pbNetworkView);

            BuildButtons();
            LayoutButtons();
            UpdateForm();
            this.KeyPreview = true;
            this.KeyUp += GenericKeyDown;

            myTimer.Interval = 10;
            myTimer.Tick += Tick;
            myTimer.Start();

            LoadPuzzleInfo();            
        }

        private void Tick(object sender, EventArgs e)
        {
            if (NeedsUpdate)
            {
                UpdateVisuals();
                NeedsUpdate = false;
            }
            myNetwork.Tick();
        }

        private void LanguagifyComponents()
        {
            msMainMenuStrip.Text = NB.Translate("NB_msMainMenuStrip");
            fileToolStripMenuItem.Text = NB.Translate("NB_fileToolStripMenuItem");
            newToolStripMenuItem.Text = NB.Translate("LBW_btnAdd");
            loadToolStripMenuItem.Text = NB.Translate("_Load");
            reloadToolStripMenuItem.Text = NB.Translate("NB_reloadToolStripMenuItem");
            saveToolStripMenuItem.Text = NB.Translate("NB_saveToolStripMenuItem");
            exitToolStripMenuItem.Text = NB.Translate("NB_exitToolStripMenuItem");
            editToolStripMenuItem.Text = NB.Translate("_Edit");
            cutToolStripMenuItem.Text = NB.Translate("NB_cutToolStripMenuItem");
            copyToolStripMenuItem.Text = NB.Translate("NB_copyToolStripMenuItem");
            pasteToolStripMenuItem.Text = NB.Translate("NB_pasteToolStripMenuItem");
            undoToolStripMenuItem.Text = NB.Translate("NB_undoToolStripMenuItem");
            optionsToolStripMenuItem.Text = NB.Translate("NB_optionsToolStripMenuItem");
            allToolStripMenuItem.Text = NB.Translate("_All");
            dHCPRequestToolStripMenuItem.Text = NB.Translate("NB_NetViewDHCP");
            clearArpTableToolStripMenuItem.Text = NB.Translate("NB_NetViewClr");
            clearIPsToolStripMenuItem.Text = NB.Translate("NB_clearIPsToolStripMenuItem");
            pingToolStripMenuItem.Text = NB.Translate("_Ping");
            helpToolStripMenuItem.Text = NB.Translate("_Help");
            helpToolStripMenuItem1.Text = NB.Translate("_Help");
            aboutToolStripMenuItem.Text = NB.Translate("NB_aboutToolStripMenuItem");
            releaseNotesToolStripMenuItem.Text = NB.Translate("NB_releaseNotesToolStripMenuItem");
            checkForUpdatesToolStripMenuItem.Text = NB.Translate("NB_checkForUpdatesToolStripMenuItem");
            samplesToolStripMenuItem.Text = NB.Translate("NB_samplesToolStripMenuItem");
            puzzlesToolStripMenuItem.Text = NB.Translate("NB_puzzlesToolStripMenuItem");
            solvedToolStripMenuItem.Text = NB.Translate("_Solved");
            dHCPToolStripMenuItem.Text = NB.Translate("_DHCP");
            oneNetworkToolStripMenuItem.Text = NB.Translate("NB_OneNetwork");
            twoNetworksToolStripMenuItem.Text = NB.Translate("NB_TwoNetworks");
            threeNetworksToolStripMenuItem.Text = NB.Translate("NB_ThreeNetworks");
            firewallsToolStripMenuItem.Text = NB.Translate("NB_Firewalls");
            toSolveToolStripMenuItem.Text = NB.Translate("NB_toSolveToolStripMenuItem");
            solvedDHCPToolStripMenuItem.Text = NB.Translate("_DHCP");
            solvedOneNetworkToolStripMenuItem.Text = NB.Translate("NB_OneNetwork");
            solvedTwoNetworksToolStripMenuItem.Text = NB.Translate("NB_TwoNetworks");
            SolvedThreeNetworksToolStripMenuItem.Text = NB.Translate("NB_ThreeNetworks");
            firewallsToolStripMenuItem1.Text = NB.Translate("NB_Firewalls");
            lblStatus.Text = NB.Translate("NB_lblStatus");
            btnHelp.Text = NB.Translate("NB_btnHelp");
            changeLanguageToolStripMenuItem.Text = NB.Translate("NB_changeLanguageToolStripMenuItem");
            Text = NB.Translate("NB_Form");
        }

        public ResourceManager GetResource()
        {
            if(LanguageResources == null)
            {
                System.Reflection.Assembly MyAssembly;
                MyAssembly = this.GetType().Assembly;
                LanguageResources = new ResourceManager("EduNetworkBuilder.Resources.languages.edustrings", MyAssembly);
            }
            return LanguageResources;
        }

        public CultureInfo GetCulture()
        {
            if(LanguageCulture == null)
            {
                string CL = Properties.Settings.Default.ChosenLanguage;
                if (CL != ChosenLanguage) ChosenLanguage = CL;
                LanguageCulture = CultureInfo.CreateSpecificCulture(ChosenLanguage);
            }
            return LanguageCulture;
        }

        /// <summary>
        /// Look up a translate key from the resx file.
        /// </summary>
        /// <param name="Key">The string to look up</param>
        /// <returns>The translated string</returns>
        public string Translate(string Key)
        {
            ResourceManager RM = GetResource();
            CultureInfo CI = GetCulture();
            string answer;
            answer = RM.GetString(Key, CI);
            if (answer == null) return "";
            return answer;
        }

        private void GenericKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                pbNetworkView_Delete_Click(sender, e);
                ItemClickedOn = null;
            }
            if(e.KeyCode == Keys.S && e.Modifiers == Keys.Control)
            {
                doSave(true);
            }
            //MessageBox.Show(e.KeyCode.ToString());
        }

        /// <summary>
        /// Return the control with the given name.  Used primarily to color help buttons
        /// </summary>
        /// <param name="Name">The name of the control to search for</param>
        /// <returns>The control, or null if no control is found</returns>
        public Control GetControlNamed(string Name)
        {
            Control[] tList =  Controls.Find(Name, true);
            if (tList.Count() > 0) return tList[0]; //return the first one
            return null; //return nothing
        }

        private void UpdateHelpTopicButtons()
        {
            Button tButton;
            this.SuspendLayout();
            foreach(Control tCont in HelpTopicButtons)
            {
                tCont.Click -= btnRead_Click;
                Controls.Remove(tCont); //remove them all
                HelpPanel.Controls.Remove(tCont); //Remove from the panel
                tCont.Dispose();
            }
            HelpTopicButtons.Clear(); //They are all gone.

            //Make a bunch of new buttons.
            int count=0;
            int offset = btnHelp.Height + 3;
            foreach (HelpTopics HT in myNetwork.SuggestedReadings)
            {
                tButton = new Button();
                tButton.Location = new Point(btnHelp.Location.X, rbHelp1.Location.Y + rbHelp1.Height + 5 + (offset * count));
                tButton.Text = (count + 1).ToString();
                tButton.Width = btnHelp.Width;
                tButton.Height = btnHelp.Height;
                tButton.Click += btnRead_Click;
                tButton.Name = HT.ToString();
                HelpPanel.Controls.Add(tButton);
                myTooltip.SetToolTip(tButton, NB.Translate("_ReadContext") + " " + NB.Translate(NB.GetHelpTopicTitle(HT)));
                HelpTopicButtons.Add(tButton);
                count++;
            }
            foreach(NetTest nt in myNetwork.NetTests)
            {
                if(nt.TheTest == NetTestType.ReadContextHelp)
                {
                    nt.ColorItemsIfNeeded(true);
                }
            }
            this.ResumeLayout();
        }

        /// <summary>
        /// Called by the context_read clicks
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRead_Click(object sender, EventArgs e)
        {
            Button me = (Button)sender;
            HelpTopics HT = NB.TryParseEnum<HelpTopics>(me.Name, HelpTopics.None);
            if(HT != HelpTopics.None)
            {
                myNetwork.NoteActionDone(NetTestType.ReadContextHelp, me.Name, NB.Translate("_Read"));
                NB.ReadContextHelp(HT);
            }
            UpdateHelpTopicButtons();
            UpdateForm();
            UpdateMenu();
        }

        private void myTooltip_Popup(Object sender, PopupEventArgs e)
        {
            //In case we have a puzzle we are trying to solve
            if (MouseHoverOver == null) return;
            bool didsomething = myNetwork.NoteActionDone(NetTestType.HelpRequest, MouseHoverOver.hostname, myNetwork.HintsToDisplay.ToString());
            if (didsomething)
            {
                UpdateVisuals();
                myNetwork.TestForCompletion(true);
            }
        }
        private void BuildButton(string btnName, Image btnImage, string tooltipString)
        {
            int size = panelChoices.Width / 2;

            Button tButton;
            tButton = new Button();
            tButton.Name = btnName;
            tButton.BackgroundImage = new Bitmap(btnImage);
            tButton.BackgroundImageLayout = ImageLayout.Zoom;
            tButton.Click += btnClick;
            tButton.Height = size;
            tButton.Width = size;
            tButton.Location = new Point(0, 0);
            Buttons.Add(tButton);
            panelChoices.Controls.Add(tButton);
            myTooltip.SetToolTip(tButton, tooltipString);
        }

        private void BuildButtons()
        {
            BuildButton("btnSwitch", Properties.Resources.Switch, NB.Translate("NB_BuildBtnSwitch"));
            BuildButton("btnHub", Properties.Resources.Hub, NB.Translate("NB_BuildBtnHub"));
            BuildButton("btnServer", Properties.Resources.Server, NB.Translate("NB_BuildBtnServer"));
            BuildButton("btnLaptop", Properties.Resources.Laptop, NB.Translate("NB_BuildBtnLaptop"));
            BuildButton("btnPC", Properties.Resources.PC, NB.Translate("NB_BuildBtnPC"));
            BuildButton("btnRouter", Properties.Resources.Router, NB.Translate("NB_BuildBtnRouter"));
            BuildButton("btnIPPhone", Properties.Resources.ip_phone, NB.Translate("NB_BuildBtnPhone"));
            BuildButton("btnFirewall", Properties.Resources.firewall, NB.Translate("NB_BuildBtnFirewall"));
            BuildButton("btnPrinter", Properties.Resources.Printer, NB.Translate("NB_BuildBtnPrinter"));
            BuildButton("btnCopier", Properties.Resources.Copier, NB.Translate("NB_BuildBtnCopier"));
            BuildButton("btnMicrowave", Properties.Resources.microwave, NB.Translate("NB_BuildBtnMicrowave"));
            BuildButton("btnFluorescent", Properties.Resources.fluorescent, NB.Translate("NB_BuildBtnLight"));
            BuildButton("btnWAP", Properties.Resources.wap, NB.Translate("NB_BuildBtnWAP"));
            BuildButton("btnWRouter", Properties.Resources.WRouter, NB.Translate("NB_BuildBtnWRouter"));
            BuildButton("btnWBridge", Properties.Resources.WBridge, NB.Translate("NB_BuildBtnBridge"));
            BuildButton("btnWRepeater", Properties.Resources.WRepeater, NB.Translate("NB_BuildBtnRepeat"));
            BuildButton("btnCellphone", Properties.Resources.cellphone, NB.Translate("NB_BuildBtnCell"));
            BuildButton("btnTablet", Properties.Resources.tablet, NB.Translate("NB_BuildBtnTablet"));
            BuildButton("btnLink", Properties.Resources.link, NB.Translate("NB_BuildBtnCable"));
            BuildButton("btnSelect", Properties.Resources.select, NB.Translate("NB_BuildBtnSelect"));
        }

        private void LayoutButtons(List<string> what)
        {
            foreach (Button btn in Buttons)
            {
                btn.Visible = false; //Hide them all
            }
            //now we place them.
            int count = 0;
            int size = panelChoices.Width / 2;
            int x, y;
            foreach (Button btn in Buttons)
            {
                if(what.Contains(btn.Name))
                {
                    x = (count % 2) * size;
                    y = (count / 2) * size;
                    btn.Location = new Point(x, y);
                    btn.Visible = true;
                    count++;
                }
                
            }
        }

        public void UpdateMessages()
        {
            //redo this later
            lbMessages.Items.Clear();
            List<string> messages = myNetwork.GetMessageStrings();
            foreach (string msg in messages)
            {
                lbMessages.Items.Add(msg);
            }
            
            if(lbMessages.Items.Count > 0)
                lbMessages.SelectedIndex = lbMessages.Items.Count-1;

        }

        public void UpdateMenu()
        {
            if (myNetwork.NetworkFilename != "")
            {
                reloadToolStripMenuItem.Enabled = true;
            }
            else
            {
                reloadToolStripMenuItem.Enabled = false;
            }
        }

        public void UpdateLinks()
        {
            bool didanything = false;
            //Remove links if needed
            didanything = didanything || myNetwork.DoAllVerifyLinks();

            //now, update wireless links if we can.
            didanything = myNetwork.DoAllAutoJoin() || didanything;

            //If we have done anything, check for tests being completed
            if (didanything)
                myNetwork.TestForCompletion(true);
        }

        public void UpdateForm()
        {
            UpdateMenu();
            UpdateMessages();
            UpdateVisuals();
            processing = true;
            cbViewTitles.Checked = myNetwork.ShowLabelsHere;
            Text = NB.Translate("NB_UpdteFrmName");
            if (myNetwork.NetTitle.GetText() != "")
                Text += ": " + myNetwork.NetTitle.GetText();
            if (myNetwork.NetMessage.GetText() != "")
            {
                btnHelp.Visible = true;
            }
            else
            {
                btnHelp.Visible = false;
            }
            if (myNetwork.NetTests.Count > 0)
            {
                rbHelp1.Visible = true;
                rbHelp2.Visible = true;
                rbHelp3.Visible = true;
                rbHelp4.Visible = true;
            }
            else
            {
                rbHelp1.Visible = false;
                rbHelp2.Visible = false;
                rbHelp3.Visible = false;
                rbHelp4.Visible = false;
            }
            switch(myNetwork.HintsToDisplay)
            {
                case NetTestVerbosity.full:
                    rbHelp4.Checked = true;
                    break;
                case NetTestVerbosity.basic:
                    rbHelp3.Checked = true;
                    break;
                case NetTestVerbosity.hints:
                    rbHelp2.Checked = true;
                    break;
                case NetTestVerbosity.none:
                    rbHelp1.Checked = true;
                    break;
            }
            UpdateHelpTopicButtons();
            processing = false;            
        }

        private void LayoutButtons()
        {
            List<string> what = new List<string>();
            foreach(Button btn in Buttons)
            {
                what.Add(btn.Name);
            }
            LayoutButtons(what);
        }

       
        private void LoadPuzzleInfo()
        {
            XmlDocument xmlDoc = new XmlDocument();
            System.Reflection.Assembly MyAssembly;
            System.String myString;
            MyAssembly = this.GetType().Assembly;
            PuzzleInfo newPuzzle;

            // Creates the ResourceManager.
            System.Resources.ResourceManager myManager = new
               System.Resources.ResourceManager("EduNetworkBuilder.Properties.Resources",
               MyAssembly);

            foreach (string str in Enum.GetNames(typeof(PuzzleNames)))
            {
                byte[] item = (byte[])myManager.GetObject(str);
                if(item == null)
                {
                    MessageBox.Show(String.Format(NB.Translate("NB_LoadPuzInfo"), str));
                    continue;
                }
                myString = new StreamReader(new MemoryStream(item), true).ReadToEnd();
                //myString = System.Text.Encoding.Default.GetString(item);
                xmlDoc.LoadXml(myString);
                newPuzzle = new PuzzleInfo();
                newPuzzle.Load(xmlDoc, str);
                PuzzleList.Add(newPuzzle);
                //Console.WriteLine("Puzzle: " + str + " " + newPuzzle.PuzzleTitle);
            }
            PuzzleList = PuzzleList.OrderBy( c=> c.Level).ThenBy(c => c.SortOrder).ThenBy(c=> c.PuzzleName).ToList();
        }

        public PuzzleInfo PuzzleInfoFromName(string PuzzleName)
        {
            foreach(PuzzleInfo pi in PuzzleList)
            {
                if (pi.PuzzleName == PuzzleName)
                    return pi;
            }
            return null;
        }
        
        public bool PuzzleLevelHasUnsolved(string LevelName)
        {
            if (Properties.Settings.Default.ScoreList == null)
                Properties.Settings.Default.ScoreList = new System.Collections.Specialized.StringCollection();

            foreach (PuzzleInfo pi in PuzzleList)
            {
                if ("Level_" + pi.Level.ToString() == LevelName)
                {
                    if (!Properties.Settings.Default.ScoreList.Contains(pi.PuzzleName))
                    {
                        return true; //We have one puzzle in the level which has not been solved
                    }
                }
            }
            return false;
        }

        public int nextPacketID()
        {
            return LastPacketID++;
        }

        public List<string> GetPuzzleTags()
        {
            List<string> PuzzleTags = new List<string>();
            List<string> LevelTags = new List<string>();
            foreach (PuzzleInfo pi in PuzzleList)
            {
                foreach(string str in pi.PuzzleTags)
                {
                    if(Regex.IsMatch(str,NB.Translate("NB_Level")))
                    {
                        if (!LevelTags.Contains(str, StringComparer.OrdinalIgnoreCase))
                            LevelTags.Add(str);
                    }
                    else
                    {
                        //if (!PuzzleTags.Contains(str, StringComparer.OrdinalIgnoreCase))
                        //    PuzzleTags.Add(str);
                    }
                }
            }
            PuzzleTags.Sort();
            LevelTags.Sort();
            LevelTags.AddRange(PuzzleTags);
            return LevelTags;
        }

        public List<string> GetPuzzleNames()
        {
            List<string> PuzzleNames = new List<string>();
            foreach (PuzzleInfo pi in PuzzleList)
            {
                PuzzleNames.Add(pi.PuzzleName);
            }
            return PuzzleNames;
        }

        private void btnClick(object sender, EventArgs e)
        {
            foreach(Control btn in Buttons)
            {
                if(btn == sender)
                {
                    //This is the selected item
                    btn.BackColor = Color.LightGreen;
                    selectedButton = btn.Name;
                    lblStatus.Text = myTooltip.GetToolTip(btn);
                }
                else
                {
                    btn.BackColor = Button.DefaultBackColor;
                }
            }
        }
        private void btnReset()
        {
            foreach (Control btn in Buttons)
            {
                lblStatus.Text = "";
                selectedButton = "";
                btn.BackColor = Button.DefaultBackColor;
            }
        }

        private void pbNetworkView_DoubleClick(object sender, EventArgs e)
        {

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void pbNetworkView_RightMouseUp(NetworkDevice ReleasedOn, MouseEventArgs e)
        { 
            int index = 0;
            bool LockedOut = false;
            if (pbNetworkView.ContextMenuStrip == null)
            {
                pbNetworkView.ContextMenuStrip = new ContextMenuStrip();
            }
            if (ReleasedOn != null) LockedOut = ReleasedOn.DeviceIsLockedOutByVLANs();
            pbNetworkView.ContextMenuStrip.Items.Clear();

            if (!LockedOut)
            {
                if (ReleasedOn != null && ReleasedOn.IsNotNetDevice())
                {
                    List<string> DoneList = new List<string>();
                    foreach (string tStr in myNetwork.GetIncompleteTestDestinations(ReleasedOn.hostname, true))
                    {
                        if (!DoneList.Contains(tStr))
                        {
                            pbNetworkView.ContextMenuStrip.Items.Add(string.Format(NB.Translate("_PingStr"), tStr));
                            pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Ping_Name_Click;
                            DoneList.Add(tStr);
                        }
                    }
                    DoneList.Clear();
                    foreach (string tStr in myNetwork.GetIncompleteTestDestinations(ReleasedOn.hostname, false))
                    {
                        if (!DoneList.Contains(tStr))
                        {
                            pbNetworkView.ContextMenuStrip.Items.Add(string.Format(NB.Translate("H_ARP_TitleStr"), tStr));
                            pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Arp_Name_Click;
                            DoneList.Add(tStr);
                        }
                    }
                }
                if (ReleasedOn != null && ReleasedOn.IsNotNetDevice())
                {
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Ping1"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Ping_Click;
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Traceroute"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Traceroute_Click;
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("H_ARP_Title"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Arp_Click;
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_NetViewClr"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_ArpClear_Click;
                }
                if (ReleasedOn != null)
                {
                    if (!myNetwork.ItemIsCritical(ReleasedOn.hostname))
                    {
                        pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Delete"));
                        pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Delete_Click;
                    }
                }
                if (ReleasedOn != null && ReleasedOn.IsNotNetDevice())
                {
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Edit"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Edit_Click;
                }

                if (ReleasedOn != null)
                {
                    ItemClickedOn = ReleasedOn;
                    if (ReleasedOn.HasDHCPNic())
                    {
                        pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_NetViewDHCP"));
                        pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_DHCPRequest_Click;
                    }
                    foreach (string host in ReleasedOn.ListOfConnectedHosts())
                    {
                        pbNetworkView.ContextMenuStrip.Items.Add(string.Format(NB.Translate("NB_NetViewRmLnkStr"), host));
                        pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_RemoveLink_Click;
                    }
                    if(ReleasedOn.PowerOff)
                    {
                        pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_PowerOn"));
                        pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_PowerOn_Click;
                    }
                    else if(ReleasedOn.ForwardsPackets() || ReleasedOn.RoutesPackets())
                    {
                        pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_PowerOff"));
                        pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_PowerOff_Click;
                    }

                }
            }
            else //we are locked out.
            {
                pbNetworkView.ContextMenuStrip.Items.Add(string.Format(NB.Translate("NB_Reset")));
                pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Reset_Click;
            }
            if (ReleasedOn != null && myNetwork.VLANsEnabled)
            {
                int MenuIndex = pbNetworkView.ContextMenuStrip.Items.Count;
                pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_ColorStr"));
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Blue"),null, pbNetworkView_Color_Click);
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Purple"), null, pbNetworkView_Color_Click);
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Yellow"), null, pbNetworkView_Color_Click);
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Green"), null, pbNetworkView_Color_Click);
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Orange"), null, pbNetworkView_Color_Click);
                (pbNetworkView.ContextMenuStrip.Items[MenuIndex] as ToolStripMenuItem).DropDownItems.Add(NB.Translate("NB_Cyan"), null, pbNetworkView_Color_Click);
            }
            if (ReleasedOn == null)
            {
                pbNetworkView.ContextMenuStrip.Visible = false;
            }
            else
            {
                pbNetworkView.ContextMenuStrip.Visible = true;
                pbNetworkView.ContextMenuStrip.Show(Cursor.Position);
            }
        }

        private void pbNetworkView_PowerOn_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn != null)
            {
                ItemClickedOn.PowerOff = false;
                UpdateLinks();
                UpdateVisuals();
            }
        }

        private void pbNetworkView_PowerOff_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn != null)
            {
                ItemClickedOn.PowerOff = true;
                UpdateLinks();
                UpdateVisuals();
            }
        }

        private void pbNetworkView_Color_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem TSMI = (ToolStripMenuItem)sender;
            if(ItemClickedOn != null)
            {
                if (TSMI.Text == NB.Translate("NB_Blue"))
                    ItemClickedOn.ChangeColor(Color.Empty);
                if (TSMI.Text == NB.Translate("NB_Purple"))
                    ItemClickedOn.ChangeColor(Color.Purple);
                if (TSMI.Text == NB.Translate("NB_Yellow"))
                    ItemClickedOn.ChangeColor(Color.Yellow);
                if (TSMI.Text == NB.Translate("NB_Green"))
                    ItemClickedOn.ChangeColor(Color.Green);
                if (TSMI.Text == NB.Translate("NB_Orange"))
                    ItemClickedOn.ChangeColor(Color.Orange);
                if (TSMI.Text == NB.Translate("NB_Cyan"))
                    ItemClickedOn.ChangeColor(Color.Cyan);
                UpdateVisuals();
            }
        }

        private void pbNetworkView_RemoveLink_Click(object sender, EventArgs e)
        {
            ToolStripItem thing = (ToolStripItem)sender;
            string released = thing.Text;
            released = Regex.Replace(released, ".* ", "");
            if (ItemClickedOn != null)
            {
                ItemClickedOn.RemoveLinkTo(released);
            }
            myNetwork.TestForCompletion(true);
            pbNetworkView.Update();
            UpdateVisuals();

        }

        private void pbNetworkView_DHCPRequest_Click(object sender, EventArgs e)
        {
            ItemClickedOn.DHCPRequestFromHere();
            myNetwork.ProcessPackets();
            UpdateMessages();
            pbNetworkView.Update();
            UpdateVisuals();
            myNetwork.TestForCompletion(true);
        }

        private void pbNetworkView_Reset_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn == null) return;
            ItemClickedOn.ClearIPs(); //reset the device
            UpdateVisuals();
        }

        private void pbNetworkView_Edit_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn == null) return;
            if (ItemClickedOn.DeviceIsLockedOutByVLANs()) return; //we cannot edit this
            if (ItemClickedOn.GetNetType() == NetworkComponentType.microwave || ItemClickedOn.GetNetType() == NetworkComponentType.fluorescent)
                return;
            if (ItemClickedOn != null)
            {

                DeviceConfig editwindow = new DeviceConfig(ItemClickedOn);
                editwindow.ShowDialog();
            }
            UpdateLinks();
            myNetwork.TestForCompletion(true);
            UpdateVisuals();
        }

        private void pbNetworkView_Delete_Click(object sender, EventArgs e)
        {
            //Deleting the item is easy, but we also need to delete any links to that item
            List<HostNicID> NicIDs = new List<HostNicID>();
            if(ItemClickedOn != null)
            {
                if (myNetwork.ItemIsCritical(ItemClickedOn.hostname))
                    return; //we cannot delete this
                NicIDs = ItemClickedOn.GetHostNicIDs();
                foreach (HostNicID nicID in NicIDs)
                {
                    myNetwork.RemoveLinksToNic(nicID);
                }
                myNetwork.RemoveComponent(ItemClickedOn);
            }
            UpdateLinks();
            myNetwork.TestForCompletion(true);
            UpdateVisuals();
        }

        private void pbNetworkView_Ping_Click(object sender, EventArgs e)
        {
            bool todo = true;
            if (ItemClickedOn == null) return; //we do not have something chosen to ping from
            IPAddress destination = new IPAddress(NB.ZeroIPString, NB.ZeroIPString, IPAddressType.ip_only);
            todo = destination.Edit(ItemClickedOn, this, NB.Translate("_Ping"));
            if(todo)
            {
                ItemClickedOn.PingFromHere(destination);
                myNetwork.ProcessPackets();
                UpdateMessages();
            }
        }

        private void pbNetworkView_Traceroute_Click(object sender, EventArgs e)
        {
            bool todo = true;
            if (ItemClickedOn == null) return; //we do not have something chosen to traceroute from
            IPAddress destination = new IPAddress(NB.ZeroIPString, NB.ZeroIPString, IPAddressType.ip_only);
            todo = destination.Edit(ItemClickedOn, this, NB.Translate("_Traceroute"));
            if (todo)
            {
                ItemClickedOn.TracerouteFromHere(destination);
                myNetwork.ProcessPackets();
                UpdateMessages();
            }
        }

        private void pbNetworkView_Ping_Name_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn == null) return; //we do not have something chosen to ping from
            ToolStripMenuItem Pressed = (ToolStripMenuItem)sender;
            string itemname = Pressed.Text;
            string dest = Regex.Replace(itemname, NB.Translate("_Ping") + " ", "");
            IPAddress destination;
            destination = myNetwork.DNSLookup(ItemClickedOn, dest);
            if(destination == null || destination.GetIPString == NB.ZeroIPString)
                destination = new IPAddress(dest);
            ItemClickedOn.PingFromHere(destination);
            myNetwork.ProcessPackets();
            UpdateMessages();
        }
        private void pbNetworkView_Arp_Name_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn == null) return; //we do not have something chosen to ping from
            ToolStripMenuItem Pressed = (ToolStripMenuItem)sender;
            string itemname = Pressed.Text;
            string dest = Regex.Replace(itemname, NB.Translate("H_ARP_Title")+" ", "");
            IPAddress destination;
            destination = myNetwork.DNSLookup(ItemClickedOn, dest);
            if (destination == null || destination.GetIPString == NB.ZeroIPString)
                destination = new IPAddress(dest);
            ItemClickedOn.AskArpFromHere(destination);
            myNetwork.ProcessPackets();
            UpdateMessages();
        }

        private void pbNetworkView_Arp_Click(object sender, EventArgs e)
        {
            bool todo = true;
            if (ItemClickedOn == null) return; //we do not have something chosen to arp request from
            IPAddress destination = new IPAddress(NB.ZeroIPString, "255.255.255.255", IPAddressType.ip_only);
            todo = destination.Edit(ItemClickedOn, this, NB.Translate("H_ARP_Title2"));
            if (todo)
            {
                ItemClickedOn.AskArpFromHere(destination);
                myNetwork.ProcessPackets();
                UpdateMessages();
            }
        }

        private void pbNetworkView_ArpClear_Click(object sender, EventArgs e)
        {
            if (ItemClickedOn == null) return; //we do not have something chosen to arp request from
            ItemClickedOn.ClearArps();
        }

        private void pbNetworkView_MouseUp(object sender, MouseEventArgs e)
        {
            lblStatus.Text = "";
            //find where we were clicked
            Point CenteredLocation = myNetwork.clickedPosCentered(e.Location);
            Point ClickLocation = myNetwork.clickedPos(e.Location);
            NetworkDevice ReleasedOn = myNetwork.ItemAtPosition(ClickLocation);

            //Do we have something selected that we should add?
            TimeSpan duration;
            duration = DateTime.Now - LastClick;
            
            if(e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                pbNetworkView_RightMouseUp(ReleasedOn, e);
                return;
            }

            if (duration.TotalMilliseconds < 250)
            { 
                //This mouse-up is part of a double-click operation. Do an edit
                pbNetworkView_Edit_Click(sender, e);
            }
            else
            {
                if (selectedButton == "btnLink")
                {
                    //We are making a link
                    LinkEditor myEditor = new LinkEditor(ItemClickedOn, ReleasedOn);
                    myEditor.ShowDialog();
                    UpdateLinks();
                    UpdateVisuals(); //In case any changes have been made
                }
                else if (ItemClickedOn == null)
                {
                    NetworkComponent NC = null;
                    switch (selectedButton)
                    {
                        case "btnSwitch":
                            NC = myNetwork.AddItem(NetworkComponentType.net_switch, CenteredLocation);
                            break;
                        case "btnHub":
                            NC = myNetwork.AddItem(NetworkComponentType.net_hub, CenteredLocation);
                            break;
                        case "btnLaptop":
                            NC = myNetwork.AddItem(NetworkComponentType.laptop, CenteredLocation);
                            break;
                        case "btnServer":
                            NC = myNetwork.AddItem(NetworkComponentType.server, CenteredLocation);
                            break;
                        case "btnPC":
                            NC = myNetwork.AddItem(NetworkComponentType.pc, CenteredLocation);
                            break;
                        case "btnRouter":
                            NC = myNetwork.AddItem(NetworkComponentType.router, CenteredLocation);
                            break;
                        case "btnIPPhone":
                            NC = myNetwork.AddItem(NetworkComponentType.ip_phone, CenteredLocation);
                            break;
                        case "btnFirewall":
                            NC = myNetwork.AddItem(NetworkComponentType.firewall, CenteredLocation);
                            break;
                        case "btnPrinter":
                            NC = myNetwork.AddItem(NetworkComponentType.printer, CenteredLocation);
                            break;
                        case "btnCopier":
                            NC = myNetwork.AddItem(NetworkComponentType.copier, CenteredLocation);
                            break;
                        case "btnMicrowave":
                            NC = myNetwork.AddItem(NetworkComponentType.microwave, CenteredLocation);
                            break;
                        case "btnFluorescent":
                            NC = myNetwork.AddItem(NetworkComponentType.fluorescent, CenteredLocation);
                            break;
                        case "btnWAP":
                            NC = myNetwork.AddItem(NetworkComponentType.wap, CenteredLocation);
                            break;
                        case "btnWRouter":
                            NC = myNetwork.AddItem(NetworkComponentType.wrouter, CenteredLocation);
                            break;
                        case "btnCellphone":
                            NC = myNetwork.AddItem(NetworkComponentType.cellphone, CenteredLocation);
                            break;
                        case "btnTablet":
                            NC = myNetwork.AddItem(NetworkComponentType.tablet, CenteredLocation);
                            break;
                        case "btnWBridge":
                            NC = myNetwork.AddItem(NetworkComponentType.wbridge, CenteredLocation);
                            break;
                        case "btnWRepeater":
                            NC = myNetwork.AddItem(NetworkComponentType.wrepeater, CenteredLocation);
                            break;

                    }
                    if(NC != null && NB.GetComponentType(NC) == GeneralComponentType.device)
                    {
                        ItemClickedOn = (NetworkDevice)NC;
                    }
                    UpdateVisuals();
                }
                else //Drag the item
                {
                    if (Math.Abs(ClickedLocation.X - ClickLocation.X) > 5 || Math.Abs(ClickedLocation.Y - ClickLocation.Y) > 5)
                    {
                        ItemClickedOn.ChangeLocation(CenteredLocation);
                        UpdateLinks();
                        UpdateVisuals();
                    }
                }
            }
            LastClick = DateTime.Now;
        }

        private void UpdateVisuals()
        {
            myNetwork.Print();
            pbNetworkView.Invalidate();
        }

        private void pbNetworkView_MouseDown(object sender, MouseEventArgs e)
        {
            Point location = myNetwork.clickedPos(e.Location);
            ClickedLocation = location;
            //See if we have clicked on something
            ItemClickedOn = myNetwork.ItemAtPosition(location);
        }

        private void pbNetworkView_MouseMove(object sender, MouseEventArgs e)
        {
            Point location = myNetwork.clickedPos(e.Location);
            NetworkDevice MouseOver = myNetwork.ItemAtPosition(location);
            MouseHoverOver = MouseOver;
            string oldtooltip = myTooltip.GetToolTip(pbNetworkView);
            string newtooltip = "";
            if (MouseOver != null)
            {
                if (!MouseOver.DeviceIsLockedOutByVLANs())
                    newtooltip = MouseOver.TooltipString();
                else
                    newtooltip = NB.Translate("NB_LockedOut");
            }
            if(oldtooltip != newtooltip)
            {
                myTooltip.SetToolTip(pbNetworkView, newtooltip);
            }
        }

        private void PrepForLoad()
        {
            processing = true;
            myNetwork = new Network("");
            myNetwork.RegisterDisplayArea(pbNetworkView);
            GC.Collect();
            RTFWindow myWin = (RTFWindow)Application.OpenForms["RTFWindow"];
            if (myWin != null) 
            {
                myWin.Close();
            }

            myNetwork.Print();
            UpdateMessages();
            btnReset();
            myNetwork.HintsToDisplay = NetTestVerbosity.none;
            rbHelp1.Checked = true;
            processing = false;
        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog mydialog = new OpenFileDialog();
            mydialog.AddExtension = true;
            mydialog.Filter = "EduNet File (*.enbx)|*.enbx";
            mydialog.Multiselect = false;
            mydialog.ShowHelp = true;
            if (LastPath != null && LastPath != "") mydialog.FileName = LastPath;
            DialogResult result = mydialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.Cancel) return;
            if(!Regex.IsMatch(mydialog.FileName,@"^.*.enbx$"))
            {
                MessageBox.Show(NB.Translate("_LoadErr"));
                return;
            }
            LastPath = mydialog.FileName;
            if (!File.Exists(mydialog.FileName)) return;

            PrepForLoad();
            myNetwork.Load(mydialog.FileName);
            UpdateMenu();
            UpdateForm();
        }

        private void reloadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string oldfile = myNetwork.NetworkFilename;
            if (oldfile != null && oldfile != "" && File.Exists(oldfile))
            {
                PrepForLoad();
                myNetwork.Load(oldfile);
            }
            UpdateMenu();
            UpdateForm();
        }

        public void doSave(bool TrySkipPrompt = false)
        {
            if (TrySkipPrompt && myNetwork.NetworkFilename != null && File.Exists(myNetwork.NetworkFilename))
            {
                //Just save over it
                myNetwork.Save(myNetwork.NetworkFilename);
                NB.PlaySound(NBSoundType.saved_ok);
            }
            else
            {
                SaveFileDialog mydialog = new SaveFileDialog();
                mydialog.AddExtension = true;
                mydialog.Filter = "EduNet File (*.enbx)|*.enbx";
                mydialog.FileName = myNetwork.NetworkFilename;
                string initialfolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                if (myNetwork.NetworkFilename != "")
                    initialfolder = Path.GetDirectoryName(myNetwork.NetworkFilename);
                mydialog.CreatePrompt = true;
                mydialog.OverwritePrompt = true;
                mydialog.InitialDirectory = initialfolder;
                DialogResult result = mydialog.ShowDialog();

                if (result == System.Windows.Forms.DialogResult.Cancel)
                {
                    NB.PlaySound(NBSoundType.saved_failed);
                    lblStatus.Text = NB.Translate("_Canceled");
                    return;
                }
                LastPath = mydialog.FileName;
                myNetwork.Save(mydialog.FileName);
                NB.PlaySound(NBSoundType.saved_ok);
            }
            lblStatus.Text = NB.Translate("_Saved");
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            doSave(false);
        }

        private void BuilderWindow_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Normal)
            {
                //size limits go here
                int smallestX = 400;
                int smallestY = 300;
                if (Width < smallestX) Width = smallestX;
                if (Height < smallestY) Height = smallestY;
            }
        }

        private void BuilderWindow_ResizeEnd(object sender, EventArgs e)
        {
            UpdateVisuals();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RTFWindow mywindow = new RTFWindow(RTFWindowContents.about);
            mywindow.ShowDialog();

        }

        private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            NB.ReadContextHelp(HelpTopics.None);
        }

        private void releaseNotesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RTFWindow mywindow = new RTFWindow(RTFWindowContents.release_notes);
            mywindow.ShowDialog();
        }

        private void lbMessages_DoubleClick(object sender, EventArgs e)
        {
            if(lbMessages.SelectedIndex < 0) return; //nothing to do
            if(lbMessages.SelectedIndex > myNetwork.CountMessages()) return; //invalid.  Do nothing
            PacketMessage newMessage = myNetwork.GetMessageAtIndex(lbMessages.SelectedIndex);
            if(newMessage == null) return; //Not sure how we could get to this, but break out just in case
            ListBoxWindow newwindow = new ListBoxWindow(newMessage);
            newwindow.ShowDialog();
        }

        private void BuilderWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.ChosenLanguage = ChosenLanguage;
            Properties.Settings.Default.LastPath = LastPath;
            if (WindowState == FormWindowState.Normal)
            {
                Properties.Settings.Default.MainWindowHeight = Height;
                Properties.Settings.Default.MainWindowWidth = Width;
                Properties.Settings.Default.MainWindowX = Location.X;
                Properties.Settings.Default.MainWindowY = Location.Y;
            }
            Properties.Settings.Default.Save();
        }

        private void dHCPRequestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            myNetwork.DoAllDHCP();
            myNetwork.ProcessPackets();
            UpdateMessages();
        }

        private void clearArpTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            myNetwork.DoAllClearArp();
            UpdateMessages();
        }

        private void clearIPsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }

        private void pingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool todo = true;
            IPAddress destination = new IPAddress(NB.ZeroIPString, NB.ZeroIPString, IPAddressType.ip_only);
            todo = destination.Edit(null, this, NB.Translate("NB_NetViewPng"));
            if (todo)
            {
                myNetwork.DoAllPing(destination);
                myNetwork.ProcessPackets();
                UpdateMessages();
            }
        }

        public void LoadNetworkFromResource(string resource)
        {
            XmlDocument xmlDoc = new XmlDocument();
            //Load(SavePath);
            System.Reflection.Assembly MyAssembly;
            MyAssembly = this.GetType().Assembly;

            // Creates the ResourceManager.
            System.Resources.ResourceManager myManager = new
               System.Resources.ResourceManager("EduNetworkBuilder.Properties.Resources",
               MyAssembly);

            // Retrieves String and Image resources.
            System.String myString;
            byte[] item = (byte[])myManager.GetObject(resource);
            myString = new StreamReader(new MemoryStream(item), true).ReadToEnd();
            //myString = System.Text.Encoding.Default.GetString(item);
            xmlDoc.LoadXml(myString);
            PrepForLoad();
            myNetwork.Load(xmlDoc,resource);
            UpdateMenu();
            UpdateForm();
        }

        private void oneNetworkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("OneNet");
            UpdateMessages();
        }

        private void twoNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("TwoNets");
            UpdateMessages();
        }

        private void dHCPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("DHCP");
            UpdateMessages();
        }

        private void solvedOneNetworkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("OneNet");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }

        private void solvedTwoNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("TwoNets");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }

        private void solvedDHCPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("DHCP");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }


        private void VLANToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("VLAN");
            UpdateMessages();
        }

        private void SolvedVLANToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("VLAN");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
            UpdateVisuals();
        }

        private void threeNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("ThreeNets");
            UpdateMessages();
        }

        private void SolvedThreeNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("ThreeNets");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrepForLoad();
            UpdateForm();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OptionsWindow tWindow = new OptionsWindow(myNetwork);
            tWindow.ShowDialog();
            myNetwork.UpdateDeviceSizes();
           
            UpdateForm();
        }

        private void BuilderWindow_Load(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.MainWindowX != -1 && Properties.Settings.Default.MainWindowY != -1)
            {
                Location = new Point(Properties.Settings.Default.MainWindowX, Properties.Settings.Default.MainWindowY);
            }
            if (Properties.Settings.Default.MainWindowHeight != -1 && Properties.Settings.Default.MainWindowWidth != -1)
            {
                Height = Properties.Settings.Default.MainWindowHeight;
                Width = Properties.Settings.Default.MainWindowWidth;
            }
            //If we started by clicking on a file, load that file
            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments != null && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Any())
            {
                string[] activationData = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData;
                var uri = new Uri(activationData[0]);
                //MessageBox.Show("Trying Localpath: " + uri.LocalPath);
                //MessageBox.Show("isUNC: " + uri.IsUnc.ToString());
                //MessageBox.Show("isFile: " + uri.IsFile.ToString());

                if (uri.IsFile)
                {
                    PrepForLoad();
                    myNetwork.Load(uri.LocalPath);
                    UpdateMenu();
                    UpdateForm();
                }
            }
            else
            {
                if (Properties.Settings.Default.AutoStartPuzzles)
                {
                    //We are supposed to start the puzzle-selection box
                    puzzlesToolStripMenuItem_Click(null, null);
                }
            }
        }

        private void btnHelp_Click(object sender, EventArgs e)
        {
            OpenNetHelpWindow();
            bool didsomething = myNetwork.NoteActionDone(NetTestType.HelpRequest, "", "?Button");
            if (didsomething)
            {
                UpdateForm();
                myNetwork.TestForCompletion(true);
            }
        }

        public void OpenNetHelpWindow()
        {
            RTFWindow rtwin = (RTFWindow)Application.OpenForms["RTFWindow"];
            if (rtwin == null)
            {
                rtwin = new RTFWindow(NB.Translate("H_Help_Key ") + myNetwork.NetTitle.GetText(), myNetwork.NetMessage.GetText(), myNetwork.NetTests);
                rtwin.Show();
                Activate();
            }
        }

        private void rbHelp1_CheckedChanged(object sender, EventArgs e)
        {
            if (processing) return;
            myNetwork.HintsToDisplay = NetTestVerbosity.none;
            UpdateForm();
        }
        
        private void rbHelp2_CheckedChanged(object sender, EventArgs e)
        {
            if (processing) return;
            myNetwork.HintsToDisplay = NetTestVerbosity.hints;
            UpdateForm();
        }

        private void rbHelp3_CheckedChanged(object sender, EventArgs e)
        {
            if (processing) return;
            myNetwork.HintsToDisplay = NetTestVerbosity.basic;
            UpdateForm();
        }

        private void rbHelp4_CheckedChanged(object sender, EventArgs e)
        {
            if (processing) return;
            myNetwork.HintsToDisplay = NetTestVerbosity.full;
            UpdateForm();
        }


        private void puzzlesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ListBoxWindow LBW = new ListBoxWindow();
            LBW.ShowDialog();
        }

        private void firewallsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("firewalls");
            UpdateMessages();
        }

        private void firewallsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            LoadNetworkFromResource("firewalls");
            myNetwork.DoAllClearIPs();
            UpdateMessages();
        }

        public void SetProgress(double HowFar, double total)
        {
            int max = (int)(total * 100);
            myProgressBar.Maximum = max;
            int distance = (int)(HowFar * 100);
            if(distance > max) distance = max;
            myProgressBar.Value = distance;
        }

        private void changeLanguageToolStripMenuItem_Click(object sender, EventArgs e)
        {
           DialogResult answer = MessageBox.Show(NB.Translate("NB_ChngLngClose"),NB.Translate("NB_ChngLngSure"),MessageBoxButtons.YesNoCancel);
           if (answer == System.Windows.Forms.DialogResult.Yes)
           {
               Properties.Settings.Default.LanguageHasBeenChosen = false; //So we choose the language on restart
               //System.Diagnostics.Process.Start(Application.ExecutablePath); // to start new instance of application
               this.Close(); //to turn off current app
           }
        }

        private void cbViewTitles_CheckedChanged(object sender, EventArgs e)
        {
            if(!processing)
            {
                myNetwork.ShowLabelsHere = cbViewTitles.Checked;
                bool didsomething = myNetwork.NoteActionDone(NetTestType.HelpRequest, "", "ViewButton");
                if (didsomething)
                {
                    UpdateForm();
                    myNetwork.TestForCompletion(true);
                }
                UpdateVisuals();
            }
        }

        private void BuilderWindow_Shown(object sender, EventArgs e)
        {
            //Console.WriteLine(this.DesktopLocation.X);
            //Console.WriteLine(Screen.FromControl(this).WorkingArea.ToString());
            int x = this.DesktopLocation.X;
            int y = this.DesktopLocation.Y;

            if (x + this.Width > Screen.FromControl(this).WorkingArea.X)
                x = Screen.FromControl(this).WorkingArea.X - this.Width;
            if (x < 0) x = 0;
            if (x - 30 > Screen.FromControl(this).WorkingArea.Width)
                x = 100;

            if (y + this.Height > Screen.FromControl(this).WorkingArea.Y)
                y = Screen.FromControl(this).WorkingArea.Y - this.Height;
            if (y < 0) y = 0;
            if (y - 30 > Screen.FromControl(this).WorkingArea.Height)
                y = 100;

            this.DesktopLocation = new Point(x, y);
        }
    }
}