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


namespace EduNetworkBuilder
{
    public partial class LinkEditor : Form
    {
        NetworkDevice Source=null;
        NetworkDevice Dest=null;
        bool processing = false;
        NetworkLink EditingLink = null;
        List<string> UsedLinks = new List<string>();

        public LinkEditor(NetworkDevice Src, NetworkDevice Dst)
        {
            Network Net = NB.GetNetwork();
            InitializeComponent();
            LanguagifyComponents();
            Source = Src;
            if (Source != Dst)
            {
                Dest = Dst;
            }
            UsedLinks.AddRange(Net.UnavailableNics());

            UpdateDeviceList();
            //The first time, we change the selections to the source and dest, if we had drug a line
            int tindex;
            if(Source != null)
            {
                tindex = lbSrcHost.Items.IndexOf(Source.hostname);
                if (tindex >= 0)
                {
                    lbSrcHost.SelectedIndex = tindex;
                    UpdateDeviceList();
                }
            }
            if (Dest != null)
            {
                tindex = lbDstHost.Items.IndexOf(Dest.hostname);
                if (tindex >= 0)
                {
                    lbDstHost.SelectedIndex = tindex;
                    UpdateDeviceList();
                }
            }
        }

        public LinkEditor(NetworkLink FromWhat)
        {
            InitializeComponent();
            LanguagifyComponents();

            EditingLink = FromWhat;
            UpdateFormFromLink(); //read in all the previous values.
        }

        private void LanguagifyComponents()
        {
            Text = NB.Translate("LE_btnLink");
            Text = NB.Translate("_Cancel");
            Text = NB.Translate("LE_Form");
        }


        private void UpdateDeviceList()
        {
            processing = true;
            Network myNet = NB.GetNetwork();
            NicType srcNicType = NicType.none;
            string SrcHost="";
            if (lbSrcHost.SelectedItem != null)
                SrcHost = lbSrcHost.SelectedItem.ToString();
            string DstHost="";
            if (lbDstHost.SelectedItem != null)
                DstHost = lbDstHost.SelectedItem.ToString();
            string SrcNic = "";
            if (lbSrcNic.SelectedItem != null)
            {
                SrcNic = lbSrcNic.SelectedItem.ToString();
                int sNicIndex = lbSrcNic.SelectedIndex;
                NetworkDevice Src = myNet.DeviceFromName(lbSrcHost.SelectedItem.ToString());
                NetworkCard sNic = null;
                if(Src != null) sNic = Src.NicFromName(lbSrcNic.SelectedItem.ToString());
                if(sNic != null) srcNicType = sNic.GetNicType;
            }
            string DstNic = "";
            if (lbDstNic.SelectedItem != null)
                DstNic = lbDstNic.SelectedItem.ToString();
            string theLinkType = LinkType.normal.ToString();
            if (cbLinkType.SelectedItem != null)
                theLinkType = cbLinkType.SelectedItem.ToString();
            int ChosenSrcHost = lbSrcHost.SelectedIndex;
            int ChosenDstHost = lbDstHost.SelectedIndex;
            int tint;
            lbSrcHost.Items.Clear();
            myNet.SortNetComponents(); //just so we have them in order
            List<string> srcHostnames = myNet.GetHostnames();
            List<string> dstHostnames = myNet.GetHostnames();
            foreach(string tString in srcHostnames)
            {
                lbSrcHost.Items.Add(tString);
            }
            if (ChosenSrcHost >= 0)
            {
                ChosenSrcHost = lbSrcHost.Items.IndexOf(SrcHost);
                lbSrcHost.SelectedIndex = ChosenSrcHost;
            }

            lbSrcNic.Items.Clear();
            //List the Nics of the selected host
            if (lbSrcHost.SelectedIndex >= 0)
            {
                List<string> srcNics = myNet.NetworkCardForHostList(lbSrcHost.SelectedItem.ToString(),true,true);
                foreach (string tString in srcNics)
                {
                    lbSrcNic.Items.Add(tString);
                }
            }
            if (EditingLink != null) lbSrcNic.Items.Add(EditingLink.Src.NicName);

            lbDstHost.Items.Clear();
            foreach (string tString in dstHostnames)
            {
                lbDstHost.Items.Add(tString);
            }
            if (ChosenDstHost >= 0)
            {
                ChosenDstHost = lbDstHost.Items.IndexOf(DstHost);
                if(ChosenDstHost >= 0)
                    lbDstHost.SelectedIndex = ChosenDstHost;
            }

            //We cannot link to ourselves.  Remove the source from the dest list
            if (lbSrcHost.SelectedIndex >= 0)
            {
                int delindex = lbDstHost.Items.IndexOf(lbSrcHost.SelectedItem.ToString());
                if (delindex >= 0)
                    lbDstHost.Items.RemoveAt(delindex);
            }


            //remove the dst nic lst
            lbDstNic.Items.Clear();
            if (lbDstHost.SelectedIndex >= 0)
            {
                List<string> dstNics = myNet.NetworkCardForHostList(lbDstHost.SelectedItem.ToString(), true, true, srcNicType);
                foreach (string tString in dstNics)
                {
                    lbDstNic.Items.Add(tString);
                }
            }
            if (EditingLink != null) lbDstNic.Items.Add(EditingLink.Dst.NicName);

            if (SrcNic != "")
            {
                tint = lbSrcNic.Items.IndexOf(SrcNic);
                if (tint != -1)
                    lbSrcNic.SelectedIndex = tint;
            }
            if (DstNic != "")
            {
                tint = lbDstNic.Items.IndexOf(DstNic);
                if (tint != -1)
                    lbDstNic.SelectedIndex = tint;
            }

            if(lbDstNic.SelectedIndex > -1 && lbSrcNic.SelectedIndex > -1)
            {
                btnLink.Enabled = true;
            }
            else
            {
                btnLink.Enabled = false;
            }
            if (Regex.IsMatch(SrcNic, "^wport") || Regex.IsMatch(SrcNic, "^wlan"))
            {
                //It is a wireless nic.
                cbLinkType.Items.Clear();
                cbLinkType.Items.Add(LinkType.wireless.ToString());
                cbLinkType.Enabled = false;
            }
            else
            {
                cbLinkType.Items.Clear();
                cbLinkType.Items.Add(LinkType.normal.ToString());
                cbLinkType.Items.Add(LinkType.broken.ToString());
                cbLinkType.Enabled = true;  
            }
            if (cbLinkType.Items.Contains(theLinkType))
                cbLinkType.SelectedItem = theLinkType;
            else
                cbLinkType.SelectedIndex = 0;
            processing = false;
        }

