using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Security.Cryptography;
using Microsoft.VisualBasic;

namespace WIN_CLIENT_RPI
{
    public partial class Form1 : Form
    {
        Boolean Prihlaseny = false;
        USB_IP_LIB.Class1 A;
        MD5 md5Hash;
        static List<bool> stav = new List<bool>();
        List<List<string>> LAN_Zariadenia = new List<List<string>>();

        struct CON_VSTUP
        {
            public USB_IP_LIB.Class1 A;
            public string heslo;
            public string PORT;
            public string IP;
            public int port;
            public UInt64 ID;
            public int mod;
        }

        public Form1()
        {
            InitializeComponent();
            button_LAN_connect.Enabled = false;
            button_LAN_DISCONNECT.Enabled = false;
            button_LAN_connect.Enabled = false;
            button_LAN_connect2.Enabled = false;
            stav.Add(false);
            stav.Add(false);
            md5Hash = MD5.Create();
            //ClientFunctions.GetMd5Hash(md5Hash,PasswordDeriveBytes)
            //string hashheslo = GetMd5Hash(md5Hash, heslo);
            A = new USB_IP_LIB.Class1();
            //string str = Properties.Settings.Default.IPs[1];
            ClientFunctions.Connect();
            
            //ClientFunctions.Login();
            //Properties.Settings.Default.Save();

            //textBox.Text = Properties.Settings.Default.Setting;
        

           // System.Resources.IResourceWriter write = new System.Resources.ResourceWriter("myResources.resources");
           // write.AddResource("string1", "pokus");
           // write.Close();





        }

        private void Connect_click(object sender, EventArgs e)
        {
            string meno = textBox1.Text;
            string heslo= textBox2.Text;
            bool ok = ClientFunctions.Login(meno,heslo);
            if (ok)
            {
                button1.BackColor = Color.LightGreen;
                Prihlaseny = true;
            }
            else
            {
                button1.BackColor = Color.Red;
                Prihlaseny = false;
            }
        }

        private void Register_click(object sender, EventArgs e)
        {
            if (textBox_Register_Heslo.Text != textBox_Register_overenie_hesla.Text)
            {
                MessageBox.Show("Zadané heslá sa nezhodujú!", "WARNING"); return;
            }
            string meno = textBox_Register_meno.Text;
            string heslo = textBox_Register_Heslo.Text;
            string mail = textBox_Register_Mail.Text;
            bool ok =ClientFunctions.Register(meno, heslo,mail);
            if (ok) button_Register_User.BackColor = Color.LightGreen;
            else button_Register_User.BackColor = Color.Red;
        }

        private void Add_devi_click(object sender, EventArgs e)
        {
            if (!Prihlaseny)
            {
                MessageBox.Show("Neprihlaseny"); return;
            }
            if (textBox_ADD_DEVI_HESLO.Text != textBox_ADD_DEVI_orerPASS.Text)
            {
                MessageBox.Show("Zadané heslá sa nezhodujú!", "WARNING"); return;
            }

            UInt64 ID;
            string sID = textBox_ADD_DEVI_ID.Text;
            string heslo = textBox_ADD_DEVI_HESLO.Text;
            UInt16 typ = (UInt16)comboBox_ADD_DEVI_TYP.SelectedIndex;
            if (typ < 0){
            
                MessageBox.Show("Neplatne zvolený typ"); return;
            }
            if(!UInt64.TryParse(sID,System.Globalization.NumberStyles.AllowHexSpecifier,null,out ID))
            {
                MessageBox.Show("Chybne zadané ID"); return;
            }
            bool ok = ClientFunctions.ADD_Devi(typ, ID, heslo);
            if (ok) button_ADD_Devi.BackColor = Color.LightGreen;
            else button_ADD_Devi.BackColor = Color.Red;
        }

