using GenjiDotNet;
using System.Net;


namespace NetCoreSample
{
    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();           
        }

        ~Form1()
        {
        }

        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);
            }
            api.Release();
        }

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

                toolStripStatusLabel1.Text = "";

                ELTimer timer = new ELTimer(1234, 1);

                timer.Start();

                for (int i = 19; i >= 0; i--)
                {
                    Thread.Sleep(1000);
                    ELTimerBtn.Text = i + "秒";
                }

                timer.Stop();

                toolStripStatusLabel1.Text = "20秒(20000ミリ秒)スリープしている間のクロックカウント=" + timer.Count() + "\nタイマー計測の経過時間=" + timer.Millsec() + "ミリ秒";

                ELTimerBtn.Text = "タイマー";
            }
            catch (APIException) { }
            catch (Exception) { }

            api.Release();
        }

        private void ELTimerBtn_Click(object sender, EventArgs e)
        {

            try
            {
                if (toolStripStatusLabel1.Text != "")
                {
                    toolStripStatusLabel1.Text = "";
                    return;
                }

                ThreadPool.QueueUserWorkItem(SleepTimerFunc);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

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

            return;
        }

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

            return;
        }

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

                api.LockData2(1234, 1, 987654123, 1);
                MessageBox.Show("ロック成功");
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiが見つかりません");
                else
                    MessageBox.Show(ex.Message + ":" + ex.errorNo);
            }

            api.Release();
        }

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

                api.LockData2(1234, 0, 987654123, 1);
                MessageBox.Show("アンロック成功");
            }
            catch (APIException ex)
            {
                if (ex.Message == "Count" && ex.errorNo == 0)
                    MessageBox.Show("Genjiが見つかりません");
                else
                    MessageBox.Show(ex.Message + ":" + ex.errorNo);
            }

            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 LEFOFF_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 MemSize2_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                MessageBox.Show("メモリサイズ: " + api.MemSize2(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 Rand_Click(object sender, EventArgs e)
        {
            try
            {
                api.Init();
                api.Count();

                byte[] byteRand = new byte[32];
                api.GetRand(1234, 32, byteRand, 1);
                MessageBox.Show(Convert.ToHexString(byteRand));
            }
            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();


        }


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

            return;
        }

        private void toolStripStatusLabel1_Click(object sender, EventArgs e)
        {
            toolStripStatusLabel1.Text = "";
        }

        /*
                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);
                }

                private void Form1_Load(object sender, EventArgs e)
                {

                }

                private void Form1_FormClosing(object sender, FormClosingEventArgs e)
                {   
        
                }

        */

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

        System.Net.Sockets.UdpClient? udp = null;
        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 = 10005;

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

            frm1Obj.api.RegisterGenjiCallbackPort(10005);


            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();

        }

    }
}