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

#include <vcl.h>
#pragma hdrstop

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

TfmMain *fmMain;
//---------------------------------------------------------------------------
__fastcall TfmMain::TfmMain(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
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::FtpConnect(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::FtpDisconnect(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("OBEX session closed with result: 0x" + IntToHex(Error, 8) +
    ". Description: " + Description);
  lvFiles->Items->Clear();
}
//---------------------------------------------------------------------------
#if __BORLANDC__ >= 0x0740
  void __fastcall TfmMain::FtpPutComplete(TObject* Sender, const int Error,
	const String Description, TStream* const Stream)
#else
  void __fastcall TfmMain::FtpPutComplete(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::FtpProgress(TObject* Sender, const unsigned Length,
  const unsigned Position)
{
  ProgressBar->Max = Length;
  ProgressBar->Position = Position;
}
//---------------------------------------------------------------------------
#if __BORLANDC__ >= 0x0740
  void __fastcall TfmMain::FtpGetComplete(TObject* Sender, const int Error,
	const String Description, TStream* const Stream)
#else
  void __fastcall TfmMain::FtpGetComplete(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();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FtpDirComplete(TObject* Sender, const int Error,
  const String Description, const TwclObexFileObjects Dirs)
{
  lbLog->Items->Add("Dir completed with result: 0x" + IntToHex(Error, 8) +
    ". Description: " + Description);

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

  for (int i = 0; i < Dirs.Length; i++)
  {
    TListItem* Item = lvFiles->Items->Add();
    Item->Caption = Dirs[i].Name;
    if (Dirs[i].IsDirectory)
      Item->SubItems->Add("Folder");
    else
      Item->SubItems->Add("File");
    Item->SubItems->Add(IntToStr((int)Dirs[i].Size));

    String Perm = "";
    if (Dirs[i].Permissions.Contains(opRead))
      Perm = Perm + "R";
    if (Dirs[i].Permissions.Contains(opWrite))
      Perm = Perm + "W";
    if (Dirs[i].Permissions.Contains(opDelete))
      Perm = Perm + "D";
    Item->SubItems->Add(Perm);
    if (Dirs[i].Modified != TDateTime(0))
      Item->SubItems->Add(DateToStr(Dirs[i].Modified));
    else
      Item->SubItems->Add("");
    if (Dirs[i].Created != TDateTime(0))
      Item->SubItems->Add(DateToStr(Dirs[i].Created));
    else
      Item->SubItems->Add("");
    if (Dirs[i].Accessed != TDateTime(0))
      Item->SubItems->Add(DateToStr(Dirs[i].Accessed));
    else
      Item->SubItems->Add("");

    Item->SubItems->Add(Dirs[i].Description);
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FtpChangeDirComplete(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("Change dir completed with result: 0x" +
    IntToHex(Error, 8) + ". Description: " + Description);

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

  lvFiles->Items->Clear();
  FFtp->Dir();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FtpDeleteComplete(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("Delete completed with result: 0x" +
    IntToHex(Error, 8) + ". Description: " + Description);

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

  lvFiles->Items->Clear();
  FFtp->Dir();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FtpMkDirComplete(TObject* Sender, const int Error,
  const String Description)
{
  lbLog->Items->Add("Make dir completed with result: 0x" +
    IntToHex(Error, 8) + ". Description: " + Description);

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

  lvFiles->Items->Clear();
  FFtp->Dir();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::FormCreate(TObject *Sender)
{
  // We use ObjectPush Profile so must set the profile"s UUID.
  wclRfCommClient->Service = OBEXFileTransferServiceClass_UUID;

  FFtp = 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("");
}
//---------------------------------------------------------------------------

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)
      ShowMessage("Failed to start discovering: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

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

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 (FFtp != NULL)
  {
    // Make sure it is our connection is goind to destroy.
    if (Connection->Processor == FFtp)
    {
      // Ok, destroy the data processor here.
      FFtp->Free();
      FFtp = 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
	FFtp = new TwclObexFtpClient((TwclClientDataConnection*)Connection);
	#if __BORLANDC__ >= 0x0740
	  FFtp->OnGetComplete = FtpGetComplete;
	  FFtp->OnPutComplete = FtpPutComplete;
	#else
	  FFtp->OnGetComplete = (TwclObexObjectOperationResultEvent)&FtpGetComplete;
	  FFtp->OnPutComplete = (TwclObexObjectOperationResultEvent)&FtpPutComplete;
	#endif
  #else
	FFtp = new TwclObexFtpClient(Connection);
	FFtp->OnGetComplete = FtpGetComplete;
	FFtp->OnPutComplete = FtpPutComplete;
  #endif
  FFtp->OnConnect = FtpConnect;
  FFtp->OnDisconnect = FtpDisconnect;
  FFtp->OnProgress = FtpProgress;
  FFtp->OnDirComplete = FtpDirComplete;
  FFtp->OnChangeDirComplete = FtpChangeDirComplete;
  FFtp->OnDeleteComplete = FtpDeleteComplete;
  FFtp->OnMakeDirComplete = FtpMkDirComplete;
}
//---------------------------------------------------------------------------

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

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

void __fastcall TfmMain::btConnectClick(TObject *Sender)
{
  if (wclRfCommClient->State != csDisconnected)
    ShowMessage("Client is connected");
  else
  {
    if (lvDevices->Selected == NULL)
      ShowMessage("Select device");
    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)
          ShowMessage("Failed to connect: 0x" + IntToHex(Res, 8));
      }
    }
  }
}
//---------------------------------------------------------------------------

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

void __fastcall TfmMain::btAbortClick(TObject *Sender)
{
  if (FFtp == NULL)
    ShowMessage("Not connected");
  else
  {
    int Res = FFtp->Abort("");
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Open session failed: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btSendFileClick(TObject *Sender)
{
  if (FFtp == NULL)
    ShowMessage("Not connected");
  else
  {
    if (edFileName->Text == "")
      ShowMessage("Select file");
    else
    {
      TFileStream* Stream = new TFileStream(edFileName->Text, fmOpenRead);
      int Res = FFtp->Put(ExtractFileName(edFileName->Text), "", Stream);
      if (Res != WCL_E_SUCCESS)
      {
        ShowMessage("Send file failed: 0x" + IntToHex(Res, 8));
        Stream->Free();
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btDirClick(TObject *Sender)
{
  if (FFtp == NULL)
    ShowMessage("Not connected");
  else
  {
    int Res = FFtp->Dir();
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Dir failed: 0x" + IntToHex(Res, 8));
    else
      lvFiles->Items->Clear();
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::lvFilesDblClick(TObject *Sender)
{
  if (lvFiles->Selected != NULL)
  {
    if (FFtp == NULL)
      ShowMessage("Not connected");
    else
    {
      if (lvFiles->Selected->SubItems->Strings[0] == "Folder")
      {
        int Res = FFtp->ChangeDir(lvFiles->Selected->Caption);
        if (Res != WCL_E_SUCCESS)
          ShowMessage("Change path failed 0x" + IntToHex(Res, 8));
      }
      else
      {
        TFileStream* Stream = new TFileStream(".\\" + lvFiles->Selected->Caption,
           fmCreate);
        int Res = FFtp->Get(lvFiles->Selected->Caption, Stream);
        if (Res != WCL_E_SUCCESS)
        {
          ShowMessage("Get failed 0x" + IntToHex(Res, 8));
          Stream->Free();
        }
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btRootClick(TObject *Sender)
{
  if (FFtp == NULL)
    ShowMessage("Not connected");
  else
  {
    int Res = FFtp->ChangeDir("");
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Root failed 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btDeleteClick(TObject *Sender)
{
  if (lvFiles->Selected != NULL)
  {
    if (FFtp == NULL)
      ShowMessage("Not connected");
    else
    {
      int Res = FFtp->Delete(lvFiles->Selected->Caption);
      if (Res != WCL_E_SUCCESS)
        ShowMessage("Delete failed 0x" + IntToHex(Res, 8));
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btMkDirClick(TObject *Sender)
{
  if (FFtp == NULL)
    ShowMessage("Not connected");
  else
  {
    int Res = FFtp->MkDir(edNewDirName->Text);
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Make sire failed 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