        private void Get_Devices(object sender, EventArgs e)
        {
            if (!Prihlaseny)
            {
                MessageBox.Show("Neprihlaseny"); return;
            }
            int pocet;
            UInt64 ID = 0;
            string PORTA,PORTB;
            var pole = ClientFunctions.GET_Devi(out pocet);
            if (pocet == 0 || pole == null) { Prihlaseny = false; return; }
            //dataGridView1.ColumnCount = 2;
            dataGridView1.RowCount = pocet;
            for (int i=0;i<pocet;i++){
                ID=BitConverter.ToUInt64(pole, 0 + i * 10);
                dataGridView1.Rows[i].Cells[0].Value = ID.ToString("X");
                dataGridView1.Rows[i].Cells[1].Value = BitConverter.ToUInt16(pole, 8 + i * 10);
                if (ClientFunctions.GET_Connected_to_RPi(ID, out PORTA, out PORTB))
                {
                    dataGridView1.Rows[i].Cells[3].Value = "pripoj";
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Items.Clear();
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Items.Add(PORTA);
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Items.Add(PORTB);
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Value = PORTA;

                }
                else
                {
                    dataGridView1.Rows[i].Cells[3].Value = "------";
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Items.Clear();
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Items.Add("------");
                    ((DataGridViewComboBoxCell)(dataGridView1.Rows[i].Cells[2])).Value = "------";
                }

            }
        }

        private void Open_connect(object sender, EventArgs e)
        {
            IPAddress iIP;
            if (IPAddress.TryParse(textBox_IP_direct.Text, out iIP))
            {
                CON_VSTUP vstup;
                if (((Button)sender).Name == "button_LAN_connect")
                {
                    vstup.PORT = "1-1.2";
                    vstup.port = 0;
                }
                else
                {
                    vstup.PORT = "1-1.3";
                    vstup.port = 1;
                }
                if (stav[vstup.port])
                {
                    MessageBox.Show("Už pripojené","WARNING");
                }
                stav[vstup.port] = true;
                vstup.A = A;
                vstup.heslo = ClientFunctions.GetMd5Hash(md5Hash, textBox_HESLO_LAN.Text);
                vstup.IP = textBox_IP_direct.Text;
                vstup.mod = 3;//LOCAL
                //3 LAN
                //2 prepojenie cez server
                //1 SERVER
                vstup.ID = 0x00000000bdbe5751;


                System.Threading.Thread thr = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(vlakno));
                thr.Start(vstup);
            }
            else {
                MessageBox.Show("NEPLATNA IPAddress ADRESA");
            }
            button_LAN_DISCONNECT.Enabled = true;
            textBox_IP_direct.Enabled = false;
            button_Dostupnost_konstrola.Enabled = false;
            ((Button)sender).BackColor = Color.Orange;
            timer_connect.Enabled = true;
        }
         
