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

#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::FormDestroy(TObject *Sender)
{
  wclAudioSwitcher->Close();       
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btEnumClick(TObject *Sender)
{
  EnumDevices();        
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btDefaultClick(TObject *Sender)
{
  if (lvDevices->Selected == NULL)
    ShowMessage("Select device");
  else
  {
    TwclAudioDeviceRole Role;
    switch (cbRole->ItemIndex)
    {
      case 0:
        Role = drConsole;
        break;
      case 1:
        Role = drMultimedia;
        break;
      default:
        Role = drCommunications;
        break;
    }

    int Res = wclAudioSwitcher->SetDefault(Role, lvDevices->Selected->Caption);
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Unable to set default device: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclAudioSwitcherOpened(TObject *Sender)
{
  lbLog->Items->Add("Audio switcher opened");
  EnumDevices();
}
//---------------------------------------------------------------------------
void TfmMain::EnumDevices()
{
  TwclAudioDeviceStates States;
  if (cbActive->Checked)
    States << asActive;
  if (cbDisabled->Checked)
    States << asDisabled;
  if (cbNotPresent->Checked)
    States << asNotPresent;
  if (cbUnplugged->Checked)
    States << asUnplugged;
  if (States.Empty())
    ShowMessage("Select device state.");
  else
  {
    lvDevices->Clear();

    TwclAudioDevices Devices;
    int Res = wclAudioSwitcher->Enum(States, Devices);
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Enum failed: 0x" + IntToHex(Res, 8));
    else
    {
      if (Devices.Length > 0)
      {
        for (int i = 0; i < Devices.Length; i++)
        {
          TListItem* Item = lvDevices->Items->Add();
          Item->Caption = Devices[i].Id;
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          Item->SubItems->Add("");
          UpdateDevice(Item, Devices[i]);
        }
      }
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::wclAudioSwitcherClosed(TObject *Sender)
{
  lvDevices->Clear();
  lbLog->Items->Add("Audio switcher closed");
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btClearClick(TObject *Sender)
{
  lbLog->Clear();        
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclAudioSwitcherDefaultDeviceChanged(
      TObject *Sender, const String Id,
      const TwclAudioDeviceDataFlow Flow, const TwclAudioDeviceRole Role)
{
  String Str = "Default device changed: " + Id + "; Flow: ";
  if (Flow == dfRender)
    Str += "Render";
  else
    Str += "Capture";
  Str += "; Role: ";
  switch (Role)
  {
    case drConsole:
      Str += "Console";
      break;
    case drMultimedia:
      Str += "Multimedia";
      break;
    case drCommunications:
      Str += "Communications";
      break;
  }
  lbLog->Items->Add(Str);
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclAudioSwitcherDeviceAdded(TObject *Sender,
      const String Id)
{
  lbLog->Items->Add("Device added: " + Id);        
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclAudioSwitcherDeviceRemoved(TObject *Sender,
      const String Id)
{
  lbLog->Items->Add("Device removed: " + Id);        
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::wclAudioSwitcherStateChanged(TObject *Sender,
	  const String Id, const TwclAudioDeviceState State)
{
  String Str;
  switch (State)
  {
    case asActive:
      Str = "Active";
      break;
    case asDisabled:
      Str = "Disabled";
      break;
    case asNotPresent:
      Str = "NotPresent";
      break;
    case asUnplugged:
      Str = "Unplugged";
      break;
  }
  lbLog->Items->Add("Device " + Id + " state changed: " + Str);
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btRefreshClick(TObject *Sender)
{
  if (lvDevices->Selected == NULL)
    ShowMessage("Select device");
  else
  {
    TwclAudioDevice Device;
    int Res = wclAudioSwitcher->GetDeviceDetails(lvDevices->Selected->Caption,
      Device);
    if (Res != WCL_E_SUCCESS)
      ShowMessage("Refresh device error: 0x" + IntToHex(Res, 8));
    else
      UpdateDevice(lvDevices->Selected, Device);
  }
}
//---------------------------------------------------------------------------

void TfmMain::UpdateDevice(TListItem* Item, const TwclAudioDevice& Device)
{
  String FlowStr;
  if (Device.Flow == dfRender)
    FlowStr = "Render";
  else
    FlowStr = "Capture";

  String RolesStr = "[ ";
  if (Device.Roles.Contains(drConsole))
    RolesStr += "Console ";
  if (Device.Roles.Contains(drMultimedia))
    RolesStr += "Multimedia ";
  if (Device.Roles.Contains(drCommunications))
    RolesStr += "Communications ";
  RolesStr += "]";

  String StateStr;
  switch (Device.State)
  {
    case asActive:
      StateStr = "Active";
      break;
    case asDisabled:
      StateStr = "Disabled";
      break;
    case asNotPresent:
      StateStr = "NotPresent";
      break;
    case asUnplugged:
      StateStr = "Unplugged";
      break;
  }

  String MacStr;
  String ServiceStr;
  if (Device.IsBluetooth)
  {
    MacStr = IntToHex(Device.Mac, 12);
    ServiceStr = Sysutils::GUIDToString(Device.Service);
  }
  else
  {
    MacStr = "";
    ServiceStr = "";
  }

  Item->SubItems->Strings[0] = Device.FriendlyName;
  Item->SubItems->Strings[1] = Device.Description;
  Item->SubItems->Strings[2] = FlowStr;
  Item->SubItems->Strings[3] = RolesStr;
  Item->SubItems->Strings[4] = StateStr;
  Item->SubItems->Strings[5] = MacStr;
  Item->SubItems->Strings[6] = ServiceStr;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::btConnectClick(TObject *Sender)
{
  if (lvDevices->Selected == NULL)
    ShowMessage("Select device");
  else
  {
    int Res;
    if (cbUseMac->Checked)
    {
      if (lvDevices->Selected->SubItems->Strings[5] == "")
      {
        ShowMessage("Selected device is not Bluetooth enabled");
        return;
      }

      Res = wclAudioSwitcher->Connect(
        StrToInt64("$" + lvDevices->Selected->SubItems->Strings[5]));
    }
    else
      Res = wclAudioSwitcher->Connect(lvDevices->Selected->Caption);

    if (Res != WCL_E_SUCCESS)
      ShowMessage("Connect error: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btDisconnectClick(TObject *Sender)
{
  if (lvDevices->Selected == NULL)
    ShowMessage("Select device");
  else
  {
    int Res;
    if (cbUseMac->Checked)
    {
      if (lvDevices->Selected->SubItems->Strings[5] == "")
      {
        ShowMessage("Selected device is not Bluetooth enabled");
        return;
      }

      Res = wclAudioSwitcher->Disconnect(
        StrToInt64("$" + lvDevices->Selected->SubItems->Strings[5]));
    }
    else
      Res = wclAudioSwitcher->Disconnect(lvDevices->Selected->Caption);

    if (Res != WCL_E_SUCCESS)
      ShowMessage("Connect error: 0x" + IntToHex(Res, 8));
  }
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::FormCreate(TObject *Sender)
{
  int Res = wclAudioSwitcher->Open();
  if (Res != WCL_E_SUCCESS)
    lbLog->Items->Add("Open failed: 0x" + IntToHex(Res, 8));
}
//---------------------------------------------------------------------------

void __fastcall TfmMain::btGetDefaultClick(TObject *Sender)
{
  TwclAudioDeviceRole Role;
  switch (cbRole->ItemIndex)
  {
    case 0:
      Role = drConsole;
      break;
    case 1:
      Role = drMultimedia;
      break;
    default:
      Role = drCommunications;
      break;
  }

  TwclAudioDeviceDataFlow Flow;
  if (cbFlow->ItemIndex == 0)
    Flow = dfCapture;
  else
    Flow = dfRender;

  String Id;
  int Res = wclAudioSwitcher->GetDefault(Role, Flow, Id);
  if (Res != WCL_E_SUCCESS)
    ShowMessage("Unable to get default device: 0x" + IntToHex(Res, 8));
  else
    ShowMessage("Default device ID: " + Id);
}
//---------------------------------------------------------------------------

