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

#include <vcl.h>
#pragma hdrstop

#include "LCDMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "JvHidControllerClass"
#pragma resource "*.dfm"
TLCDMainForm *LCDMainForm;
//---------------------------------------------------------------------------
__fastcall TLCDMainForm::TLCDMainForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TLCDMainForm::FormActivate(TObject *Sender)
{
  int I;
  AnsiString S;

  // place the edit controls in an array for easy access
  if (Edits[0] == NULL)
    for(I = 0; I < 7; I++)
      Edits[I] = (TEdit *) FindComponent(S.sprintf("Write%d", I+1));
}
//---------------------------------------------------------------------------

bool __stdcall FindLcdIOWarrior(TJvHidDevice *HidDev)
{
  // the IO-Warrior shows up as two devices
  // we want access to the IO-Warrior device for the LCD module
  // the other one with a InputReportByteLength of 5 is for access to
  // the IO pins
  // It is quite interesting to use the IO-WarriorDemo in parallel!
  return (HidDev->Attributes.VendorID == cCodeMercenariesVID &&
    HidDev->Attributes.ProductID == cIOWarriorPID &&
    HidDev->Caps.InputReportByteLength == 8);
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::HidCtlDeviceChange(TObject *Sender)
{
  // Free the device object if it has been unplugged
  if(IOWarrior != NULL && !IOWarrior->IsPluggedIn)
  {
    FreeAndNil(&IOWarrior);
    // throw away the log (better save it before unplugging)
    HistoryListBox->Items->Clear();
    EnableChk->Checked = false;
    EnableChk->Enabled = false;
  }

  // if no IO-Warrior in use yet then search for one
  if(IOWarrior == NULL)
    if(HidCtl->CheckOutByCallback(IOWarrior, FindLcdIOWarrior))
    {
      EnableChk->Enabled = true;
      EnableChk->Checked = true;
    }
  // an alternative to "if Assigned(IOWarrior) then"
  if(HidCtl->CountByID(cCodeMercenariesVID, cIOWarriorPID) > 0)
    IOWarriorAvailable->Caption = "IO-Warrior found";
  else
    IOWarriorAvailable->Caption = "No IO-Warrior found";
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::EnableChkClick(TObject *Sender)
{
  int I;
  unsigned int BytesWritten;
  TIOWarriorOutputReport IOWarriorOutputReport;

  if(IOWarrior != NULL)
  {
    // initialize the output report to enable/disable the LCD module
    IOWarriorOutputReport.ReportID = cLCDEnableReportID;
    for(I = 0; I < 7; I++)
      IOWarriorOutputReport.LCDBytes[I] = 0x00;
    if(EnableChk->Checked)
      IOWarriorOutputReport.LCDBytes[0] = cEnable;
    else
      IOWarriorOutputReport.LCDBytes[0] = cDisable;
    // write the bits to the IO-Warrior to enable/disable the LCD
    IOWarrior->WriteFile(&IOWarriorOutputReport, sizeof(IOWarriorOutputReport), BytesWritten);
    WriteBtn->Enabled = EnableChk->Checked;
    ReadBtn->Enabled  = EnableChk->Checked;
  }
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::WriteBtnClick(TObject *Sender)
{
  unsigned int I;
  unsigned int BytesWritten;
  TIOWarriorOutputReport IOWarriorOutputReport;
  AnsiString S;
  AnsiString Str;

  IOWarriorOutputReport.ReportID = cLCDWriteReportID;
  // get the input from the user
  for(I = 0; I < 7; I++)
  {
    IOWarriorOutputReport.LCDBytes[I] = StrToIntDef("$" + Edits[I]->Text, 0);
    Edits[I]->Text.sprintf("%02X", IOWarriorOutputReport.LCDBytes[I]);
  }
  // reset unused bits in first byte
  IOWarriorOutputReport.LCDBytes[0] &= 0x07;
  // add the RS bit from the checkbox
  if(RSBit->Checked)
    IOWarriorOutputReport.LCDBytes[0] |= 0x80;
  IOWarrior->WriteFile(&IOWarriorOutputReport, 8, BytesWritten);

  // show the data in the history listbox
  Str.sprintf("W %02X  ", IOWarriorOutputReport.ReportID);
  for(I = 0; I < BytesWritten; I++)
    Str += S.sprintf("%02X ", IOWarriorOutputReport.LCDBytes[I-1]);
  HistoryListBox->ItemIndex = HistoryListBox->Items->Add(Str);
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::ReadBtnClick(TObject *Sender)
{
  unsigned int I;
  unsigned int BytesWritten;
  TIOWarriorOutputReport IOWarriorOutputReport;
  AnsiString S;
  AnsiString Str;

  IOWarriorOutputReport.ReportID = cLCDReadReportID;
  for(I = 0; I < 7; I++)
    IOWarriorOutputReport.LCDBytes[I] = 0x00;
  // get number of bytes to read, ensure the max of 63 and reset unused bits
  IOWarriorOutputReport.LCDBytes[0] = StrToIntDef("$" + Read1->Text, 0) & 0x3F;
  // add the RS bit from the checkbox
  if(RSBit->Checked)
    IOWarriorOutputReport.LCDBytes[0] |= 0x80;
  IOWarrior->WriteFile(&IOWarriorOutputReport, 8, BytesWritten);

  // show the data in the history listbox
  Str.sprintf("W %02X  ", IOWarriorOutputReport.ReportID);
  for(I = 0; I < BytesWritten; I++)
    Str += S.sprintf("%02X ", IOWarriorOutputReport.LCDBytes[I-1]);
  HistoryListBox->ItemIndex = HistoryListBox->Items->Add(Str);
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::SaveBtnClick(TObject *Sender)
{
  if(SaveDialog->Execute())
    HistoryListBox->Items->SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------

void __fastcall TLCDMainForm::HidCtlDeviceData(TJvHidDevice *HidDev,
      BYTE ReportID, const Pointer Data, WORD Size)
{
  WORD I;
  AnsiString Str;
  AnsiString S;
  char *P;

  P = (char *) Data;
  // show all bytes of the report in hex
  Str.sprintf("R %02X  ", ReportID);
  for(I = 0; I < Size; I++)
    Str += S.sprintf("%02X ", (unsigned char) P[I]);
  Str += Str + "  \"";
  // only show the net content as letters
  for (I = 1; I < P[0] & 0x07; I++)
    if((unsigned char) P[I] >= ' ')
      Str += P[I];
    else
      Str += '.';
  Str += "\"";
  HistoryListBox->ItemIndex = HistoryListBox->Items->Add(Str);
}
//---------------------------------------------------------------------------