        private NetworkLink NewLinkFromSettings()
        {
            Network Net = NB.GetNetwork();
            NetworkDevice Src = Net.DeviceFromName(lbSrcHost.SelectedItem.ToString());
            int sNicIndex = lbSrcNic.SelectedIndex;
            NetworkCard sNic = Src.NicFromName(lbSrcNic.SelectedItem.ToString());
            NetworkDevice Dst = Net.DeviceFromName(lbDstHost.SelectedItem.ToString());
            int dNicIndex = lbDstNic.SelectedIndex;
            NetworkCard dNic = Dst.NicFromName(lbDstNic.SelectedItem.ToString());
            LinkType LT = NB.ParseEnum<LinkType>(cbLinkType.SelectedItem.ToString());
            if (sNic.GetNicType == NicType.wport || sNic.GetNicType == NicType.wlan)
                LT = LinkType.wireless; //We cannot have broken wireless links the same way.
            NetworkLink newLink = new NetworkLink(sNic.myID, dNic.myID, LT);
            return newLink;
        }

        private void btnLink_Click(object sender, EventArgs e)
        {
            Network Net = NB.GetNetwork();

            if(EditingLink != null)
            {
                Net.RemoveComponent(EditingLink); //get rid of the old one and put the new one in
            }

            NetworkLink newLink = NewLinkFromSettings();
            //Net.AddItem(newLink);
            int OldLinkID = -1;
            if (EditingLink != null) OldLinkID = EditingLink.GetUniqueIdentifier;
            NB.DoActionChangeComponent(OldLinkID,newLink);
            if (EditingLink != null)
            {
                EditingLink = null;
            }
            Close();
        }

        private void lbSrcHost_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(!processing)
                UpdateDeviceList();
        }

        private void lbDstHost_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!processing)
                UpdateDeviceList();
        }

        private void lbSrcNic_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!processing)
                UpdateDeviceList();
        }

        private void lbDstNic_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!processing)
                UpdateDeviceList();
        }

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

        private void UpdateFormFromLink()
        {

            Network Net = NB.GetNetwork();
            NetworkDevice Src = Net.GetDeviceFromID(EditingLink.Src.HostID);
            NetworkCard sNic = Src.NicFromID(EditingLink.Src.NicID);
            NetworkDevice Dst = Net.GetDeviceFromID(EditingLink.Dst.HostID);
            NetworkCard dNic = Dst.NicFromID(EditingLink.Dst.NicID);
            LinkType LT = EditingLink.theLinkType;

            lbSrcNic.Items.Clear();
            //List the Nics of the selected host
            List<string> srcNics = Net.NetworkCardForHostList(Src.hostname, false, true);
            foreach (string tString in srcNics)
            {
                lbSrcNic.Items.Add(tString);
            }

            lbDstNic.Items.Clear();
            List<string> dstNics = Net.NetworkCardForHostList(Dst.hostname, false, true, sNic.GetNicType);
            foreach (string tString in dstNics)
            {
                lbDstNic.Items.Add(tString);
            }

            UpdateDeviceList();

            lbSrcHost.SelectedItem = Src.hostname;
            lbSrcNic.SelectedItem = sNic.NicName();
            lbDstHost.SelectedItem = Dst.hostname;
            lbDstNic.SelectedItem = dNic.NicName();
            cbLinkType.SelectedItem = LT.ToString();

            UpdateDeviceList();
        }

        private void LinkEditor_Shown(object sender, EventArgs e)
        {
            BuilderWindow BW = NB.GetBuilderWin();
            if (BW != null)
            {
                Point tLocation = new Point(BW.Location.X + ((BW.Width - Width) / 2), BW.Location.Y + ((BW.Height - Height) / 2));
                Location = tLocation;
            }
        }
    }
}