//---------------------------------------------------------------------------

#include <vcl.h>
#include "EasyPODDLL.H"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
MW_EasyPOD mEasyPOD;
int gTypeIn = 0;
char szApplication[] = "Megawin Easy USB (v1.2)";
HANDLE m_hCOMDevice = NULL;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    int i;
    AnsiString strTmp;

    for (i=1 ; i<17; i++)
    {
        strTmp.printf("COM%d",i);
        cboCOMPort->AddItem(strTmp,NULL) ;
    }
    cboCOMPort->ItemIndex = 0;

    cboBaudRate->AddItem("1200",NULL);
    cboBaudRate->AddItem("2400",NULL);
    cboBaudRate->AddItem("4800",NULL);
    cboBaudRate->AddItem("9600",NULL);
    cboBaudRate->AddItem("14400",NULL);
    cboBaudRate->AddItem("19200",NULL);
    cboBaudRate->AddItem("28800",NULL);
    cboBaudRate->AddItem("38400",NULL);
    cboBaudRate->AddItem("57600",NULL);
    cboBaudRate->AddItem("115200",NULL);
    cboBaudRate->ItemIndex = 0;

    cboDevice->AddItem("EasyPOD",NULL);
    cboDevice->AddItem("EasyCOM",NULL);
    cboBaudRate->Visible = FALSE;
    cboCOMPort->Visible = FALSE;
    GroupBox4->Visible = FALSE;


    cboDevice->ItemIndex = 0;
    edtVID->Text = "0E6A";
    edtPID->Text = "0317";
    edtIndex->Text = "1";
    btnWriteBytes->Enabled = FALSE;
    btnReadBytes->Enabled = FALSE;
    rdoHex->Checked = TRUE;
    gTypeIn = 0;

}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnConnectClick(TObject *Sender)
{
    DWORD dwResult;
    AnsiString strTmp;
    DWORD COMRxBufferSize;
    DWORD COMTxBufferSize;
    DCB dcb;
    BOOL bResult;
    if (cboDevice->ItemIndex == 0)
    {
        if ((edtVID->Text == "") || (edtPID->Text == "") || (edtIndex->Text == ""))
        {
            MessageBox(NULL,"VID and PID and Index must have value !" ,szApplication, MB_OK);
            return;
        }
        strTmp.cat_printf("0x%s",edtVID->Text);
        mEasyPOD.VID = StrToInt64(strTmp);
        strTmp = "";
        strTmp.cat_printf("0x%s",edtPID->Text);
        mEasyPOD.PID = StrToInt64(strTmp);
        dwResult = ConnectPOD(&mEasyPOD, edtIndex->Text.ToInt());
        if (dwResult == ERROR_SUCCESS)
        {
            edtStatus->Text = "Connect !";
            btnWriteBytes->Enabled = TRUE;
            btnReadBytes->Enabled = TRUE;
        }
        else
            edtStatus->Text = "Fail Connect Megawin EasyPOD";
    }
    else
    {
        edtStatus->Text = "Fail Connect Megawin EasyCOM";
        if (m_hCOMDevice != NULL)
        {
            //CloseCOMPort();
            btnDisconnectClick(Sender);
            return;
        }
        strTmp = cboCOMPort->Text;
        if ((m_hCOMDevice = CreateFile( strTmp.c_str(), GENERIC_READ | GENERIC_WRITE,   // open COMM device
                                        0,                                      // exclusive access
                                        NULL,                                   // no security attrs
                                        OPEN_EXISTING,
                                        FILE_ATTRIBUTE_NORMAL ,
                                        //NULL,					        	    // no overlapped I/O
                                        NULL )) == (HANDLE) -1 )
	{
            MessageBox(NULL, "Open EasyCOM fail !", szApplication, MB_OK);
	    return;
        }
 	COMRxBufferSize = 4096;
	COMTxBufferSize = 4096;
        bResult = SetupComm(m_hCOMDevice , COMRxBufferSize, COMTxBufferSize );  // setup device buffers
        if (bResult == 0)
	{
            MessageBox(NULL, "SetupComm fail !", szApplication, MB_OK);
	    CloseHandle(m_hCOMDevice);
	    m_hCOMDevice = NULL;
	    return;
	}
        // purge any information in the buffer
        bResult = PurgeComm(m_hCOMDevice, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
        if (bResult == 0)
	{
	    MessageBox(NULL, "PurgeComm fail !", szApplication, MB_OK);
	    CloseHandle(m_hCOMDevice);
	    m_hCOMDevice = NULL;
            return;
	}

        dcb.DCBlength = sizeof( DCB );
        bResult = GetCommState(m_hCOMDevice, &dcb ) ;
        if (bResult == 0)
      	{
            MessageBox(NULL, "GetCommState fail !", szApplication, MB_OK);
	    CloseHandle(m_hCOMDevice);
	    m_hCOMDevice = NULL;
            return;
	}
	switch (cboBaudRate->ItemIndex)
	{
	case 0: dcb.BaudRate = CBR_1200;    break;
        case 1: dcb.BaudRate = CBR_2400;    break;
	case 2: dcb.BaudRate = CBR_4800;    break;
        case 3: dcb.BaudRate = CBR_9600;    break;
	case 4: dcb.BaudRate = CBR_14400;    break;
        case 5: dcb.BaudRate = CBR_19200;    break;
	case 6: dcb.BaudRate = CBR_38400;    break;
        case 7: dcb.BaudRate = CBR_56000;    break;
	case 8: dcb.BaudRate = CBR_57600;    break;
        case 9: dcb.BaudRate = CBR_115200;    break;
        }

        dcb.ByteSize = 8;
        dcb.Parity = NOPARITY;
        dcb.fParity  = 0;
        dcb.StopBits = ONESTOPBIT;
        dcb.fBinary  = TRUE ;

	bResult = SetCommState(m_hCOMDevice, &dcb );		// set COM with dcb
        if (bResult == 0)
	{
            MessageBox(NULL, "SetCommState fail !", szApplication, MB_OK);
	    CloseHandle(m_hCOMDevice);
	    m_hCOMDevice = INVALID_HANDLE_VALUE;
            return;
	}

        edtStatus->Text = "Connect !";
        btnWriteBytes->Enabled = TRUE;
        btnReadBytes->Enabled = TRUE;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDisconnectClick(TObject *Sender)
{
    DWORD dwResult;
    if (cboDevice->ItemIndex == 0)
    {
        dwResult = DisconnectPOD(&mEasyPOD);
        if (dwResult == ERROR_SUCCESS)
        {
            edtStatus->Text = "Disconnect";
            btnWriteBytes->Enabled = FALSE;
            btnReadBytes->Enabled = FALSE;
            mmoWriteBuffer->Text = "";
            mmoReadBuffer->Text = "";
        }
    }
    else
    {
        PurgeComm(m_hCOMDevice, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
	CloseHandle(m_hCOMDevice);
	m_hCOMDevice = NULL;

        edtStatus->Text = "Disconnect";
        btnWriteBytes->Enabled = FALSE;
        btnReadBytes->Enabled = FALSE;
        mmoWriteBuffer->Text = "";
        mmoReadBuffer->Text = "";
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnExitClick(TObject *Sender)
{
    Application->Terminate();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnReadBytesClick(TObject *Sender)
{
    DWORD dwResult;
    DWORD dwPacketSize;
    DWORD dwRxTotalSize;
    DWORD dwByteToRead;
    DWORD dwByteRead;
    char* pRxBuffer = NULL;
    char* pPacketBuffer = NULL;
    COMSTAT comstat;
    DWORD dwErrorFlags;

    mmoReadBuffer->Clear();
    if (cboDevice->ItemIndex == 0)
    {
        mEasyPOD.ReadTimeOut = 500;
        dwPacketSize = mEasyPOD.InputReportSize;
        dwByteToRead = dwPacketSize;
        dwRxTotalSize = 0;
        pPacketBuffer = new char[dwPacketSize];
        pRxBuffer = new char[0x10000];
        do
        {
            dwResult = ReadData(&mEasyPOD, pPacketBuffer, dwByteToRead, &dwByteRead);
            if ((dwResult == ERROR_SUCCESS) || ((dwResult == 0xE0000008) && (dwByteRead > 0)))
            {
                memcpy(pRxBuffer+dwRxTotalSize, pPacketBuffer, dwByteRead);
                dwRxTotalSize = dwRxTotalSize + dwByteRead;
                if (dwRxTotalSize + dwPacketSize > 0x10000)
                    realloc(pRxBuffer, sizeof(pRxBuffer) + 0x10000);
            }
        } while (dwResult == ERROR_SUCCESS);
        if ((pRxBuffer != NULL) && (dwRxTotalSize > 0))
        {
            if (rdoString->Checked == TRUE)
                ShowRxDataString(pRxBuffer,dwRxTotalSize);
            else
                ShowRxDataHex(pRxBuffer,dwRxTotalSize);

            edtStatus->Text = edtStatus->Text.sprintf("Read return size is : %d", dwRxTotalSize);
        }
        else
        {
            edtStatus->Text = "Read return size is : 0";
        }
    }
    else
    {
        ClearCommError(m_hCOMDevice, &dwErrorFlags, &comstat);
        if (comstat.cbInQue > 0)
        {
            pRxBuffer = new char[0x10000];
            if (pRxBuffer != NULL)
            {
                dwResult = ReadFile( m_hCOMDevice ,
	  	                     pRxBuffer ,
			             comstat.cbInQue,
			             &dwByteRead ,                   // can be NULL or &numBytesReturned
			             NULL
			            );
                if (dwResult != 0)
                {
                    if (rdoString->Checked == TRUE)
                        ShowRxDataString(pRxBuffer,dwByteRead);
                    else
                        ShowRxDataHex(pRxBuffer,dwByteRead);

                    edtStatus->Text = edtStatus->Text.sprintf("Read return size is : %d", dwByteRead);
                }
                else
                    edtStatus->Text = "Read EasyCOM fail !";
            }
        }
    }
    if (pPacketBuffer != NULL)
        delete []pPacketBuffer;
    if (pRxBuffer != NULL)
        delete []pRxBuffer;

}

//---------------------------------------------------------------------------



void TForm1::ShowRxDataString(char* pBuffer, DWORD dwSize)
{
    //TODO: Add your source code here
    DWORD i;
    AnsiString strOutput;
    strOutput = "";
    for(i=0;i<dwSize;i++)
       strOutput.cat_printf("%c",*(pBuffer+i));
    mmoReadBuffer->Text = strOutput;
}

//---------------------------------------------------------------------------

void TForm1::ShowRxDataHex(char* pBuffer, DWORD dwSize)
{
    //TODO: Add your source code here
    DWORD i;
    AnsiString strOutput;
    strOutput = "";
    for(i=0;i<dwSize;i++)
       strOutput.cat_printf("%02X ",(BYTE)*(pBuffer+i));
    mmoReadBuffer->Text = strOutput.c_str();
    //mmoReadBuffer->Text = strOutput;
}
void __fastcall TForm1::btnWriteBytesClick(TObject *Sender)
{
    DWORD dwBufferLength = 0;
    DWORD dwByteWritten = 0;
    DWORD dwTxSize = 0;
    DWORD dwResult = ERROR_SUCCESS;
    DWORD i;
    char * pTxBuffer = NULL;
 
    dwBufferLength = mmoWriteBuffer->Text.Length() ;
    if (dwBufferLength == 0)
        return;
    if (cboDevice->ItemIndex == 0)
    {
        if (rdoString->Checked == TRUE)
        {
             pTxBuffer = new char[dwBufferLength];
             if (pTxBuffer != NULL)
             {
                 memcpy(pTxBuffer, mmoWriteBuffer->Text.c_str(),dwBufferLength);
                 dwResult = WriteData(&mEasyPOD, pTxBuffer, dwBufferLength, &dwByteWritten);
                 if (dwResult != ERROR_SUCCESS)
                     edtStatus->Text = edtStatus->Text.sprintf("Write Error, Error Code = %d", dwResult);
                 else
                     edtStatus->Text = edtStatus->Text.sprintf("Write return size is : %d", dwByteWritten);
             }
        }
        else
        {
            char* tmpBuf = new char[ dwBufferLength + 1 ];
            dwTxSize = dwBufferLength / 3 + 1;
            pTxBuffer = new char[dwTxSize];
            char buf[30];
            if (pTxBuffer != NULL)
            {
                strcpy( tmpBuf, mmoWriteBuffer->Text.c_str() );
                for(i=0 ; i<dwTxSize ; i++)
                {
                    pTxBuffer[i] = HexStringToHex(tmpBuf+i*3);
                }
                dwResult = WriteData(&mEasyPOD, pTxBuffer, dwTxSize, &dwByteWritten);
                if (dwResult != ERROR_SUCCESS)
                    edtStatus->Text = edtStatus->Text.sprintf("Write Error, Error Code = %d", dwResult);
                else
                    edtStatus->Text = edtStatus->Text.sprintf("Write return size is : %d", dwByteWritten);
            }
        }
    }
    else
    {
        if (rdoString->Checked == TRUE)
        {
             pTxBuffer = new char[dwBufferLength];
             if (pTxBuffer != NULL)
             {
                 memcpy(pTxBuffer, mmoWriteBuffer->Text.c_str(),dwBufferLength);
                 //dwResult = WriteData(&mEasyPOD, pTxBuffer, dwBufferLength, &dwByteToWrite);
                 dwResult = WriteFile( m_hCOMDevice ,
	   			       pTxBuffer ,
                                       dwBufferLength ,
                                       &dwByteWritten ,     // Why always return "0" ??
                                       NULL
                                      );

                 if (dwResult == 0)
                     edtStatus->Text = edtStatus->Text.sprintf("Write Error, Error Code = %d", dwResult);
                 else
                     edtStatus->Text = edtStatus->Text.sprintf("Write return size is : %d", dwByteWritten);
             }
        }
        else
        {
            char* tmpBuf = new char[ dwBufferLength + 1 ];
            dwTxSize = dwBufferLength / 3 + 1;
            pTxBuffer = new char[dwTxSize];
            char buf[30];
            if (pTxBuffer != NULL)
            {
                strcpy( tmpBuf, mmoWriteBuffer->Text.c_str() );
                for(i=0 ; i<dwTxSize ; i++)
                {
                    pTxBuffer[i] = HexStringToHex(tmpBuf+i*3);
                }
                //dwResult = WriteData(&mEasyPOD, pTxBuffer, dwTxSize, &dwByteToWrite);
                dwResult = WriteFile( m_hCOMDevice ,
	   	 	              pTxBuffer ,
                                      dwTxSize ,
                                      &dwByteWritten ,     // Why always return "0" ??
                                      NULL
                                     );
                if (dwResult == 0)
                    edtStatus->Text = edtStatus->Text.sprintf("Write Error, Error Code = %d", dwResult);
                else
                    edtStatus->Text = edtStatus->Text.sprintf("Write return size is : %d", dwByteWritten);
            }
        }
    }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::mmoWriteBufferKeyPress(TObject *Sender, char &Key)
{
    DWORD dwLength;
    DWORD dwIndex;

    if (rdoHex->Checked == TRUE)
    {
        dwLength = mmoWriteBuffer->Text.Length();
        if (Key == 8)
        {
            dwIndex = dwLength / 3;
            mmoWriteBuffer->SelStart = dwIndex * 3;
            mmoWriteBuffer->SelLength = (dwLength - dwIndex * 3);
            mmoWriteBuffer->SelText = "";
            gTypeIn = 0;
        }
        else if ( ((Key>=48) && (Key <=57)) || ((Key>=65) && (Key <=70)) || ((Key>=97) && (Key <=102)))
        {
            if ((Key>=97) && (Key <=102))
                Key = Key - 32;
            dwIndex = dwLength % 3;
            switch (dwIndex)
            {
            case 0:
                 mmoWriteBuffer->Text = mmoWriteBuffer->Text.cat_sprintf("0");
                 mmoWriteBuffer->SelStart = dwLength + 1;
                 gTypeIn = 1;
                 break;
            case 1:
                 MessageBox(NULL, "Error 1",szApplication,MB_OK);
                 break;
            case 2:
                 if (gTypeIn == 1)
                 {
                     mmoWriteBuffer->SelStart = dwLength - 2;
                     mmoWriteBuffer->SelLength = 1;
                     mmoWriteBuffer->SelText = "";
                     mmoWriteBuffer->SelStart = dwLength - 1;
                     gTypeIn = 0;
                 }
                 else
                 {
                     mmoWriteBuffer->Text = mmoWriteBuffer->Text.cat_sprintf(" 0");
                     mmoWriteBuffer->SelStart = dwLength + 2;
                     gTypeIn = 1;
                 }
                 break;
            }
        }
        else
            Key = 0;

    }
}
//---------------------------------------------------------------------------


unsigned char TForm1::HexStringToHex(char * pBuffer)
{
        //TODO: Add your source code here
    unsigned char bytResult = 0;

    if ((*pBuffer >= 48) && (*pBuffer <=57))
        bytResult = (*pBuffer - 48) * 16;
    else if ((*pBuffer >= 65) && (*pBuffer <=70))
        bytResult = (*pBuffer - 55) * 16;

    if ((*(pBuffer+1) >= 48) && (*(pBuffer+1) <=57))
        bytResult = bytResult + (*(pBuffer+1) - 48) ;
    else if ((*(pBuffer+1) >= 65) && (*(pBuffer+1) <=70))
        bytResult = bytResult + (*(pBuffer+1) - 55) ;

    return bytResult;
}
void __fastcall TForm1::cboDeviceClick(TObject *Sender)
{
    if (cboDevice->ItemIndex == 0)
    {
        cboCOMPort->Visible = FALSE;
        cboBaudRate->Visible = FALSE;
        GroupBox4->Visible = FALSE;
        lblPID->Visible = TRUE;
        lblPID->Visible = TRUE;
        lblIndex->Visible = TRUE;
        edtPID->Visible = TRUE;
        edtVID->Visible = TRUE;
        edtIndex->Visible = TRUE;
        GroupBox3->Visible = TRUE;
    }
    else
    {
        cboCOMPort->Visible = TRUE;
        cboBaudRate->Visible = TRUE;
        GroupBox4->Visible = TRUE;
        lblPID->Visible = FALSE;
        lblPID->Visible = FALSE;
        lblIndex->Visible = FALSE;
        edtPID->Visible = FALSE;
        edtVID->Visible = FALSE;
        edtIndex->Visible = FALSE;
        GroupBox3->Visible = FALSE;
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::rdoHexClick(TObject *Sender)
{
    mmoWriteBuffer->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::rdoStringClick(TObject *Sender)
{
    mmoWriteBuffer->Clear();   
}
//---------------------------------------------------------------------------

