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

#include <vcl.h>
#pragma hdrstop

#include "Info.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TInfoForm *InfoForm;
//---------------------------------------------------------------------------
__fastcall TInfoForm::TInfoForm(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

char *BoolToString(bool B)
{
  if(B)
    return("True");
  else
    return("False");
}
//---------------------------------------------------------------------------

void __fastcall TInfoForm::CollectBtnInfo(WORD Val, char *Title, char *TitleBar)
{
  int I;
  int Ret;
  WORD N;
  AnsiString UsagePageText;
  AnsiString UsageText;
  AnsiString LinkUsagePageText;
  AnsiString LinkUsageText;
  AnsiString S;
  // more than enough Caps structures to read
  THIDPButtonCaps BtnCaps[256];

  N = 256;
  Dev->ReportTypeParam = Val;
  Ret = Dev->GetButtonCaps(BtnCaps, N);
  if(Ret == HIDP_STATUS_SUCCESS)
  {
    InfoMemo->Lines->Add("");
    InfoMemo->Lines->Add(Title);
    InfoMemo->Lines->Add(TitleBar);
    for(I = 0; I < N; I++)
    {
      UsageAndUsagePageText(BtnCaps[I].UsagePage,     BtnCaps[I].Usage,     &UsagePageText,     &UsageText);
      UsageAndUsagePageText(BtnCaps[I].LinkUsagePage, BtnCaps[I].LinkUsage, &LinkUsagePageText, &LinkUsageText);
      InfoMemo->Lines->Add("");
      InfoMemo->Lines->Add(S.sprintf("%u)", I));
      InfoMemo->Lines->Add(S.sprintf("UsagePage:         %s (0x%04X)", UsagePageText, BtnCaps[I].UsagePage));
      InfoMemo->Lines->Add(S.sprintf("ReportID:          %u",          BtnCaps[I].ReportID));
      InfoMemo->Lines->Add(S.sprintf("IsAlias:           %s",          BoolToString(BtnCaps[I].IsAlias)));
      InfoMemo->Lines->Add(S.sprintf("BitField:          %u",          BtnCaps[I].BitField));
      InfoMemo->Lines->Add(S.sprintf("LinkCollection:    %u",          BtnCaps[I].LinkCollection));
      InfoMemo->Lines->Add(S.sprintf("LinkUsage:         %s (0x%04X)", LinkUsageText, BtnCaps[I].LinkUsage));
      InfoMemo->Lines->Add(S.sprintf("LinkUsagePage:     %s (0x%04X)", LinkUsagePageText, BtnCaps[I].LinkUsagePage));
      InfoMemo->Lines->Add(S.sprintf("IsRange:           %s",          BoolToString(BtnCaps[I].IsRange)));
      InfoMemo->Lines->Add(S.sprintf("IsStringRange:     %s",          BoolToString(BtnCaps[I].IsStringRange)));
      InfoMemo->Lines->Add(S.sprintf("IsDesignatorRange: %s",          BoolToString(BtnCaps[I].IsDesignatorRange)));
      InfoMemo->Lines->Add(S.sprintf("IsAbsolute:        %s",          BoolToString(BtnCaps[I].IsAbsolute)));
      if(BtnCaps[I].IsRange)
      {
        InfoMemo->Lines->Add(S.sprintf("UsageMin:      %d UsageMax:      %d", BtnCaps[I].UsageMin,      BtnCaps[I].UsageMax));
        InfoMemo->Lines->Add(S.sprintf("StringMin:     %d StringMax:     %d", BtnCaps[I].StringMin,     BtnCaps[I].StringMax));
        InfoMemo->Lines->Add(S.sprintf("DesignatorMin: %d DesignatorMax: %d", BtnCaps[I].DesignatorMin, BtnCaps[I].DesignatorMax));
        InfoMemo->Lines->Add(S.sprintf("DataIndexMin:  %d DataIndexMax:  %d", BtnCaps[I].DataIndexMin,  BtnCaps[I].DataIndexMax));
      }
      else
      {
        InfoMemo->Lines->Add(S.sprintf("Usage:             %s (0x%04X)", UsageText, BtnCaps[I].Usage));
        InfoMemo->Lines->Add(S.sprintf("StringIndex:       %u",          BtnCaps[I].StringIndex));
        InfoMemo->Lines->Add(S.sprintf("DesignatorIndex:   %u",          BtnCaps[I].DesignatorIndex));
        InfoMemo->Lines->Add(S.sprintf("DataIndex:         %u",          BtnCaps[I].DataIndex));
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TInfoForm::CollectValueInfo(WORD Val, char *Title, char *TitleBar)
{
  int I;
  int Ret;
  WORD N;
  AnsiString UsagePageText;
  AnsiString UsageText;
  AnsiString LinkUsagePageText;
  AnsiString LinkUsageText;
  AnsiString S;
  // more than enough Caps structures to read
  THIDPValueCaps ValCaps[256];

  N = 256;
  Dev->ReportTypeParam = Val;
  Ret = Dev->GetValueCaps(ValCaps, N);
  if(Ret == HIDP_STATUS_SUCCESS)
  {
    InfoMemo->Lines->Add("");
    InfoMemo->Lines->Add(Title);
    InfoMemo->Lines->Add(TitleBar);
    for(I = 0; I < N; I++)
    {
      UsageAndUsagePageText(ValCaps[I].UsagePage,     ValCaps[I].Usage,     &UsagePageText,     &UsageText);
      UsageAndUsagePageText(ValCaps[I].LinkUsagePage, ValCaps[I].LinkUsage, &LinkUsagePageText, &LinkUsageText);
      InfoMemo->Lines->Add("");
      InfoMemo->Lines->Add(S.sprintf("%u)", I));
      InfoMemo->Lines->Add(S.sprintf("UsagePage:         %s (0x%04X)", UsagePageText, ValCaps[I].UsagePage));
      InfoMemo->Lines->Add(S.sprintf("ReportID:          %u",          ValCaps[I].ReportID));
      InfoMemo->Lines->Add(S.sprintf("IsAlias:           %s",          BoolToString(ValCaps[I].IsAlias)));
      InfoMemo->Lines->Add(S.sprintf("BitField:          %u",          ValCaps[I].BitField));
      InfoMemo->Lines->Add(S.sprintf("LinkCollection:    %u",          ValCaps[I].LinkCollection));
      InfoMemo->Lines->Add(S.sprintf("LinkUsage:         %s (0x%04X)", LinkUsageText, ValCaps[I].LinkUsage));
      InfoMemo->Lines->Add(S.sprintf("LinkUsagePage:     %s (0x%04X)", LinkUsagePageText, ValCaps[I].LinkUsagePage));
      InfoMemo->Lines->Add(S.sprintf("IsRange:           %s",          BoolToString(ValCaps[I].IsRange)));
      InfoMemo->Lines->Add(S.sprintf("IsStringRange:     %s",          BoolToString(ValCaps[I].IsStringRange)));
      InfoMemo->Lines->Add(S.sprintf("IsDesignatorRange: %s",          BoolToString(ValCaps[I].IsDesignatorRange)));
      InfoMemo->Lines->Add(S.sprintf("IsAbsolute:        %s",          BoolToString(ValCaps[I].IsAbsolute)));
      InfoMemo->Lines->Add(S.sprintf("HasNull:           %s",          BoolToString(ValCaps[I].HasNull)));
      InfoMemo->Lines->Add(S.sprintf("BitSize:           %u",          ValCaps[I].BitSize));
      InfoMemo->Lines->Add(S.sprintf("ReportCount:       %u",          ValCaps[I].ReportCount));
      InfoMemo->Lines->Add(S.sprintf("UnitsExp:          %u",          ValCaps[I].UnitsExp));
      InfoMemo->Lines->Add(S.sprintf("Units:             %u",          ValCaps[I].Units));
      InfoMemo->Lines->Add(S.sprintf("LogicalMin:        %d",          ValCaps[I].LogicalMin));
      InfoMemo->Lines->Add(S.sprintf("LogicalMax:        %d",          ValCaps[I].LogicalMax));
      InfoMemo->Lines->Add(S.sprintf("PhysicalMin:       %d",          ValCaps[I].PhysicalMin));
      InfoMemo->Lines->Add(S.sprintf("PhysicalMax:       %d",          ValCaps[I].PhysicalMax));
      if(ValCaps[I].IsRange)
      {
        InfoMemo->Lines->Add(S.sprintf("UsageMin:      %d UsageMax:      %d", ValCaps[I].UsageMin,      ValCaps[I].UsageMax));
        InfoMemo->Lines->Add(S.sprintf("StringMin:     %d StringMax:     %d", ValCaps[I].StringMin,     ValCaps[I].StringMax));
        InfoMemo->Lines->Add(S.sprintf("DesignatorMin: %d DesignatorMax: %d", ValCaps[I].DesignatorMin, ValCaps[I].DesignatorMax));
        InfoMemo->Lines->Add(S.sprintf("DataIndexMin:  %d DataIndexMax:  %d", ValCaps[I].DataIndexMin,  ValCaps[I].DataIndexMax));
      }
      else
      {
        InfoMemo->Lines->Add(S.sprintf("Usage:             %s (0x%04X)", UsageText, ValCaps[I].Usage));
        InfoMemo->Lines->Add(S.sprintf("StringIndex:       %u",          ValCaps[I].StringIndex));
        InfoMemo->Lines->Add(S.sprintf("DesignatorIndex:   %u",          ValCaps[I].DesignatorIndex));
        InfoMemo->Lines->Add(S.sprintf("DataIndex:         %u",          ValCaps[I].DataIndex));
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TInfoForm::FormShow(TObject *Sender)
{
  AnsiString S;

  InfoMemo->Lines->Clear();
  if(Dev->VendorName != NULL)
    InfoMemo->Lines->Add(S.sprintf("\"%S\" \"%S\" VID=0x%04X PID=0x%04X",
      Dev->VendorName, Dev->ProductName, Dev->Attributes.VendorID, Dev->Attributes.ProductID));
  else
    InfoMemo->Lines->Add(S.sprintf("VID=0x%04X PID=0x%04X",
      Dev->Attributes.VendorID, Dev->Attributes.ProductID));
  if(Dev->SerialNumber != NULL)
    InfoMemo->Lines->Add(S.sprintf("SerialNumber=%s", Dev->SerialNumber));
  if(Dev->Caps.InputReportByteLength > 0)
    InfoMemo->Lines->Add(S.sprintf("Input Report Size=%d", Dev->Caps.InputReportByteLength-1));
  else
    InfoMemo->Lines->Add("Input Report Size=0");
  if(Dev->Caps.OutputReportByteLength > 0)
    InfoMemo->Lines->Add(S.sprintf("Output Report Size=%d", Dev->Caps.OutputReportByteLength-1));
  else
    InfoMemo->Lines->Add("Output Report Size=0");
  if(Dev->Caps.FeatureReportByteLength > 0)
    InfoMemo->Lines->Add(S.sprintf("Feature Report Size=%d", Dev->Caps.FeatureReportByteLength-1));
  else
    InfoMemo->Lines->Add("Feature Report Size=0");
  CollectBtnInfo(HidP_Input,     "Button Input",   "============");
  CollectBtnInfo(HidP_Output,    "Button Output",  "=============");
  CollectBtnInfo(HidP_Feature,   "Button Feature", "==============");
  CollectValueInfo(HidP_Input,   "Value Input",    "===========");
  CollectValueInfo(HidP_Output,  "Value Output",   "============");
  CollectValueInfo(HidP_Feature, "Value Feature",  "=============");
}
//---------------------------------------------------------------------------

void __fastcall TInfoForm::SaveClick(TObject *Sender)
{
  if(SaveDialog->Execute())
    InfoMemo->Lines->SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------

