using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MSRDemo
{
    [StructLayout(LayoutKind.Sequential)]
    public struct Tests
    {
        // UnmanagedType.ByValArray， [MarshalAs(UnmanagedType.U1)]这个非常重要，就是申明对应类型和长度的
        [MarshalAs(UnmanagedType.U2)]
        public char a1;

        [MarshalAs(UnmanagedType.U2)]
        public char a2;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
        public char[] a3;

        [MarshalAs(UnmanagedType.U8)]
        public long a4;

    };

    [StructLayout(LayoutKind.Sequential)]
    public struct PARSEDATAFORMAT
	{
       // [MarshalAs(UnmanagedType.U2)]
        public char startSentinel;
       // [MarshalAs(UnmanagedType.U2)]
        public char endSentinel;
	};


    public partial class Form1 : Form
    {
        private MessageBoxButtons buttons = MessageBoxButtons.OKCancel;
        private bool m_bconncet = false;
        public int iExit = 0;
        //private int m_handle = 0;
        private string m_csdata = ("");
        private char[,] m_szTrackFormat = new char[64, 2];
        private int m_nTrackFormat;
        private int baud, parity, databits, stopbits;
//#if 1
        Tests[] pTrackData = new Tests[16];
        //int iStructSize = Marshal.SizeOf(typeof(Tests));
        int num = 8;
//#endif
//        int[] a = new int[10];

        public delegate void MsrDataCallback(IntPtr pTrackData, UInt32 dataLen);
        public delegate void TextBoxDelegate();
        //typedef void (__stdcall *MsrDataCallback)(void *pBuf,long dataLen);

        [DllImport("DTMsrAPI.dll")]
        public static extern int Msr_Connect(int Handle);

        [DllImport("DTMsrAPI.dll")]
        public static extern int Msr_Disconnect();
        [DllImport("DTMsrAPI.dll")]
        public static extern UInt16 Msr_GetFirmwareInfo(string name, int nameBufLen, string version, int verBufLen);
        [DllImport("DTMsrAPI.dll")]
        public static extern UInt16 Msr_GetPortParameters(ref int baud, ref int databits, ref int parity, ref int stopbits);
        [DllImport("DTMsrAPI.dll", CharSet = CharSet.Auto)]   
        public static extern int Msr_SetDataReceiverCallback(MsrDataCallback revFun);
        [DllImport("DTMsrAPI.dll")]
        public static extern unsafe UInt16 Msr_ParseEnable(bool bParse, PARSEDATAFORMAT* parseFormat, int parseCount);

        [DllImport("DTMsrAPI.dll")]
        public static extern UInt16 Msr_SetPortParameters(int baud, int databits, int parity, int stopbits);

        MsrDataCallback callbackDelegate;
        public Form1()
        {
            InitializeComponent();
            int j = 0;
            int i = 0;
            char a;
            for (i = 0; i < 64; i++)
            {
                m_szTrackFormat[i,0] = '\0';
                m_szTrackFormat[i,1] = '\0';
            }

            j = 0;
            a = '!';
            for (i = 0; i < 15; i++)
            {
                m_szTrackFormat[j++,0] = a++;

            }
            a = ':';
            for (i = 0; i < 7; i++)
            {
                m_szTrackFormat[j++,0] = a++;

            }
            a = '[';
            for (i = 0; i < 6; i++)
            {
                m_szTrackFormat[j++,0] = a++;

            }
            a = '{';
            for (i = 0; i < 4; i++)
            {
                m_szTrackFormat[j++,0] = a++;

            }
            m_nTrackFormat = j;
            m_szTrackFormat[j++,0] = '\0';
            for (i = 0; i < m_nTrackFormat; i++)
            {
                string str = m_szTrackFormat[i, 0].ToString();
                comboBox6.Items.Add(str);
                comboBox7.Items.Add(str);
            }
            comboBox1.SelectedIndex = 2;

            comboBox6.SelectedIndex = 16;
            comboBox7.SelectedIndex = 20;
            textBox2.Text = "";
            textBox2.ScrollToCaret();
            textBox1.Enabled = false;
            textBox2.Enabled = false;
            textBox3.Enabled = false;
            comboBox5.Enabled = false;
            comboBox4.Enabled = false;
            comboBox3.Enabled = false;
            comboBox2.Enabled = false;
            button6.Enabled = false;
            button5.Enabled = false;
        }

        private void ShowErrMsg(int error)
        {
            string str = "";
	        switch(error)
	        {
	        case 0:
		        break;
	        case 1:
		        str = "Interface is invalid";
		        break;
	        case 2:
		        str = "No device found";
		        break;
	        case 3:
		        str = "Time out";
		        break;
	        case 4:
		        str = "Not connected";
		        break;
	        case 5:
		        str = "Dll inner error";
		        break;
	        case 6:
		        str = "Not support";
		        break;
	        case 7:
		        str = "Connection lost";
		        break;
	        default:
		        str = "UnKnown";
		        break;
	        }
            if (str.Length != 0)
            {
                MessageBox.Show(str, "Warning", buttons, 0, 0);
            }
        }
        public void UpdataPortParameters()
        {
            
	        int i=0;
	        int count;
	       // CString str,strParam;
	        int result = Msr_GetPortParameters(ref baud,ref databits,ref parity,ref stopbits);
	        //TRACE("Port Parameters:%d,%d,%d,%d",baud,databits,parity,stopbits);
	        if (result==0)
	        {
               
		        count = comboBox2.Items.Count;
		        for (i=0;i<count;i++)
		        {
                    string str1 = baud.ToString();
                    string str2 = comboBox2.Items[i].ToString();
                 
                    if (str1.CompareTo(str2) == 0)
			        {
				        comboBox2.SelectedIndex = i;
				        break;
			        }
		        }

		        //databits;
                count = comboBox3.Items.Count;
                for (i = 0; i < count; i++)
                {
                    string str1 = databits.ToString();
                    string str2 = comboBox3.Items[i].ToString();

                    if (str1.CompareTo(str2) == 0)
                    {
                        comboBox3.SelectedIndex = i;
                        break;
                    }
                }

		        //parity

		        if (parity<3)
		        {
			        comboBox4.SelectedIndex = parity;
		        }

		        if (stopbits>=0&&stopbits<1)
		        {
                    comboBox5.SelectedIndex = stopbits;
		        }          
	        }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            int result;
            if (m_bconncet)
            {
                result = Msr_Disconnect();
                if (result == 0)
                {
                    m_bconncet = false;
                    textBox1.Enabled = false;
                    textBox2.Enabled = false;
                    textBox3.Enabled = false;
                    comboBox5.Enabled = false;
                    comboBox4.Enabled = false;
                    comboBox3.Enabled = false;
                    comboBox2.Enabled = false;
                    button6.Enabled = false;
                    button5.Enabled = false;
                    comboBox1.Enabled = true;
                    button1.Text = "Connect";  
                }
                ShowErrMsg(result);
            }
            else
            {
                int index = comboBox1.SelectedIndex;
                if (index >= 0)
                {
                    index += 1;
                }
                result = Msr_Connect(index);
                if(result == 0)
                {
                    button1.Text = "Disconnect";
                    m_bconncet = true;
                    string name=("aaaaaaaaaaaaaaaaaaaaaaaaa");
                    string versiona = ("bbbbbbbbbbbbbbbbbbbbbbbbbb");
                  
                    Msr_GetFirmwareInfo(name, 256, versiona, 256);
                    textBox1.Text = name;
                    textBox3.Text = versiona;
                    textBox1.Enabled = true;
                    textBox2.Enabled = true;
                    textBox3.Enabled = true;
                    comboBox5.Enabled = true;
                    comboBox4.Enabled = true;
                    comboBox3.Enabled = true;
                    comboBox2.Enabled = true;
                    button6.Enabled = true;
                    button5.Enabled = true;
                    comboBox1.Enabled = false;
                    UpdataPortParameters();
                    callbackDelegate = new MsrDataCallback(revFun);
                    Msr_SetDataReceiverCallback(callbackDelegate);
                    
                }
                ShowErrMsg(result);
            }
        }

        private void revFun(IntPtr pTrackData, UInt32 dataLen)
        {
           Tests[] tructList = new Tests[16];
           // int iStructSize = Marshal.SizeOf(typeof(Tests));
           // int num = 8;
            for (int i = 0; i < 10; i++)
			{
               // tructList[i] = (Tests)Marshal.PtrToStructure((IntPtr)((UInt32)pTrackData + 0), typeof(Tests));
                tructList[i] = (Tests)Marshal.PtrToStructure((IntPtr)((UInt32)pTrackData + i * Marshal.SizeOf(typeof(Tests)) - num * i), typeof(Tests));
            }           
            string ssText = "";
            for (int j = 0; j < dataLen; j++)
            {
               // MessageBox.Show(tructList[j].a1.ToString());
                ssText = "";
                int i = 0;
                while (1 == 1) //(int i = 0; i < 40; i++)
                {
                    if (tructList[j].a3[i].CompareTo('\0') != 0)
                    {
                        ssText += tructList[j].a3[i].ToString();
                        i++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (ssText.CompareTo("\0") != 0)
                {
                    m_csdata = ssText;
                    int b1 = (int)tructList[j].a1, b2 = (int)tructList[j].a2;
                    if (tructList[j].a1 == 0 && tructList[j].a2 == 0)
                    {
                       // MessageBox.Show(m_csdata);
                        TextBoxHandle(m_csdata);
                    }
                    else
                    {
                        
                        m_csdata = "[SS:" + b1.ToString("x") + "]" + m_csdata + "[ES:" + b2.ToString("x") + "]";
                       // MessageBox.Show("zhang"+m_csdata);
                        TextBoxHandle(m_csdata);
                    }
                }
            }
         /*   MessageBox.Show(dataLen.ToString());
            for (int i = 0; i < dataLen; i++)
            {
                int b1 = (int)tructList[i].a1, b2 = (int)tructList[i].a2;
                
                if (tructList[i].a1 == 0 && tructList[i].a2 == 0)
                {
                    TextBoxHandle(m_csdata);
                }
                else
                {
                    m_csdata = "";
                    m_csdata = "[SS:" + b1.ToString("x")+"]" + m_csdata + "[ES:" + b2.ToString("x")+"]"; 
                    TextBoxHandle(m_csdata);
                }
            }*/
        }
        private void TextBoxHandle(string sData)
        {
            if (!textBox2.InvokeRequired)  //如果在UI主线程操作ListBox，
            {
                textBox2.Text += sData;  //则直接进行控件操作，“与UI主线程相关联”
            }
            else  //如果是在另一线程操作TextBox,则启用委托
            {
                if (iExit == 0)
                {
                    textBox2.Invoke(new TextBoxDelegate(TextShow));
                }
            }
        }
        private void TextShow()
        {
           // MessageBox.Show("11");
            textBox2.Text += m_csdata;
             textBox2.Text += "\r\n";
           // textBox2.ScrollBars = ScrollBars.Vertical;
            
            textBox2.SelectionStart = textBox2.Text.Length;
           // MessageBox.Show()
            //textBox2.Top = true;
            textBox2.ScrollToCaret();
        }
       /* private void button2_Click(object sender, EventArgs e)
        {
            textBox2.Text = m_csdata;
        }*/

        private void comboBox7_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            string str = m_szTrackFormat[comboBox6.SelectedIndex,0].ToString()+m_szTrackFormat[comboBox7.SelectedIndex,0].ToString();
            listBox1.Items.Add(str);
         
        }
        
        private void button3_Click(object sender, EventArgs e)
        {
            if ((listBox1.Items.Count <= 0) || (listBox1.SelectedIndex<0))
            {
                return;
            }
           
            listBox1.Items.RemoveAt(listBox1.SelectedIndex);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            int count = listBox1.Items.Count;
            if (count < 0)
                return;
            PARSEDATAFORMAT[] pFormatData = new PARSEDATAFORMAT[count];
            bool bParse = false;
            if(checkBox1.CheckState == CheckState.Checked)
            {
               
                bParse = true;
            }
            else if (checkBox1.CheckState == CheckState.Unchecked)
            {
                
                bParse = false;
            }
            string szFormat = "";
            unsafe
            {
                fixed (PARSEDATAFORMAT* meptr = pFormatData)
                {    
                    int n = 0;
                    for (n = 0; n < count; n++)
                    {
                        szFormat = listBox1.Items[n].ToString();
                    
                        meptr[n].startSentinel = szFormat[0];
                        meptr[n].endSentinel = szFormat[1];
                     //   MessageBox.Show(meptr[n].startSentinel.ToString());
                      //  MessageBox.Show(meptr[n].endSentinel.ToString());
                    }
                  
                    Msr_ParseEnable(bParse, meptr, count);
                }
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            UpdataPortParameters();
        }

        private void button6_Click(object sender, EventArgs e)
        {
           // MessageBox.Show("11");
           // int baud, databits, parity, stopbits;
            string str;
           // MessageBox.Show("22");
            if(comboBox2.SelectedIndex < 0)
            {
                MessageBox.Show("请选择一个波特率!","Warning", buttons, 0, 0);
                return;
            } //MessageBox.Show("33");
           // baud = 15200;
            baud = Convert.ToInt32(comboBox2.Text);
           // MessageBox.Show("44");
            if(comboBox3.SelectedIndex < 0)
            {
                MessageBox.Show("请选择一个数据位!", "Warning", buttons, 0, 0);
                return;
            } //MessageBox.Show("55");
            databits = Convert.ToInt32(comboBox3.Text);

            if (comboBox4.SelectedIndex < 0)
            {
                MessageBox.Show("请选择一个校验位!", "Warning", buttons, 0, 0);
                return;
            } //MessageBox.Show("66");

            if (comboBox4.Text.CompareTo("None") == 0)
            {
                parity = 0;
            }
            else if (comboBox4.Text.CompareTo("Odd") == 0)
            {
                parity = 1;
            }
            else if (comboBox4.Text.CompareTo("Even") == 0)
            {
                parity = 2;
                            
            }
            //parity = parity;
/*= Convert.ToInt32(comboBox4.Text);
            if (comboBox5.SelectedIndex < 0)
            {
                MessageBox.Show("请选择一个停止位!", "Warning", buttons, 0, 0);
                return;
            }*/
            //MessageBox.Show("1");
            stopbits = Convert.ToInt32(comboBox5.Text);
            //MessageBox.Show("2");
            int result = Msr_SetPortParameters(baud, databits, parity, stopbits);
            //MessageBox.Show("3");
            ShowErrMsg(result);
        }
    }
}