using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DemoAPCSharp
{
    public partial class Form1 : Form
    {
        MW_EasyPOD EasyPOD;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            String strTmp;
            for (int i = 0; i < 15; i++)
            {
                strTmp = "COM" + (i + 1);
                cboPort.Items.Add(strTmp);
            }
            cboPort.SelectedIndex = 0;

            cboBaudRate.Items.Add("1200");
            cboBaudRate.Items.Add("2400");
            cboBaudRate.Items.Add("4800");
            cboBaudRate.Items.Add("9600");
            cboBaudRate.Items.Add("14400");
            cboBaudRate.Items.Add("19200");
            cboBaudRate.Items.Add("28800");
            cboBaudRate.Items.Add("38400");
            cboBaudRate.Items.Add("56000");
            cboBaudRate.Items.Add("57600");
            cboBaudRate.Items.Add("115200");
            cboBaudRate.SelectedIndex = 3;

            cboDevices.Items.Add("EasyPOD");
            cboDevices.Items.Add("EasyCOM");
            cboDevices.SelectedIndex = 0;
            label3.Visible = true;
            label4.Visible = true;
            label5.Visible = true;
            txtVID.Visible = true;
            txtPID.Visible = true;
            txtIndex.Visible = true;
            txtVID.Text = "0E6A";
            txtPID.Text = "0317";
            txtIndex.Text = "1";            
            cboPort.Visible = false;
            cboBaudRate.Visible = false;
            groupBox3.Text = "POD Setting";

            rdoString.Checked = true;         
        }

        private void cboDevices_SelectedIndexChanged(object sender, EventArgs e)
        {
            Int32 i;
            i = cboDevices.SelectedIndex;
            if (i == 0)
            {
                label3.Visible = true;
                label4.Visible = true;
                label5.Visible = true;
                txtVID.Visible = true;
                txtPID.Visible = true;
                txtIndex.Visible = true;
                cboPort.Visible = false;
                cboBaudRate.Visible = false;
                groupBox3.Text = "POD Setting";
                groupBox3.Height = 109;
            }
            else
            {
                label3.Visible = false;
                label4.Visible = false;
                label5.Visible = false;
                txtVID.Visible = false;
                txtPID.Visible = false;
                txtIndex.Visible = false;
                cboPort.Visible = true;
                cboBaudRate.Visible = true;
                groupBox3.Text = "COM Setting";
                groupBox3.Height = 80;
            }

        }

        unsafe private void btnConnect_Click(object sender, EventArgs e)
        {
            UInt32 dwResult, Index;
            String strTmp;            

            if (cboDevices.SelectedIndex == 0)  // EasyPOD
            {
                if ((txtVID.TextLength == 0) || (txtPID.TextLength == 0) || (txtIndex.TextLength == 0))
                {
                    MessageBox.Show("VID or PID or Index must have value", "EasyPOD");
                    return;
                }                
                strTmp = txtVID.Text;
                EasyPOD.VID = Convert.ToUInt32(strTmp, 16);
                strTmp = txtPID.Text;
                EasyPOD.PID = Convert.ToUInt32(strTmp, 16);
                strTmp = txtIndex.Text;
                Index = Convert.ToUInt32(strTmp, 10);

                fixed (MW_EasyPOD* pPOD = &EasyPOD)
                {
                    dwResult = PODfuncs.ConnectPOD(pPOD, Index);
                    if (dwResult == 0x00)
                        txtStatus.Text = "Connect!";
                    else
                    {
                        txtStatus.Text = "Fail Connect To Megawin EasyPOD!";
                    }           
                }               
            }
            else // EasyCOM
            {
                if (serialPort.IsOpen == true)
                    serialPort.Close();
                serialPort.PortName = cboPort.Text;
                serialPort.BaudRate = Convert.ToInt32(cboBaudRate.Text, 10);
                serialPort.ReadTimeout = 0;
                serialPort.Open();
                txtStatus.Text = "Connect!";
            }
        }

        unsafe private void btnDisconnect_Click(object sender, EventArgs e)
        {
            UInt32 dwResult;
            if (cboDevices.SelectedIndex == 0)  // EasyPOD
            {
                fixed (MW_EasyPOD* pPOD = &EasyPOD)
                {
                    if ((pPOD->Handle != 0) && (pPOD->Handle != 0xFFFFFFFF))
                    {
                        dwResult = PODfuncs.DisconnectPOD(pPOD);
                        if (dwResult == 0x00)
                            txtStatus.Text = "Disconnect!";
                        else
                            txtStatus.Text = "Fail To Disconnect Megawin EasyPOD!";
                    }
                }
            }
            else
            {
                if (serialPort.IsOpen == true)
                    serialPort.Close();
                txtStatus.Text = "Disconnect!";
            }
        }

        unsafe private void btnWrite_Click(object sender, EventArgs e)
        {
            byte[] WriteBuffer;
            UInt32 uiLength,uiWritten,uiResult;;

            if (txtWriteBuffer.TextLength == 0)
                return;
            uiLength = TransformData(out WriteBuffer);
            if (cboDevices.Text == "EasyPOD")
            {
                fixed (MW_EasyPOD* pPOD = &EasyPOD)
                {
                    uiResult = PODfuncs.WriteData(pPOD, WriteBuffer, uiLength, &uiWritten);
                    if (uiResult == 0x00)
                    {
                        txtStatus.Text = "Write return size is : " + uiWritten;
                    }
                }
            }
            else
            {
                serialPort.Write(WriteBuffer, 0, (Int32)uiLength);
            }
        }

        private void txtWriteBuffer_KeyPress(object sender, KeyPressEventArgs e)
        {
            Int32 TxtLength = 0;
            Int32 SelectStartIndex = 0;
            Int32 Length = 0;
            string strOld;
            string strModify;
            if (rdoHex.Checked == true)
            {                
                if (e.KeyChar == 8)
                {
                    strOld = txtWriteBuffer.Text;
                    TxtLength = txtWriteBuffer.TextLength;
                    if (TxtLength > 0)
                    {
                        SelectStartIndex = txtWriteBuffer.SelectionStart;
                        Length = ((SelectStartIndex / 3 + 1)) * 3;
                        if (Length <= TxtLength)
                        {
                            strModify = strOld.Substring(Length);
                            if (strModify.Length % 3 != 0)
                                strModify = strModify + " ";
                        }
                        else
                            strModify = "";

                        Length = ((SelectStartIndex - 1) / 3) * 3;
                        txtWriteBuffer.Text = strOld.Substring(0, Length) + strModify;
                        txtWriteBuffer.SelectionStart = txtWriteBuffer.TextLength;
                    }
                    e.Handled = true;
                }
                else if ((e.KeyChar >=48) && (e.KeyChar <=57))
                {
                    strOld = txtWriteBuffer.Text;
                    TxtLength = txtWriteBuffer.TextLength;
                    if (TxtLength % 3 == 0)
                    {
                        strModify = "0" + e.KeyChar;
                    }
                    else if (TxtLength % 3 == 2)
                    {
                        strModify = strOld.Substring(TxtLength-1, 1) + e.KeyChar + " ";
                        strOld = strOld.Substring(0, TxtLength - 2);
                    }
                    else
                    {
                        strModify = "";
                    }
                    txtWriteBuffer.Text = strOld + strModify;
                    txtWriteBuffer.SelectionStart = txtWriteBuffer.TextLength;
                    e.Handled = true;
                }
                else if ((e.KeyChar >=65) && (e.KeyChar <=70))
                {
                    strOld = txtWriteBuffer.Text;
                    TxtLength = txtWriteBuffer.TextLength;
                    if (TxtLength % 3 == 0)
                    {
                        strModify = "0" + e.KeyChar;
                    }
                    else if (TxtLength % 3 == 2)
                    {
                        strModify = strOld.Substring(TxtLength - 1, 1) + e.KeyChar + " ";
                        strOld = strOld.Substring(0, TxtLength - 2);
                    }
                    else
                    {
                        strModify = "";
                    }
                    txtWriteBuffer.Text = strOld + strModify;
                    txtWriteBuffer.SelectionStart = txtWriteBuffer.TextLength;
                    e.Handled = true;
                }
                else if ((e.KeyChar >= 97) && (e.KeyChar <= 102))
                {
                    strOld = txtWriteBuffer.Text;
                    TxtLength = txtWriteBuffer.TextLength;
                    if (TxtLength % 3 == 0)
                    {
                        strModify = "0" + e.KeyChar;
                    }
                    else if (TxtLength % 3 == 2)
                    {
                        strModify = strOld.Substring(TxtLength - 1, 1) + e.KeyChar + " ";
                        strOld = strOld.Substring(0, TxtLength - 2);
                    }
                    else
                    {
                        strModify = "";
                    }
                    txtWriteBuffer.Text = strOld + strModify;
                    txtWriteBuffer.SelectionStart = txtWriteBuffer.TextLength;
                    e.Handled = true;
                }
                else
                {
                    e.Handled = true;                   
                }                
            }
        }

        private void rdoHex_Click(object sender, EventArgs e)
        {
            txtWriteBuffer.Clear();
            txtWriteBuffer.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
        }

        private void rdoString_Click(object sender, EventArgs e)
        {
            txtWriteBuffer.Clear();
            txtWriteBuffer.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
        }
        private UInt32 TransformData(out byte[] buffer)
        {
            UInt32 DataLength;
            Int32 StringLength;
            Int32 i;
            string strTmp;
            string strToken;
            strTmp = txtWriteBuffer.Text;          
            StringLength = txtWriteBuffer.TextLength;
            ASCIIEncoding AE = new ASCIIEncoding();
            if (rdoString.Checked == true)
            {                
                buffer = new byte[StringLength];                                                                 
                buffer = AE.GetBytes(strTmp);
                DataLength = (UInt32)StringLength;
            }
            else
            {                
                buffer = new byte[(StringLength+2) / 3];             
                for (i = 0; (i*3) < StringLength; i++)
                {
                    strToken = strTmp.Substring((i * 3), 2);                    
                    buffer[i] = HexByteToDec(strToken);
                }
                DataLength = (UInt32)i;
            }
            return DataLength;
        }
        private byte HexByteToDec(string strTmp)
        {
            byte bytReturn;
            char chTrans;
            
            chTrans = strTmp[0];
            if ((chTrans >= '0') && (chTrans <= '9'))
                bytReturn = (byte)(16 * (chTrans - 48));
            else
                bytReturn = (byte)(16 * ((chTrans - 'A') + 10));
            chTrans = strTmp[1];

            if ((chTrans >= '0') && (chTrans <= '9'))
                bytReturn = (byte)(bytReturn + (byte)(chTrans - 48));
            else
                bytReturn = (byte)(bytReturn + (byte)((chTrans - 'A') + 10));
            return bytReturn;
        }

        unsafe private void btnRead_Click(object sender, EventArgs e)
        {
            byte[] ReadBuffer = new byte[0x40];
            string strOutput;
            UInt32 uiLength, uiRead, uiResult; ;
            UInt32 uiTotalLength;
            Int16 i;
            if (cboDevices.Text == "EasyPOD")
            {
                fixed (MW_EasyPOD* pPOD = &EasyPOD)
                {
                    uiTotalLength = 0;
                    uiLength = 64;
                    strOutput = "";
                    do
                    {
                        uiResult = PODfuncs.ReadData(pPOD, ReadBuffer, uiLength, &uiRead);
                        if ((uiResult == 0x00) || ((uiRead > 0) && (uiResult == 0xE0000008)))
                        {
                            uiTotalLength = uiTotalLength + uiRead;
                            if (rdoString.Checked == true)
                            {
                                for (i = 0; i < uiRead; i++)
                                    strOutput = strOutput + (char)ReadBuffer[i];
                            }
                            else
                            {                                
                                strOutput = strOutput + BitConverter.ToString(ReadBuffer, 0, (Int32)uiRead).Replace("-", " ");
                            }
                        }
                    } while (uiResult == 0);
                    txtReadBuffer.Text = strOutput;
                    txtStatus.Text = "Read return size is : " + uiTotalLength;
                }
            }
            else
            {
                uiTotalLength = 0;
                strOutput = "";
                do
                {
                    uiRead = 0;
                    try
                    {
                        uiRead = (UInt32)(serialPort.Read(ReadBuffer, 0, serialPort.BytesToRead));
                        if (uiRead > 0)
                        {
                            uiTotalLength = uiTotalLength + uiRead;
                            if (rdoString.Checked == true)
                            {
                                for (i = 0; i < uiRead; i++)
                                    strOutput = strOutput + (char)ReadBuffer[i];
                            }
                            else
                            {
                                strOutput = strOutput + BitConverter.ToString(ReadBuffer, 0, (Int32)uiRead).Replace("-", " ");
                            }
                        }
                        txtReadBuffer.Text = strOutput;
                        txtStatus.Text = "Read return size is : " + uiTotalLength;
                    }
                    catch (TimeoutException) { }
                } while (uiRead > 0);

            }
        }
    }
}