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

#include <vcl.h>
#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "wclBluetooth"
#pragma resource "*.dfm"

#ifdef _WIN64
#pragma comment(lib, "wclCommon.a")
#pragma comment(lib, "wclCommunication.a")
#pragma comment(lib, "wclBluetoothFrameworkR.a")
#else
#pragma comment(lib, "wclCommon.lib")
#pragma comment(lib, "wclCommunication.lib")
#pragma comment(lib, "wclBluetoothFrameworkR.lib")
#endif

TfmMain *fmMain;
//---------------------------------------------------------------------------
__fastcall TfmMain::TfmMain(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btClearClick(TObject *Sender)
{
  lbEvents->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FormCreate(TObject *Sender)
{
  // In real application you should always analize the result code.
  // In this demo we assume that all is always OK.
  wclBluetoothManager->Open();

  cbAuthentication->Checked = wclRfCommServer->Authentication;
  cbEcnryption->Checked = wclRfCommServer->Encryption;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FormDestroy(TObject *Sender)
{
  wclRfCommServer->Close();
  wclBluetoothManager->Close();
}
//---------------------------------------------------------------------------
TwclBluetoothRadio* __fastcall TfmMain::GetRadio()
{
  TwclBluetoothRadio* Radio;
  int Res = wclBluetoothManager->GetClassicRadio(Radio);
  if (Res != WCL_E_SUCCESS)
  {
    MessageDlg("Get working radio failed: 0x" + IntToHex(Res, 8), mtError,
      TMsgDlgButtons() << mbOK, 0);
    return NULL;
  }
  return Radio;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btListenClick(TObject *Sender)
{
  TwclBluetoothRadio* Radio = GetRadio();
  if (Radio != NULL)
  {
    // Switch radio in discoverable and connectable mode.
    // Ignore any errors. In real application you need to check the result.
    Radio->SetDiscoverable(true);
    Radio->SetConnectable(true);

    wclRfCommServer->Authentication = cbAuthentication->Checked;
    wclRfCommServer->Encryption = cbEcnryption->Checked;

    wclRfCommServer->Service = SerialPortServiceClass_UUID;
    wclRfCommServer->ServiceName = edServiceName->Text;

    int Res = wclRfCommServer->Listen(Radio);
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Error: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btCloseClick(TObject *Sender)
{
  int Res = wclRfCommServer->Close();
  if (Res != WCL_E_SUCCESS)
  {
    MessageDlg("Error: 0x" + IntToHex(Res, 8), mtError,
      TMsgDlgButtons() << mbOK, 0);
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btDisconnectClick(TObject *Sender)
{
  if (lvClients->Selected == NULL)
    MessageDlg("Select client", mtWarning, TMsgDlgButtons() << mbOK, 0);

  else
  {
    int Res = ((TwclRfCommServerClientConnection*)lvClients->Selected->Data)->Disconnect();
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Error: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btSendClick(TObject *Sender)
{
  if (lvClients->Selected == NULL)
    MessageDlg("Select client", mtWarning, TMsgDlgButtons() << mbOK, 0);

  else
  {
    AnsiString Ansi = AnsiString(edText->Text);
    unsigned int Sent = 0;
    int Res = ((TwclRfCommServerClientConnection*)
      lvClients->Selected->Data)->Write(Ansi.c_str(), Ansi.Length(), Sent);
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Error: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
    else
    {
      MessageDlg("Sent: " + IntToStr((int)Sent) + " from " + IntToStr(Ansi.Length()),
        mtInformation, TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btGetBuffersClick(TObject *Sender)
{
  if (lvClients->Selected == NULL)
    MessageDlg("Select client", mtWarning, TMsgDlgButtons() << mbOK, 0);

  else
  {
    TwclRfCommServerClientConnection* Client =
      (TwclRfCommServerClientConnection*)lvClients->Selected->Data;

    // Get read buffer.
    unsigned int Size = 0;
    int Res = Client->GetReadBufferSize(Size);
    if (Res != WCL_E_SUCCESS)
      lbEvents->Items->Add("Get read buffer error: 0x" + IntToHex(Res, 8));
    else
      edReadBuffer->Text = IntToStr((int)Size);

    // Get write buffer.
    Size = 0;
    Res = Client->GetWriteBufferSize(Size);
    if (Res != WCL_E_SUCCESS)
      lbEvents->Items->Add("Get write buffer error: 0x" + IntToHex(Res, 8));
    else
      edWriteBuffer->Text = IntToStr((int)Size);
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btSetBuffersClick(TObject *Sender)
{
  if (lvClients->Selected == NULL)
    MessageDlg("Select client", mtWarning, TMsgDlgButtons() << mbOK, 0);

  else
  {
    TwclRfCommServerClientConnection* Client =
      (TwclRfCommServerClientConnection*)lvClients->Selected->Data;

    // Set read buffer.
    unsigned int Size = StrToInt(edReadBuffer->Text);
    int Res = Client->SetReadBufferSize(Size);
    if (Res != WCL_E_SUCCESS)
      lbEvents->Items->Add("Set read buffer error: 0x" + IntToHex(Res, 8));

    // Set write buffer.
    Size = StrToInt(edWriteBuffer->Text);
    Res = Client->SetWriteBufferSize(Size);
    if (Res != WCL_E_SUCCESS)
      lbEvents->Items->Add("Set write buffer error: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------
String __fastcall TfmMain::GetDeviceName(__int64 Address)
{
  TwclBluetoothRadio* Radio = GetRadio();
  if (Radio != NULL)
  {
    String DevName = "";
    int Res = Radio->GetRemoteName(Address, DevName);
    if (Res == WCL_E_SUCCESS)
      return DevName;

    return "Error: 0x" + IntToHex(Res, 8);
  }

  return "";
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclBluetoothManagerNumericComparison(
      TObject *Sender, const TwclBluetoothRadio *Radio,
      const __int64 Address, const DWORD Number, bool& Confirm)
{
  // Accept any pairing.
  Confirm = true;
  lbEvents->Items->Add("Numeric comparison: " + IntToStr((int)Number));
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclBluetoothManagerPasskeyNotification(
      TObject *Sender, const TwclBluetoothRadio *Radio,
      const __int64 Address, const DWORD Passkey)
{
  lbEvents->Items->Add("Passkey notification: " + IntToStr((int)Passkey));
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclBluetoothManagerPasskeyRequest(TObject *Sender,
      const TwclBluetoothRadio *Radio, const __int64 Address,
      DWORD& Passkey)
{
  // Use 123456 as passkey.
  Passkey = 123456;
  lbEvents->Items->Add("Passkey request: " + IntToStr((int)Passkey));
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclBluetoothManagerPinRequest(TObject *Sender,
      const TwclBluetoothRadio *Radio, const __int64 Address,
      String& Pin)
{
  // Use '0000' as PIN.
  Pin = "0000";
  lbEvents->Items->Add("Pin request: " + Pin);
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclRfCommServerClosed(TObject *Sender,
      const int Reason)
{
  lbEvents->Items->Add("Server closed on radio " +
    ((TwclRfCommServer*)Sender)->Radio->ApiName + " with reason: 0x" +
    IntToHex(Reason, 8));

  lvClients->Clear();

  edReadBuffer->Text = "";
  edWriteBuffer->Text = "";
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclRfCommServerConnect(TObject *Sender,
      const TwclRfCommServerClientConnection *Client, const int Error)
{
  TwclRfCommServerConnection* Server = (TwclRfCommServerConnection*)Client->Server;

  lbEvents->Items->Add("Client connected: " + IntToHex(Client->Address, 12) +
    " on Radio " + Server->Radio->ApiName + " error: 0x" +
    IntToHex(Error, 8));

  TListItem* Item = lvClients->Items->Add();
  Item->Caption = IntToHex(Client->Address, 12);
  Item->SubItems->Add(GetDeviceName(Client->Address));
  Item->Data = (void*)Client;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclRfCommServerData(TObject *Sender,
      const TwclRfCommServerClientConnection *Client, const Pointer Data,
      const DWORD Size)
{
  if (Size > 0)
  {
    AnsiString Str = AnsiString((PAnsiChar)Data, Size);

    TwclRfCommServerConnection* Server =
      (TwclRfCommServerConnection*)Client->Server;
    lbEvents->Items->Add("Received: " + String(Str) + " from " +
      IntToHex(Client->Address, 12) + " on radio " + Server->Radio->ApiName);
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclRfCommServerDisconnect(TObject *Sender,
      const TwclRfCommServerClientConnection *Client, const int Reason)
{
  TwclRfCommServerConnection* Server =
    (TwclRfCommServerConnection*)Client->Server;

  lbEvents->Items->Add("Client disconnected: " + IntToHex(Client->Address, 12) +
    " on radio " + Server->Radio->ApiName + " reason: 0x" +
    IntToHex(Reason, 8));

  for (int i = 0; i < lvClients->Items->Count; i++)
  {
    if ((TwclRfCommServerClientConnection*)lvClients->Items->Item[i]->Data == Client)
    {
      lvClients->Items->Delete(i);
      break;
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclRfCommServerListen(TObject *Sender)
{
  lbEvents->Items->Add("Server listening on radio " +
    ((TwclRfCommServer*)Sender)->Radio->ApiName + " on channel: " +
    IntToStr(((TwclRfCommServer*)Sender)->AssignedChannel));
}
//---------------------------------------------------------------------------
