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


namespace MifareOneSample
{
    public partial class FrmMifareOne : Form
    {
        public const int MAX_RF_BUFFER = 1024;
        private ushort icdev;
        byte mode = 0x60;
        byte secnr = 0x00;
        int state;
        byte[] strKey = new byte[6];
        byte[] pData = new byte[MAX_RF_BUFFER];
        byte cLen = 0;

        public FrmMifareOne()
        {
            InitializeComponent();
        }

        //***************Find Card*******************
        private void btnSelectCard_Click(object sender, EventArgs e)
        {
	        byte mode = 0x52;
            int status;
            int i = 0;
	        ushort TagType=0;
            byte bcnt = 0x04;////mifare card use 4
            
            byte[] Snr = new byte[MAX_RF_BUFFER];
            byte len = 0x00;
            byte Size = 0x00;

            i = masterRD.rf_beep(icdev, 0x10);
            i = masterRD.rf_init_type(icdev, 'A');
            status = masterRD.rf_request(icdev, mode, ref TagType);// request all of cards on ana
            if (status != 0)
            {//err
                txtCode.Text = "";
                return;
            }

            status = masterRD.rf_anticoll(icdev, bcnt, Snr, ref len);//get card serialno.
            if (status != 0 || len != 4)
            { //err
                txtCode.Text = "";
                return;
            }
            status = masterRD.rf_select(icdev, Snr, len, ref Size);//select a ISO14443-3 TYPE_A card
            if (status != 0)
            {//err
                txtCode.Text = "";
                return;
            }

            txtCode.Text = HexEdit.SetWindowTextEx(Snr, len);	
        }

        private void FrmMifareOne_Load(object sender, EventArgs e)
        {
            OpenPort("COM1", 19200);
        }

        private void OpenPort(string port,int baud)
        {
            ushort Port = 0;
            string szAttr = "type=com;baud=n:" + baud.ToString() + ";";
            switch (port)
            {
                case "COM1": Port = 1;
                    break;
                case "COM2": Port = 2;
                    break;
                case "COM3": Port = 3;
                    break;
                case "COM4": Port = 4;
                    break;
                case "COM5": Port = 5;
                    break;
                case "COM6": Port = 6;
                    break;
                case "COM7": Port = 7;
                    break;
                case "COM8": Port = 8;
                    break;
                case "TCP200": szAttr = "type=tcp;ipaddr=192.168.80.200;tcpport=n:9001;";
                    break;
                case "TCP201:12": szAttr = "type=tcp;ipaddr=192.168.80.201;tcpport=n:12;";
                    break;
                case "TCP202": szAttr = "type=tcp;ipaddr=192.168.80.202;tcpport=n:9001;";
                    break;
            }
            try
            {
                szAttr = "type=com;comport=n:" + Port.ToString() + ";" + baud.ToString() + ";";
                int state = masterRD.rf_init_com(Port, szAttr);
                if (state > 0)
                {
                    icdev = (ushort)state; //save reader identityNo
                }

                if (state < 0)
                {
                    masterRD.rf_ClosePort(icdev);
                    MessageBox.Show("cann't open reader!", "Error");
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }
       //******************Read Card*******************
        private void btnRead_Click(object sender, EventArgs e)
        {
            //
            if (!VerifyKey())
                return;
            //read Mifare One card a block data.
            state = masterRD.rf_M1_read(icdev, secnr, pData, ref cLen);
            if(state==-1 || cLen != 16){
                MessageBox.Show("M1_read Error","Error");
                txtData.Text = ""; 
                return;	
            }
            txtData.Text = HexEdit.SetWindowTextEx(pData, cLen);
        }
        private bool VerifyKey()
        {

            masterRD.rf_beep(icdev, 0x10);
            if (rdobtnA.Checked)
            {//KeyA
                mode = 0x60;
            }
            else
            {//KeyB
                mode = 0x61;
            }
//            string str = "";
            //m_edit_key.GetWindowTextEx(strKey);
            if (txtKey.Text.Length != 12)
            {
                MessageBox.Show("please type 16 bytes key in keyarea");
                return false;
            }

            //selected blockNo.
            //int nSel = Convert.ToInt32(cbxBlock.SelectedText);
            secnr = Convert.ToByte(cbxBlock.Text);

            //auth sector use key.
            strKey = HexEdit.HexToBytes(txtKey.Text);
            state = masterRD.rf_M1_authentication2(icdev, mode, (byte)((secnr / 4) * 4), strKey);
            if (state != 0)
            {
                MessageBox.Show("M1_authentication2 Error", "Error");
                txtKey.Text = "";
                return false;
            }
            return true;
        }
        //******************Write Card*******************
        private void btnWrite_Click(object sender, EventArgs e)
        {

            //
            if (!VerifyKey())
                return;
            //data for write
            byte[] data = new byte[txtData.Text.Length];
            data = HexEdit.HexToBytes(txtData.Text);
            //write data 
            state = masterRD.rf_M1_write(icdev, secnr, data);
            if(state!=0){
                MessageBox.Show("M1_write","Error");
                return;	
            }
        }
        //******************Halt*******************
        private void btnHalt_Click(object sender, EventArgs e)
        {
            state = masterRD.rf_halt(icdev);
            if (state!=0)
            {
                MessageBox.Show("rf_halt Error", "Error");
            }	
        }

        private void cbxSerialPort_SelectedIndexChanged(object sender, EventArgs e)
        {
            OpenPort(cbxSerialPort.Text,Convert.ToInt32(cbxRate.Text));
        }

        private void cbxRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            OpenPort(cbxSerialPort.Text, Convert.ToInt32(cbxRate.Text));
        }

    }
    

}