        static void vlakno(object input)
        {
            CON_VSTUP vstup = (CON_VSTUP)input;
            //USB_IP_LIB.Class1 A = (USB_IP_LIB.Class1)vstup;
            //byte[] IP = Encoding.ASCII.GetBytes("147.229.221.101");
            //byte[] IP = Encoding.ASCII.GetBytes("gameroompn.no-ip.biz");

            //byte[] IP = Encoding.ASCII.GetBytes("127.0.0.1");
            byte[] IP = Encoding.ASCII.GetBytes(vstup.IP);
            byte[] meno = Encoding.ASCII.GetBytes(vstup.PORT);
            
            byte[] pass = Encoding.ASCII.GetBytes(vstup.heslo);
            //0x00000000bdbe5751
            //   byte[] buffer = new byte[[256];
            int ret = 0;
            unsafe
            {
                fixed (void* ptr_byte = &IP[0], ptr_byte2 = &meno[0], ptr_byte3 = &pass[0])
                {
                    try
                    {
                        ret = vstup.A.attach_device((sbyte*)ptr_byte, (sbyte*)ptr_byte2, (sbyte*)ptr_byte3,vstup.mod,vstup.ID);
                        stav[vstup.port] = false;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(),"ERROR");
                    }
                }
            }
            if (ret==-10)
                MessageBox.Show("NEPLATNÉ HESLO");
            if (ret==-9)
                MessageBox.Show("ERROR NEPODARILO SA PRIPOJIT KU ZARIADENIU");
             
        }

        private void Close_Con(object sender, EventArgs e)
        {
            try
            {
                if (A != null)
                    A.PRIPOJENE = false;
            }
            catch (Exception)
            {
                MessageBox.Show("error");
            }
            button_LAN_DISCONNECT.Enabled = false;
            textBox_IP_direct.Enabled = true;
            button_Dostupnost_konstrola.Enabled = true;
            button_LAN_connect.BackColor = Color.WhiteSmoke;
            button_LAN_connect2.BackColor = Color.WhiteSmoke;
            //conected = 0;
        }

        private void Get_Pass(object sender, EventArgs e)
        {
            if (!Prihlaseny)
            {
                MessageBox.Show("Neprihlaseny"); return;
            }
            var pole = ClientFunctions.GET_Pass(20015997076257);
            MessageBox.Show(pole);
        }

        private void button_Dostupnost_konstrola_Click(object sender, EventArgs e)
        {
            byte[] buf = new byte[128];
            IPAddress IP;


            #region pripojenie
            /*
            System.Net.Sockets.TcpClient cl = new System.Net.Sockets.TcpClient();
            if (!IPAddress.TryParse(textBox_IP_direct.Text, out IP))
            {
                MessageBox.Show("Neplaná IP ADRESA", "WARNING");
                return;
            }
            cl.SendTimeout = 1000;
            cl.ReceiveTimeout = 1000;
            try
            {
                IAsyncResult result = cl.BeginConnect(IP, 4444, null, null);
                bool success = result.AsyncWaitHandle.WaitOne(2000, true);

                if (success)
                    cl.EndConnect(result);
                else
                {
                    cl.Close();
                    MessageBox.Show("Nepodarilo sa nájisť zariadenie", "WARNING");
                    return;
                }
                //cl.Connect(IP, 4444);//3240 4444
            }
            catch (Exception)
            {
                MessageBox.Show("CHYBA ZARIADENIA", "WARNING");
                return;
            }*/
            #endregion
            #region pripojenie2
            
            System.Net.Sockets.UdpClient cl = new System.Net.Sockets.UdpClient();
            
            if (!IPAddress.TryParse(textBox_IP_direct.Text, out IP))
            {
                MessageBox.Show("Neplaná IP ADRESA", "WARNING");
                return;
            }
            IPEndPoint endpoint = new IPEndPoint(IP, 4444);
            cl.Client.SendTimeout = 1000;
            cl.Client.ReceiveTimeout = 1000;
            
            #endregion
            #region nacitaj 
            /*
            buf[0] = 0;
            IP.GetAddressBytes().CopyTo(buf,1);
            int nacitane = 0;
            try
            {
                cl.GetStream().Write(buf, 0, 10);
                cl.GetStream().ReadTimeout = 1000;
                nacitane = cl.GetStream().Read(buf, 0, buf.Length);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
             */
            #endregion 
            #region nacitaj2
            buf[0] = 0;
            IP.GetAddressBytes().CopyTo(buf,1);
            int nacitane = 0;
            try
            {
                cl.Send(buf, 10,endpoint);
                buf = cl.Receive(ref endpoint);
                nacitane = buf.Length;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
             
            #endregion 
            if (nacitane < 11) return;
            int VIDA, PIDA, VIDB, PIDB;
            VIDA = BitConverter.ToUInt16(buf, 4);
            PIDA = BitConverter.ToUInt16(buf, 6);
            VIDB = BitConverter.ToUInt16(buf, 8);
            PIDB = BitConverter.ToUInt16(buf, 10);
            textBox_LAN_PORTA.Text = VIDA.ToString("X4") + ":" + PIDA.ToString("X4");
            textBox_LAN_PORTB.Text = VIDB.ToString("X4") + ":" + PIDB.ToString("X4");

            if (VIDA != 0)
                button_LAN_connect.Enabled = true;
            else
                button_LAN_connect.Enabled = false;
            if (VIDB != 0)
                button_LAN_connect2.Enabled = true;
            else
                button_LAN_connect2.Enabled = false;
            cl.Close();
        }

        private void LAN_Zmena_IP(object sender, EventArgs e)
        {
            button_LAN_connect.Enabled = false;
            button_LAN_connect2.Enabled = false;
           // conected = 0;
        }

        private void skontroluj(object sender, EventArgs e)
        {
            timer_connect.Enabled = false;
            if (stav[0])
                button_LAN_connect.BackColor = Color.LightGreen;
            else
                button_LAN_connect.BackColor = Color.WhiteSmoke;
            if (stav[1])
                button_LAN_connect2.BackColor = Color.LightGreen;
            else
                button_LAN_connect2.BackColor = Color.WhiteSmoke;
        }

        private void WAN_SERVER_CONNECT(object sender, EventArgs e)
        {
            if (!Prihlaseny)
            {
                MessageBox.Show("Neprihlaseny"); return;
            }
            UInt64 ID = 0x00000000bdbe5751;


            System.Net.IPAddress IP = ClientFunctions.Connect_Server_Forvarding(ID);
            //ClientFunctions.GET_Pass();
            if (IP == null)
            {
                MessageBox.Show("zariadenie je offline");
                return;
            }
            CON_VSTUP vstup;

            //stav[0] = true;
            vstup.PORT = "1-1.2";
            vstup.port = 1;
            vstup.A = A;
            vstup.heslo = ClientFunctions.GetMd5Hash(md5Hash, "AHOJ");  //upraviť heslo
            vstup.IP = IP.ToString();
            vstup.mod = 2;//LOCAL
            //3 LAN
            //2 prepojenie cez server
            //1 SERVER
            vstup.ID = ID;


            System.Threading.Thread thr = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(vlakno));
            thr.Start(vstup);
            //MessageBox.Show(pole);
        }

        private void DGW_click(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            if (e.ColumnIndex != 3)
                return;
            if (dataGridView1.Rows[index].Cells[2].Value.ToString() == "------" || dataGridView1.Rows[index].Cells[2].Value.ToString() == "0000:0000")
            {
                MessageBox.Show("Nieje možné pripojiť, neplatné zariadenie", "WARNING");
                return;
            }

            if (!Prihlaseny)
            {
                MessageBox.Show("Neprihlaseny"); return;
            }
            UInt64 ID = Convert.ToUInt64(dataGridView1.Rows[index].Cells[0].Value.ToString(), 16);


            string Heslo = ClientFunctions.GET_Pass(ID);
            System.Net.IPAddress IP = ClientFunctions.Connect_Server_Forvarding(ID);
             
            if (IP == null || Heslo==null)
            {
                MessageBox.Show("zariadenie je offline");
                return;
            }
            CON_VSTUP vstup;
            //stav[0] = true;
            vstup.PORT = dataGridView1.Rows[index].Cells[2].Value.ToString();
            vstup.port = ((DataGridViewComboBoxCell)dataGridView1.Rows[index].Cells[2]).Items.IndexOf(vstup.PORT);

            switch (vstup.port)
            { 
                case 0 :vstup.PORT = "1-1.2";  break;
                case 1 :vstup.PORT = "1-1.3";   break;
                default: return;
            }

            vstup.A = A;
            vstup.heslo = ClientFunctions.GetMd5Hash(md5Hash, "AHOJ");  //upraviť heslo
            vstup.IP = IP.ToString();
            vstup.mod = 2;//cez server;
            //3 LAN
            //2 prepojenie cez server
            //1 SERVER
            vstup.ID = ID;


            System.Threading.Thread thr = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(vlakno));
            thr.Start(vstup);
            //MessageBox.Show(pole);    
            return;
        }

        private void Rem_Devices(object sender, EventArgs e)
        {


            if (dataGridView1.SelectedRows.Count == 0)
                return;

            System.Windows.Forms.DialogResult res = MessageBox.Show("vymazať?", "WARNING", MessageBoxButtons.YesNo);
            if (res == System.Windows.Forms.DialogResult.Yes)
            {
                UInt64 ID = Convert.ToUInt64(dataGridView1.SelectedRows[0].Cells[0].Value.ToString(), 16);
                if (ClientFunctions.REM_Devi(ID))
                    MessageBox.Show("OK");
                else
                    MessageBox.Show("NOK");
                Get_Devices(sender, e);
            }
        }

        private void zatvaranie(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (A != null)
                    A.PRIPOJENE = false;
            }
            catch (Exception)
            {
                MessageBox.Show("error");
            }
        }

        private void Connect_Broadcast_Click(object sender, EventArgs e)
        {
            System.Net.Sockets.UdpClient client = new System.Net.Sockets.UdpClient();
            //IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.1"),4444);
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Broadcast, 4444);
            //client.Connect("192.168.1.1", 4444);
            byte [] pole = new Byte[128];
            ASCIIEncoding.UTF8.GetBytes("\0USB_IP_GET_CONFIG_ALL").CopyTo(pole, 0);

            client.Send(pole, 32, endpoint);
            
            client.BeginReceive(Accept_settings,client);

            timer_Nastavenie.Enabled = true;
            //pole = client.Receive(ref endpoint);
            //[pole = client.Receive(ref endpoint);
            //client.Client.Send(pole,0,10,System.Net.Sockets.SocketFlags.None);
            //client.Client.Receive(pole);
        }
        private void Accept_settings(IAsyncResult ar)
        {
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Broadcast, 4444);
            System.Net.Sockets.UdpClient c = (System.Net.Sockets.UdpClient)ar.AsyncState;
            var pole = c.EndReceive(ar, ref endpoint);
            c.BeginReceive(Accept_settings, c);

        }

        private void Zmena_Hesla(object sender, EventArgs e)
        {
            string pokus = Interaction.InputBox("Zadajte prosím nové heslo", "Zmeniť heslo?", "######");
            if (pokus!="######")
                LAN_Zariadenia[0][6]=pokus; 
        }

        private void SaveConfig(object sender, EventArgs e)
        {
            System.Net.Sockets.UdpClient client = new System.Net.Sockets.UdpClient();
            //IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.1"),4444);
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Broadcast, 4444);
            //client.Connect("192.168.1.1", 4444);
            byte[] pole = new Byte[128];
            ASCIIEncoding.UTF8.GetBytes("\0USB_IP_SET_CONFIG_ALL").CopyTo(pole, 0);

            for (int i = 0; i < 7;i++ )
                ASCIIEncoding.UTF8.GetBytes(LAN_Zariadenia[0][i]).CopyTo(pole, 32+i*32);
            client.Send(pole, 256, endpoint);

            client.BeginReceive(Accept_settings, client);

            timer_Nastavenie.Enabled = true;
            //pole = client.Receive(ref endpoint);
            //[pole = client.Receive(ref endpoint);
            //client.Client.Send(pole,0,10,System.Net.Sockets.SocketFlags.None);
            //client.Client.Receive(pole);

        }

        private void Print_Config(object sender, EventArgs e)
        {
            timer_Nastavenie.Enabled = false;
            if (LAN_Zariadenia.Count == 0)
            {
                MessageBox.Show( "Nepodarilo sa nájisť žiadne zariadenie","Warning");
                return;
            }
            comboBox_ID.Text = LAN_Zariadenia[0][0];
            textBox_IP.Text= LAN_Zariadenia[0][1];
            textBox_MASK.Text = LAN_Zariadenia[0][2];
            textBox_GTW.Text= LAN_Zariadenia[0][3];
            textBox_DNS1.Text=LAN_Zariadenia[0][4];
            textBox_DNS2.Text=LAN_Zariadenia[0][5]; 
        }
    }
}
