using GenjiDotNet;
using System;
using System.Net;
using System.Threading;
using System.Windows.Forms;

namespace NetFrameworkSample
{
    public partial class Form1 : Form
    {
        GenjiDotNet.API api = new GenjiDotNet.API();
        uint devChangeMsg = WinAPI.RegisterWindowMessage("ELDongleAPI_Device_Change");

        public Form1()
        {
            InitializeComponent();

            api.Init();
            api.Release();

        }

        private void LEDON_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                api.SetLED(-1, 1);
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiを接続してください");
                else
                    MessageBox.Show(ex.Message + ";" + ex.errorNo);
            }

            api.Release();
        }

        private void LEDOFF_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                api.SetLED(0, 1);
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiを接続してください");
                else
                    MessageBox.Show(ex.Message + ";" + ex.errorNo);
            }

            api.Release();

        }

        private void LEDBLINK_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                api.SetLED(3, 1);
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiを接続してください");
                else
                    MessageBox.Show(ex.Message + ";" + ex.errorNo);
            }

            api.Release();

        }

        private void ReadGUSN_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                MessageBox.Show(api.ReadGUSN(1234, 1));
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiを接続してください");
                else
                    MessageBox.Show(ex.Message + ";" + ex.errorNo);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message );
            }

            api.Release();
        }

        void SleepTimerFunc(object arg)
        {
            try
            {
                api.Init();
                api.Count();

                ELTimer timer = new ELTimer(1234, 1);

                timer.Start();

                Thread.Sleep(5000);

                timer.Stop();

                MessageBox.Show("5秒(5000ミリ秒)スリープしている間のクロックカウント=" + timer.Count() + "\nタイマー計測の経過時間=" + timer.Millsec() + "ミリ秒");
                Timer.Enabled = true;

            }
            catch (APIException) { }
            catch (Exception) { }

            api.Release();

        }


        private void Timer_Click(object sender, EventArgs e)
        {
            try
            {
                Timer.Enabled = false;
                ThreadPool.QueueUserWorkItem(SleepTimerFunc);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Rand_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                byte[] byteRand = new byte[32];
                api.GetRand(1234, 32, byteRand, 1);
                MessageBox.Show(BitConverter.ToString(byteRand).Replace("-", ""));
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiを接続してください");
                else
                    MessageBox.Show(ex.Message + ";" + ex.errorNo);
            }

            api.Release();

        }

        private void Data_Click(object sender, EventArgs e)
        {
            dataForm frm = new dataForm(api);
            frm.ShowDialog();
        }

        private void RSAEncrypt_Click(object sender, EventArgs e)
        {
            RSAForm frm = new RSAForm(api);
            frm.ShowDialog();
        }

        private void Signature_Click(object sender, EventArgs e)
        {
            SigForm frm = new SigForm(api);
            frm.ShowDialog();
        }

        /*
        //Genji の抜差をメッセージで受け取る
        // 　devChangeMsg = WinAPI.RegisterWindowMessage("ELDongleAPI_Device_Change") 

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == devChangeMsg)
            {
                try
                {
                    api.Init();

                    int count = api.Count();

                    if ((uint)m.WParam == WinAPI.DBT_DEVICEARRIVAL)
                        MessageBox.Show("接続:" + count);
                    else
                        MessageBox.Show("抜き取り:" + count);
                }
                catch (APIException ex)
                {
                    if (ex.Message == "Count" && ex.errorNo == 0)
                        MessageBox.Show("抜き取り:0");
                    else
                        MessageBox.Show(ex.Message + "- Error;" + ex.errorNo);
                }
                api.Release();

            }


            base.WndProc(ref m);
        }
        */

        //Genji の抜差を UDP で受け取る
        //RegisterCallbackPort(port);

        System.Net.Sockets.UdpClient udp;
        Thread myThread;

            private static void DevChangeThread(Form1 frm1Obj)
            {
                //バインドするローカルIPとポート番号
                string localIpString = "127.0.0.1";
                System.Net.IPAddress localAddress =
                    System.Net.IPAddress.Parse(localIpString);
                int localPort = 10001;

                //UdpClientを作成し、ローカルエンドポイントにバインドする
                System.Net.IPEndPoint localEP = new System.Net.IPEndPoint(localAddress, localPort);
                frm1Obj.udp = new System.Net.Sockets.UdpClient(localEP);

                frm1Obj.api.RegisterGenjiCallbackPort(10001);

                while (true)
                {
                    try
                    {
                        System.Net.IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                        byte[] rcvBytes = frm1Obj.udp.Receive(ref remoteEP);

                        string rcvMsg = System.Text.Encoding.UTF8.GetString(rcvBytes);

                        MessageBox.Show(rcvMsg, "デバイス抜差");
                    }
                    catch (Exception ex)
                    {
                        //socket closed & disposed 以外
                        if (ex.HResult != -2147467259 && ex.HResult != -2146232798)
                            MessageBox.Show(ex.Message + " " + ex.HResult);

                        break;
                    }
                }

            }

            private void Form1_Load(object sender, EventArgs e)
            {
                myThread = new Thread(() => DevChangeThread(this));
                myThread.Start();
            }

            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {

                //UdpClientを閉じる
                if( udp != null)
                    udp.Close();

            }
 
    }
}
