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();
        public NBSettings OurSettings = new NBSettings(NB.IsRunningOnMono()); //This will auto-load the settings

        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 MouseHoverOver = null;
        private Point ClickedLocation;
        private Point ClickedImageLocation;
        DateTime LastClick = DateTime.Now;
        private string 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

        //For mouse-move / dragging
        public DateTime LastMoveTime = DateTime.UtcNow;
        public bool MouseIsDown = false; //For tracking if we are dragging something
        public Image LastBackgroundImage = null;
        public Point LastMouseMovePos = new Point(-1, -1);
        private NetworkDevice ItemClickedOn = null;
        private List<NetworkDevice> ItemsSelected = new List<NetworkDevice>();
        private Point OrigClickPoint = new Point(-1, -1);

        private string InitialFileLoad = "";

        public PersonClass CurrentUser;

        public BuilderWindow(string FirstArg="")
        {
            InitializeComponent();

            InitialFileLoad = FirstArg;

            LastPath = OurSettings.LastPath;

            if(!OurSettings.LanguageHasBeenChosen)
                NB.ChangeLanguage(OurSettings);
            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", OurSettings));
            myTooltip.SetToolTip(rbHelp2, NB.Translate("NB_BuildWindColor", OurSettings));
            myTooltip.SetToolTip(rbHelp3, NB.Translate("NB_BuildWindMinor", OurSettings));
            myTooltip.SetToolTip(rbHelp4, NB.Translate("NB_BuildWindDecent", OurSettings));
            myTooltip.SetToolTip(btnHelp, NB.Translate("NB_BuildWindMsg", OurSettings));
            myTooltip.SetToolTip(cbViewTitles, NB.Translate("NB_cbViewTitles", OurSettings));
            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();

            //Set this so we can intercept the esc key.  We want to un-set the selected items if esc is pressed
            KeyPreview = true;

            LoadPuzzleInfo();            
        }

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

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

            Text = NB.Translate("NB_Form", OurSettings);
        }

        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 = OurSettings.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();
            myNetwork.TestForCompletion(true);
        }

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

            //If we already have a class setup
            if (CurrentUser == null)
            {
                classSetupToolStripMenuItem.Visible = true;
                profileToolStripMenuItem.Visible = false;
            }
            else
            {
                profileToolStripMenuItem.Visible = true;
                classSetupToolStripMenuItem.Visible = false;
                this.Text = "EduNetworkBuilder : " + CurrentUser.FullName;
            }
            if (CurrentUser == null || !CurrentUser.isAdmin)
            {
                addToClassworkToolStripMenuItem.Visible = false;
                submitHomeworkToolStripMenuItem.Visible = false;
                updateClassworkToolStripMenuItem.Visible = false;
            }
            if(CurrentUser != null)
            {
                if (CurrentUser.isAdmin)
                {
                    submitHomeworkToolStripMenuItem.Visible = false;
                    if (myNetwork.WhatFrom == null)
                    {
                        //If this is not part of homework yet, we can add it
                        addToClassworkToolStripMenuItem.Visible = true;
                        updateClassworkToolStripMenuItem.Visible = false;
                    }
                    else
                    {
                        //If this is homework, we can update it
                        addToClassworkToolStripMenuItem.Visible = false;
                        updateClassworkToolStripMenuItem.Visible = true;
                    }
                }
                else if (myNetwork.WhatFrom != null) //we are a student doing homework
                    submitHomeworkToolStripMenuItem.Visible = true;
            }

            List<string> tLoadList = new List<string>();
            loadToolStripMenuItem.DropDownItems.Clear();
            if(OurSettings != null)
            {
                foreach (string one in OurSettings.GetRecentFiles())
                {
                    if (tLoadList.Contains(one)) continue;
                    string JustFile = Path.GetFileName(one);
                    int i = loadToolStripMenuItem.DropDownItems.Count;
                    loadToolStripMenuItem.DropDownItems.Add(JustFile, null, loadRecentFilename);
                    loadToolStripMenuItem.DropDownItems[i].Name = one;
                    tLoadList.Add(one);
                }
            }
        }

        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();
            if (myNetwork != null && myNetwork.LoadedFromResource)
                optionsToolStripMenuItem.Visible = false;
            else
                optionsToolStripMenuItem.Visible = true;
            processing = true;
            cbViewTitles.Checked = myNetwork.ShowLabelsHere;
            Text = NB.Translate("NB_UpdteFrmName", OurSettings);
            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)
        {
            
            foreach (PuzzleInfo pi in PuzzleList)
            {
                if ("Level_" + pi.Level.ToString() == LevelName)
                {
                    if (!OurSettings.CheckIfDone(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;
            bool PoweredOff = false;
            if (pbNetworkView.ContextMenuStrip == null)
            {
                pbNetworkView.ContextMenuStrip = new ContextMenuStrip();
            }
            if (ReleasedOn != null) LockedOut = ReleasedOn.DeviceIsLockedOutByVLANs();
            if (ReleasedOn != null) PoweredOff = ReleasedOn.PowerOff;
            pbNetworkView.ContextMenuStrip.Items.Clear();

            if(ItemsSelected.Count > 0)
            {
                //We do not want to do the normal menu...
                LockedOut = false;
                ReleasedOn = null;

                //We need to make sure the item is not critical before we delete it.
                pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Delete"));
                pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Delete_Click;

                //We can color-code multiple items
                if (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 (!LockedOut)
            {
                if (ReleasedOn != null && ReleasedOn.IsNotNetDevice())
                {
                    List<string> DoneList = new List<string>();
                    if (!PoweredOff)
                    {
                        foreach (string tStr in myNetwork.GetIncompleteTestDestinations(ReleasedOn.hostname, ContextTest.ping))
                        {
                            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, ContextTest.traceroute))
                        {
                            if (!DoneList.Contains(tStr))
                            {
                                pbNetworkView.ContextMenuStrip.Items.Add(string.Format(NB.Translate("_Traceroute") + " " + tStr));
                                pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Traceroute_Name_Click;
                                DoneList.Add(tStr);
                            }
                        }
                        DoneList.Clear();
                        foreach (string tStr in myNetwork.GetIncompleteTestDestinations(ReleasedOn.hostname, ContextTest.arp))
                        {
                            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())
                {
                    if (!PoweredOff)
                    {
                        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() && !PoweredOff)
                {
                    pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("_Edit"));
                    pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Edit_Click;
                }

                if (ReleasedOn != null)
                {
                    ItemClickedOn = ReleasedOn;
                    if (!PoweredOff)
                    {
                        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 && (Form.ModifierKeys & Keys.Control) == Keys.Control  ) //We control-click on it
            {
                int MenuIndex = pbNetworkView.ContextMenuStrip.Items.Count;
                pbNetworkView.ContextMenuStrip.Items.Add(NB.Translate("NB_Hide"));
                pbNetworkView.ContextMenuStrip.Items[index++].Click += pbNetworkView_Hide_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 && ItemsSelected.Count == 0)
            {
                pbNetworkView.ContextMenuStrip.Visible = false;
            }
            else
            {
                pbNetworkView.ContextMenuStrip.Visible = true;
                pbNetworkView.ContextMenuStrip.Show(Cursor.Position);
            }
        }

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

        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 ColorizeDevice(NetworkDevice Item, string Text)
        {
            if (ItemClickedOn != null)
            {
                if (Text == NB.Translate("NB_Blue"))
                    Item.ChangeColor(Color.Empty);
                if (Text == NB.Translate("NB_Purple"))
                    Item.ChangeColor(Color.Purple);
                if (Text == NB.Translate("NB_Yellow"))
                    Item.ChangeColor(Color.Yellow);
                if (Text == NB.Translate("NB_Green"))
                    Item.ChangeColor(Color.Green);
                if (Text == NB.Translate("NB_Orange"))
                    Item.ChangeColor(Color.Orange);
                if (Text == NB.Translate("NB_Cyan"))
                    Item.ChangeColor(Color.Cyan);
            }
        }

        private void pbNetworkView_Color_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem TSMI = (ToolStripMenuItem)sender;
            if(ItemsSelected.Count > 0)
            {
                foreach(NetworkDevice nd in ItemsSelected)
                {
                    ColorizeDevice(nd, TSMI.Text);
                }
            }
            else
                ColorizeDevice(ItemClickedOn, TSMI.Text);
            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 TryDeleteOneItem(NetworkDevice Item)
        {
            //Deleting the item is easy, but we also need to delete any links to that item
            List<HostNicID> NicIDs = new List<HostNicID>();
            if (Item != null)
            {
                if (myNetwork.ItemIsCritical(Item.hostname))
                    return; //we cannot delete this
                NicIDs = Item.GetHostNicIDs();
                foreach (HostNicID nicID in NicIDs)
                {
                    myNetwork.RemoveLinksToNic(nicID);
                }
                myNetwork.RemoveComponent(Item);
            }
        }

        private void pbNetworkView_Delete_Click(object sender, EventArgs e)
        {
            if(ItemsSelected.Count ==0)
                TryDeleteOneItem(ItemClickedOn);
            else
            {
                for(int i=ItemsSelected.Count -1; i>=0; i--)
                {
                    TryDeleteOneItem(ItemsSelected[i]);
                }
            }
            pbNetworkView.Image = null;
            ItemsSelected.Clear(); 
            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"),true);
            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"), true);
            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_Traceroute_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("_Traceroute") + " ", "");
            IPAddress destination;
            destination = myNetwork.DNSLookup(ItemClickedOn, dest);
            if (destination == null || destination.GetIPString == NB.ZeroIPString)
                destination = new IPAddress(dest);
            ItemClickedOn.TracerouteFromHere(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);
            LastBackgroundImage = null;
            pbNetworkView.Image = null; //erase old highlight area
            LastMouseMovePos = new Point(-1, -1);

            //Do we have something selected that we should add?
            TimeSpan duration;
            duration = DateTime.Now - LastClick;

            //Track size of area for the click/drag
            int sx;
            int sy;
            int swidth;
            int sheight;
            if (ClickedImageLocation.X > e.Location.X)
            {
                sx = e.Location.X;
                swidth = ClickedImageLocation.X - sx;
            }
            else
            {
                sx = ClickedImageLocation.X;
                swidth = e.Location.X - sx;
            }
            if (ClickedImageLocation.Y > e.Location.Y)
            {
                sy = e.Location.Y;
                sheight = ClickedImageLocation.Y - sy;
            }
            else
            {
                sy = ClickedImageLocation.Y;
                sheight = e.Location.Y - sy;
            }

            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                pbNetworkView_RightMouseUp(ReleasedOn, e);
                return;
            }
            if (duration.TotalMilliseconds < 250)
            {
                bool PoweredOff = false;
                //This mouse-up is part of a double-click operation. Do an edit.  But only if we are powered on
                if (ItemClickedOn != null) PoweredOff = ItemClickedOn.PowerOff;
                if(!PoweredOff)
                    pbNetworkView_Edit_Click(sender, e);
            }
            else
            {
                if (MouseIsDown && ItemsSelected.Count > 0)
                {
                    //We were dragging stuff.  All done now
                    MouseIsDown = false;
                    ItemsSelected.Clear(); //clear it so we stop moving these ones
                    UpdateLinks();
                    UpdateVisuals();
                    return;
                }
                if (MouseIsDown && ItemClickedOn == null && (swidth > 4 || sheight>4))
                {
                    //We just finished dragging a select box
                    //Put them all into the drag box.
                    ItemsSelected.Clear();
                    
                    //Now we have a rectangle, but need to exchange numbers for numbers on the image
                    Point topCorner = myNetwork.clickedPos(new Point(sx, sy));
                    Point botCorner = myNetwork.clickedPos(new Point(sx + swidth, sy + sheight));

                    Rectangle selectbox = new Rectangle(topCorner.X, topCorner.Y, botCorner.X - topCorner.X, botCorner.Y - topCorner.Y);

                    ItemsSelected.AddRange(myNetwork.DevicesInRectangle(selectbox));
                    //Console.WriteLine("Selected " + ItemsSelected.Count + " items");
                    MouseIsDown = false;
                    DrawHighlightBoxes();
                    pbNetworkView.Invalidate();
                    return;
                }
                MouseIsDown = false;
                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);
                        ItemClickedOn.UnHide(); //If it was hidden, unhide it
                        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;
            OrigClickPoint = myNetwork.clickedPosCentered(e.Location);
            ClickedImageLocation = e.Location;
            //See if we have clicked on something
            ItemClickedOn = myNetwork.ItemAtPosition(location);
            MouseIsDown = true;
            //Make a duplicate of the old background image.
            LastBackgroundImage = new Bitmap(pbNetworkView.BackgroundImage);
        }

        private void DragItemToNewLocation(NetworkDevice toMove, Point NewPosition)
        {
            if (toMove == null) return;
            if (LastBackgroundImage == null) return;

            Size itemsize = new Size(toMove.Size, toMove.Size);
            Rectangle newrec = new Rectangle(NewPosition, itemsize);

            Point oldpoint = toMove.myLocation();
            Rectangle oldrec = new Rectangle(oldpoint.X, oldpoint.Y, toMove.Size, toMove.Size);
            Graphics.FromImage(pbNetworkView.BackgroundImage).DrawImage(LastBackgroundImage, oldrec, oldrec,GraphicsUnit.Pixel);
            myNetwork.Invalidate(oldrec);

            //set it to the new pos
            toMove.ChangeLocationUnsnapped(NewPosition);
            //tell it to draw
            toMove.Print(pbNetworkView.BackgroundImage, false);
            //invalidate
            myNetwork.Invalidate(newrec);
        }

        private void DrawHighlightBoxes()
        {
            Image tImage = new Bitmap(pbNetworkView.BackgroundImage.Width, pbNetworkView.BackgroundImage.Height);
            Graphics tGraphics = Graphics.FromImage(tImage);
            tGraphics.Clear(Color.Transparent); //erase the whole thing

            Color tColor = Color.LightGreen;
            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(128, tColor.R, tColor.G, tColor.B));
            foreach (NetworkDevice nd in ItemsSelected)
            {
                tGraphics.FillRectangle(semiTransBrush, nd.GetMyRectangle());
            }
            pbNetworkView.Image = tImage;
            pbNetworkView.Invalidate();

        }

        private void pbNetworkView_MouseMove(object sender, MouseEventArgs e)
        {
            //Only do this 10 times a second
            if (DateTime.UtcNow - LastMoveTime < TimeSpan.FromMilliseconds(100)) return;

            Point CenteredLocation = myNetwork.clickedPosCentered(e.Location);
            Point MouseLocation = myNetwork.clickedPos(e.Location);
            //If we are dragging lines, do that first.
            if (selectedButton == "btnLink")
            {
                //We are trying to do a link.  Do not drag...
            }
            else if (MouseIsDown && LastBackgroundImage != null && ItemClickedOn != null && ItemsSelected.Count == 0) //We are trying to drag something
            {
                //find where we are
                DragItemToNewLocation(ItemClickedOn, CenteredLocation);
             }
            else if (MouseIsDown && ItemsSelected.Count >0) //dragging multiple items around
            {
                //Track the difference between the last redraw and this re-draw
                //Move every item by that amount.
                int xdif = CenteredLocation.X - OrigClickPoint.X ;
                int ydif = CenteredLocation.Y - OrigClickPoint.Y;
                if (xdif != 0 || ydif != 0)
                {
                    foreach (NetworkDevice nd in ItemsSelected)
                    {
                        Point oPoint = nd.myLocation();
                        Point nPoint = new Point(oPoint.X + xdif, oPoint.Y + ydif);
                        DragItemToNewLocation(nd, nPoint);
                    }
                }
                //Now set the location so we do it from here next time
                OrigClickPoint = CenteredLocation;
            }
            else if (MouseIsDown && ItemClickedOn == null) //Dragging an empty area
            {
                //make a rectangle
                Image tImage = new Bitmap(pbNetworkView.BackgroundImage.Width, pbNetworkView.BackgroundImage.Height);
                Graphics tGraphics = Graphics.FromImage(tImage);
                tGraphics.Clear(Color.Transparent); //erase the whole thing
                int sx;
                int sy;
                int swidth;
                int sheight;
                if(ClickedLocation.X > MouseLocation.X )
                {
                    sx = MouseLocation.X;
                    swidth = ClickedLocation.X - sx;
                }
                else
                {
                    sx = ClickedLocation.X;
                    swidth = MouseLocation.X - sx;
                }
                if (ClickedLocation.Y > MouseLocation.Y)
                {
                    sy = MouseLocation.Y;
                    sheight = ClickedLocation.Y - sy;
                }
                else
                {
                    sy = ClickedLocation.Y;
                    sheight = MouseLocation.Y - sy;
                }
                Rectangle selectbox = new Rectangle(sx,sy,swidth,sheight);

                Color tColor = Color.LightGreen;
                SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(128,tColor.R,tColor.G,tColor.B));
                tGraphics.FillRectangle(semiTransBrush, selectbox);
                pbNetworkView.Image = tImage;
                pbNetworkView.Invalidate();
            }

            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;
            //If we have a user loaded, we can open homework files
            string filter = "EduNet File (*.enbx, *enbu)|*.enbx; *.enbu";
            if(NB.GetUser() != null)
                filter = "EduNet File (*.enbx, *enbu, *enbh)|*.enbx; *.enbu; *.enbh";
            mydialog.Filter = filter;
            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;
            string extension = Path.GetExtension(mydialog.FileName).ToString();
            if(extension != ".enbx" && extension != ".enbu" && extension != ".enbh")
            {
                MessageBox.Show(NB.Translate("_LoadErr"));
                return;
            }
            LastPath = mydialog.FileName;
            if (!File.Exists(mydialog.FileName)) return;

            LoadInitialFile(mydialog.FileName);
        }

        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)
        {
            //The values in the settings are all up-to-date.  Just tell them to save.
            if (WindowState == FormWindowState.Normal)
            {
                OurSettings.MainWindowHeight = Height;
                OurSettings.MainWindowWidth = Width;
                OurSettings.MainWindowX = Location.X;
                OurSettings.MainWindowY = Location.Y;
            }

            OurSettings.Save(NB.IsRunningOnMono());
            if (CurrentUser != null)
                CurrentUser.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, true);//Load it from resource.  Set the bool saying it was from resource
            UpdateMenu();
            UpdateForm();
        }

        public void LoadNetworkFromNetwork(Network NewNet)
        {
            if (NewNet != null)
            {
                PrepForLoad();
                Network.Clone(NewNet, myNetwork); //Push the settings
                myNetwork.OpenHelpIfNeeded(false);
                UpdateMenu();
                UpdateForm();
            }
        }

        private void LoadSolvedResource(string what)
        {
            LoadNetworkFromResource(what);
            myNetwork.OverrideFromResources();
            UpdateForm();
            UpdateMessages();
        }

        private void LoadUnsolvedResource(string what)
        {
            //Load the puzzle & everything we need to do with it
            LoadSolvedResource(what);
            //Then "unsolve" it
            myNetwork.DoAllClearIPs();
        }

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

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

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

        private void solvedOneNetworkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadUnsolvedResource("OneNet");
        }

        private void solvedTwoNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadUnsolvedResource("TwoNets");
        }

        private void solvedDHCPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Umm.  The function name is solved, but we are doing the unsolved version?
            LoadUnsolvedResource("DHCP");
        }


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

        private void SolvedVLANToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            LoadUnsolvedResource("VLAN");
        }

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

        private void SolvedThreeNetworksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadUnsolvedResource("ThreeNets");
        }

        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 LoadInitialFile(string filename)
        {
            if (filename == "")
            {
                MessageBox.Show(NB.Translate("NB_InvalidFile"));
                Close();
            }
            //If it is a network file
            string extension = Path.GetExtension(filename).ToLower();
            //MessageBox.Show(filename + "  " +extension);
            try
            {
                if (extension == ".enbx")
                {
                    PrepForLoad();
                    myNetwork.Load(filename);
                    UpdateMenu();
                    UpdateForm();
                }
                else if (extension == ".enbu")
                {
                    CurrentUser = new PersonClass(filename);
                    CurrentUser.filepath = Path.GetDirectoryName(filename); //store the directory
                    OurSettings = NB.GetSettings(); //Grab the new settings from the user
                    UpdateMenu();

                    //Now, open a new window to edit them.
                    PersonProfileForm PPF = new PersonProfileForm(CurrentUser);
                    CurrentUser = PPF.Edit(); //This does the form as dialog.  When we come back, update the menu.
                    UpdateMenu();
                }
                else if (extension == ".enbh")
                {
                    if(NB.GetUser() == null)
                    {
                        MessageBox.Show(NB.Translate("NB_LoadUserFirst"));
                        return;
                    }
                }
                else
                {
                    MessageBox.Show(NB.Translate("NB_InvalidFile"));
                    Close();
                    return; //We return here so we do not register the filename...
                }
                if (OurSettings != null) OurSettings.RegisterFileAsLoaded(filename);
            }
            catch (Exception e)
            {
                MessageBox.Show("Error: " + e.ToString());
            }
        }

        private void loadRecentFilename(object sender, EventArgs e)
        {
            //find the full filename & load that.
            ToolStripDropDownItem TSDDI = (ToolStripDropDownItem)sender;
            LoadInitialFile(TSDDI.Name);
            UpdateMenu();
        }

        private void BuilderWindow_Load(object sender, EventArgs e)
        {
            if (OurSettings.MainWindowX != -1 && OurSettings.MainWindowY != -1)
            {
                Location = new Point(OurSettings.MainWindowX, OurSettings.MainWindowY);
            }
            if (OurSettings.MainWindowHeight != -1 && OurSettings.MainWindowWidth != -1)
            {
                Height = OurSettings.MainWindowHeight;
                Width = OurSettings.MainWindowWidth;
            }

            //If we started by clicking on a using a one_click installer, 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)
                {
                    LoadInitialFile(uri.LocalPath);
                }
            }
            if (InitialFileLoad != "") //This is set when we are installed by msi and we click a file
            {                
                if (File.Exists(InitialFileLoad))
                {
                    LoadInitialFile(InitialFileLoad);
                }
            }
            else
            {
                if (OurSettings.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)
           {
               OurSettings.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);
        }

        private void BuilderWindow_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                ItemsSelected.Clear();
                pbNetworkView.Image = null;
                UpdateVisuals();
            }
        }

        private void classSetupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PersonProfileForm PPF = new PersonProfileForm();
            CurrentUser = PPF.Edit();
            UpdateMenu();
        }

        private void profileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CurrentUser == null) return;
            PersonProfileForm PPF = new PersonProfileForm(CurrentUser);
            CurrentUser = PPF.Edit();
            UpdateMenu();
        }

        private void addToClassworkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CurrentUser == null) return;
            if (!CurrentUser.isAdmin) return;

            PersonProfileForm PPF = new PersonProfileForm(CurrentUser);
            CurrentUser = PPF.AddSchoolwork(myNetwork);
            UpdateMenu();

        }

        private void updateClassworkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CurrentUser == null) return;
            if (!CurrentUser.isAdmin) return;

            SchoolworkClass SC = myNetwork.WhatFrom;
            if (SC == null) return;

            SC.theProject = myNetwork.Clone();

            PersonProfileForm PPF = new PersonProfileForm(CurrentUser);
            CurrentUser = PPF.Edit();
            UpdateMenu();
        }

        private void submitHomeworkToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}