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

#include <vcl.h>
#pragma hdrstop

#include "main.h"
#include "wclUUIDs.hpp"
//---------------------------------------------------------------------------
#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::FormCreate(TObject *Sender)
{
  // We use ObjectPush Profile so must set the profile's UUID.
  wclRfCommClient->Service = OBEXObjectPushServiceClass_UUID;

  FOpp = NULL;

  // Try to open Bluetooth Manager.
  int Res = wclBluetoothManager->Open();
  if (Res != WCL_E_SUCCESS)
    lbLog->Items->Add("Bluetooth Manager Open failed: 0x" + IntToHex(Res, 8));
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btClearClick(TObject *Sender)
{
  lbLog->Clear();        
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::FormDestroy(TObject *Sender)
{
  wclRfCommClient->Disconnect();
  wclBluetoothManager->Close();
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerAfterOpen(TObject *Sender)
{
  lbLog->Items->Add("Bluetooth Manager has been opened");        
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerAuthenticationCompleted(
      TObject *Sender, const TwclBluetoothRadio *Radio,
      const __int64 Address, const int Error)
{
  lbLog->Items->Add("Authentication completed with result: 0x" +
    IntToHex(Error, 8));
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerDiscoveringCompleted(
      TObject *Sender, const TwclBluetoothRadio *Radio, const int Error)
{
  lbLog->Items->Add("Discovering completed with result: 0x" +
    IntToHex(Error, 8));

  for (int i = 0; i < lvDevices->Items->Count; i++)
  {
    TListItem* Item = lvDevices->Items->Item[i];
    __int64 Addr = StrToInt64("$" + Item->Caption);
    String Name;
    int Res = ((TwclBluetoothRadio*)Radio)->GetRemoteName(Addr, Name);
    if (Res != WCL_E_SUCCESS)
      Name = "Error: 0x" + IntToHex(Res, 8);
    Item->SubItems->Strings[0] = Name;
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerDiscoveringStarted(
      TObject *Sender, const TwclBluetoothRadio *Radio)
{
  lbLog->Items->Add("Discovering started");

  lvDevices->Items->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerNumericComparison(
      TObject *Sender, const TwclBluetoothRadio *Radio,
      const __int64 Address, const DWORD Number, bool& Confirm)
{
  lbLog->Items->Add("Numeric comparison. Accept");
  Confirm = true;
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerPasskeyNotification(
      TObject *Sender, const TwclBluetoothRadio *Radio,
      const __int64 Address, const DWORD Passkey)
{
  lbLog->Items->Add("Passkey notification. Passkey: " + IntToStr((int)Passkey));
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerPasskeyRequest(TObject *Sender,
      const TwclBluetoothRadio *Radio, const __int64 Address,
      DWORD& Passkey)
{
  lbLog->Items->Add("Passkey request. Passkey: 12345678");        
  Passkey = 12345678;
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerPinRequest(TObject *Sender,
      const TwclBluetoothRadio *Radio, const __int64 Address,
      String& Pin)
{
  lbLog->Items->Add("PIN code request. PIN: 0000");
  Pin = "0000";
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclBluetoothManagerDeviceFound(TObject *Sender,
      const TwclBluetoothRadio *Radio, const __int64 Address)
{
  TListItem* Item = lvDevices->Items->Add();
  Item->Caption = IntToHex(Address, 12);
  Item->SubItems->Add("");
}
//---------------------------------------------------------------------------

TwclBluetoothRadio* 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::btDiscoverClick(TObject *Sender)
{
  TwclBluetoothRadio* Radio = GetRadio();
  if (Radio != NULL)
  {
    // Discover classic devices only.
    int Res = Radio->Discover(10, dkClassic);
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Failed to start discovering: 0x" + IntToHex(Res, 8),
        mtError, TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btDisconnectClick(TObject *Sender)
{
  int Res = wclRfCommClient->Disconnect();
  if (Res != WCL_E_SUCCESS)
  {
    MessageDlg("Disconnect failed: 0x" + IntToHex(Res, 8), mtError,
      TMsgDlgButtons() << mbOK, 0);
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclRfCommClientDisconnect(TObject *Sender,
      const int Reason)
{
  lbLog->Items->Add("Disconnected with reason: 0x" + IntToHex(Reason, 8));
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclRfCommClientConnect(TObject *Sender,
      const int Error)
{
  lbLog->Items->Add("Connect. Operation result: 0x" + IntToHex(Error, 8));
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclRfCommClientDestroyProcessor(TObject *Sender,
      const TwclClientDataConnection *Connection)
{
  // Do we have any data processor created?
  if (FOpp != NULL)
  {
    // Make sure it is our connection is goind to destroy.
    if (Connection->Processor == FOpp)
    {
      // Ok, destroy the data processor here.
      FOpp->Free();
      FOpp = NULL;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclRfCommClientCreateProcessor(TObject *Sender,
      const TwclClientDataConnection *Connection)
{
  // here we must create the data processor for the connection. In this demo
  // we use OPPClient.
  #if __BORLANDC__ >= 0x0650
	FOpp = new TwclObexOppClient((TwclClientDataConnection*)Connection);
  #else
	FOpp = new TwclObexOppClient(Connection);
  #endif

  FOpp->OnConnect = OppConnect;
  FOpp->OnDisconnect = OppDisconnect;
  #if __BORLANDC__ >= 0x0650
	#if __BORLANDC__ >= 0x0740
	  FOpp->OnGetComplete = OppGetComplete;
	  FOpp->OnPutComplete = OppPutComplete;
	#else
	  FOpp->OnGetComplete = (TwclObexObjectOperationResultEvent)&OppGetComplete;
	  FOpp->OnPutComplete = (TwclObexObjectOperationResultEvent)&OppPutComplete;
	#endif
  #else
	FOpp->OnGetComplete = OppGetComplete;
    FOpp->OnPutComplete = OppPutComplete;
  #endif
  FOpp->OnProgress = OppProgress;
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btCloseSessionClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    int Res = FOpp->Disconnect("");
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Close session failed: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btOpenSessionClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    int Res = FOpp->Connect();
    if (Res != WCL_E_SUCCESS)
    {
	  MessageDlg("Open session failed: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::OppConnect(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("OBEX session opened with result: 0x" + IntToHex(Error, 8) +
    ". Description: " + Description);
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::OppDisconnect(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("OBEX session closed with result: 0x" + IntToHex(Error, 8) +
    ". Description: " + Description);
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btConnectClick(TObject *Sender)
{
  if (wclRfCommClient->State != csDisconnected)
    MessageDlg("Client is connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    if (lvDevices->Selected == NULL)
      MessageDlg("Select device", mtWarning, TMsgDlgButtons() << mbOK, 0);

    else
    {
      TwclBluetoothRadio* Radio = GetRadio();
      if (Radio != NULL)
      {
        __int64 Addr = StrToInt64("$" + lvDevices->Selected->Caption);
        wclRfCommClient->Address = Addr;
        int Res = wclRfCommClient->Connect(Radio);
        if (Res != WCL_E_SUCCESS)
        {
		  MessageDlg("Failed to connect: 0x" + IntToHex(Res, 8),
            mtError, TMsgDlgButtons() << mbOK, 0);
        }
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btSelectFileClick(TObject *Sender)
{
  if (OpenDialog->Execute())
    edFileName->Text = OpenDialog->FileName;
}
//---------------------------------------------------------------------------

#if __BORLANDC__ >= 0x0740
  void __fastcall TfmMain::OppPutComplete(TObject* Sender, const int Error,
	const String Description, TStream* const Stream)
#else
  void __fastcall TfmMain::OppPutComplete(TObject* Sender, const int Error,
	const String Description, const TStream* Stream)
#endif
{
  lbLog->Items->Add("File sending completed with result: 0x" +
    IntToHex(Error, 8) + ". Description: " + Description);

  ProgressBar->Position = 0;
  ProgressBar->Max = 0;

  // We must destroy the stream object here.
  ((TStream*)Stream)->Free();
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::OppProgress(TObject* Sender, const unsigned Length,
  const unsigned Position)
{
  ProgressBar->Max = Length;
  ProgressBar->Position = Position;
}
//---------------------------------------------------------------------------


void __fastcall TfmMain::btAbortClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    int Res = FOpp->Abort("");
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("Abort failed: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btSendFileClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    if (edFileName->Text == "")
      MessageDlg("Select file", mtWarning, TMsgDlgButtons() << mbOK, 0);

    else
    {
      TFileStream* Stream = new TFileStream(edFileName->Text, fmOpenRead);
      int Res = FOpp->Put(ExtractFileName(edFileName->Text), "", Stream);
      if (Res != WCL_E_SUCCESS)
      {
        MessageDlg("Send file failed: 0x" + IntToHex(Res, 8), mtError,
          TMsgDlgButtons() << mbOK, 0);
        Stream->Free();
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btGetvCardClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    TFileStream* Stream = new TFileStream("vcard.vcf", fmCreate);
    // Request default vCard object.
    int Res = FOpp->Get("text/x-vCard", Stream);
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("GetvCard failed: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
      Stream->Free();
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btGetCapsClick(TObject *Sender)
{
  if (FOpp == NULL)
    MessageDlg("Not connected", mtWarning, TMsgDlgButtons() << mbOK, 0);
  else
  {
    TFileStream* Stream = new TFileStream("caps.xml", fmCreate);
    // Request default vCard object.
    int Res = FOpp->Get("x-obex/capability", Stream);
    if (Res != WCL_E_SUCCESS)
    {
      MessageDlg("GetCaps failed: 0x" + IntToHex(Res, 8), mtError,
        TMsgDlgButtons() << mbOK, 0);
      Stream->Free();
    }
  }
}
//---------------------------------------------------------------------------

#if __BORLANDC__ >= 0x0740
  void __fastcall TfmMain::OppGetComplete(TObject* Sender, const int Error,
	const String Description, TStream* const Stream)
#else
  void __fastcall TfmMain::OppGetComplete(TObject* Sender, const int Error,
    const String Description, const TStream* Stream)
#endif
{
  lbLog->Items->Add("File receiving completed with result: 0x" +
    IntToHex(Error, 8) + ". Description: " + Description);

  ProgressBar->Position = 0;
  ProgressBar->Max = 0;

  // We must destroy the stream object here.
  ((TStream*)Stream)->Free();
}
//---------------------------------------------------------------------------
