//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop

#include "Settings.h"
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TFormSettings *FormSettings;

//---------------------------------------------------------------------------
String BooleanToStr(bool value)
{
  return value ? "True" : "False";
}
//---------------------------------------------------------------------------
__fastcall TFormSettings::TFormSettings(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxCameraChange(TObject *Sender)
{
  TACamera *Camera = FormMain->ACamera;
  Camera->Active = false;

  ChangesDisabled = true;
  try
  {
    Camera->CameraIndex = ComboBoxCamera->ItemIndex;

    try
    {
      Camera->Active = true;
      Camera->PreviewSize = Camera->PreferredPreviewSize;
      if (Camera->SupportedFocusModes.Contains(foContinuousVideo))
        Camera->FocusMode = foContinuousVideo;

      SetComboBoxSceneMode(Camera);
      SetComboBoxPreviewSize(Camera);
      SetComboBoxPictureSize(Camera);
      SetComboBoxFocusMode(Camera);
      SetComboBoxFlashMode(Camera);
      SetComboBoxColorEffect(Camera);
      SetComboBoxAntibanding(Camera);
      SetComboBoxWhiteBalance(Camera);
    }
    catch (Exception &exception)
    {
      ShowMessage(exception.Message);
    }
  }
  __finally
  {
    ChangesDisabled = false;
  }
}
//---------------------------------------------------------------------------
TSceneMode SceneModes[] =
{
  smUnknown, smAction, smAuto, smBarcode, smBeach, smCandleLight, smFireworks, smHdr, smLandscape,
  smNight, smNighPortrait, smParty, smPortrait, smSnow, smSports, smSteadyPhoto, smSunset, smTheatre
};

String SceneModeNames[] =
{
  "Unknown", "Action", "Auto", "Barcode", "Beach", "Candle light", "Fireworks", "HDR", "Landscape",
  "Night", "Nigh portrait", "Party", "Portrait", "Snow", "Sports", "Steady photo", "Sunset", "Theatre"
};

void __fastcall TFormSettings::SetComboBoxSceneMode(TACamera *Camera)
{
  ComboBoxSceneMode->ItemIndex = -1;
  ComboBoxSceneMode->Items->Clear();
  ComboBoxSceneMode->Enabled = false;

  TSceneMode CameraSceneMode = Camera->SceneMode;
  TSceneModes SupportedSceneModes = Camera->SupportedSceneModes;
  for (int i = 0; i < sizeof(SceneModes) / sizeof(SceneModes[0]); ++i)
    if (SupportedSceneModes.Contains(SceneModes[i]))
    {
      ComboBoxSceneMode->Items->Add(SceneModeNames[i]);
      if (SceneModes[i] == CameraSceneMode)
        ComboBoxSceneMode->ItemIndex = ComboBoxSceneMode->Items->Count - 1;
    }
  ComboBoxSceneMode->Enabled = ComboBoxSceneMode->Items->Count > 1;
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::SetComboBoxPreviewSize(TACamera *Camera)
{
  ComboBoxPreviewSize->ItemIndex = -1;
  ComboBoxPreviewSize->Items->Clear();
  ComboBoxPreviewSize->Enabled = false;

  Camera::TSize CameraSize = Camera->PreviewSize;
  System::DynamicArray<Camera::TSize> SupportedSizes = Camera->SupportedPreviewSizes;
  for (int i = 0; i < SupportedSizes.Length; ++i)
  {
    Camera::TSize Size = SupportedSizes[i];
    ComboBoxPreviewSize->Items->Append(IntToStr(Size.Width) + " x " + IntToStr(Size.Height));
    if ((Size.Width == CameraSize.Width) && (Size.Height == CameraSize.Height))
      ComboBoxPreviewSize->ItemIndex = ComboBoxPreviewSize->Items->Count - 1;
  }
  ComboBoxPreviewSize->Enabled = ComboBoxPreviewSize->Items->Count > 1;
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::SetComboBoxPictureSize(TACamera *Camera)
{
  ComboBoxPictureSize->ItemIndex = -1;
  ComboBoxPictureSize->Items->Clear();
  ComboBoxPictureSize->Enabled = false;

  Camera::TSize CameraSize = Camera->PictureSize;
  System::DynamicArray<Camera::TSize> SupportedSizes = Camera->SupportedPictureSizes;
  for (int i = 0; i < SupportedSizes.Length; ++i)
  {
    Camera::TSize Size = SupportedSizes[i];
    ComboBoxPictureSize->Items->Append(IntToStr(Size.Width) + " x " + IntToStr(Size.Height));
    if ((Size.Width == CameraSize.Width) && (Size.Height == CameraSize.Height))
      ComboBoxPictureSize->ItemIndex = ComboBoxPictureSize->Items->Count - 1;
  }
  ComboBoxPictureSize->Enabled = ComboBoxPictureSize->Items->Count > 1;
}
//---------------------------------------------------------------------------
TFocusMode FocusModes[] =
{
  foUnknown, foAuto, foContinuousPicture, foContinuousVideo, foEdof, foFixed, foInfinity, foMacro
};

String FocusModeNames[] =
{
  "Unknown", "Auto", "Continuous picture", "Continuous video", "EDOF", "Fixed", "Infinity", "Macro"
};

void __fastcall TFormSettings::SetComboBoxFocusMode(TACamera *Camera)
{
  ComboBoxFocusMode->ItemIndex = -1;
  ComboBoxFocusMode->Items->Clear();
  ComboBoxFocusMode->Enabled = false;

  TFocusMode CameraFocusMode = Camera->FocusMode;
  TFocusModes SupportedFocusModes = Camera->SupportedFocusModes;
  for (int i = 0; i < sizeof(FocusModes) / sizeof(FocusModes[0]); ++i)
    if (SupportedFocusModes.Contains(FocusModes[i]))
    {
      ComboBoxFocusMode->Items->Add(FocusModeNames[i]);
      if (FocusModes[i] == CameraFocusMode)
        ComboBoxFocusMode->ItemIndex = ComboBoxFocusMode->Items->Count - 1;
    }
  ComboBoxFocusMode->Enabled = ComboBoxFocusMode->Items->Count > 1;
}
//---------------------------------------------------------------------------
TFlashMode FlashModes[] = { flUnknown, flOff, flAuto, flOn, flTorch, flRedEye };

String FlashModeNames[] = { "Unknown", "Off", "Auto", "On", "Torch", "Red eye" };

void __fastcall TFormSettings::SetComboBoxFlashMode(TACamera *Camera)
{
  ComboBoxFlashMode->ItemIndex = -1;
  ComboBoxFlashMode->Items->Clear();
  ComboBoxFlashMode->Enabled = false;

  TFlashMode CameraFlashMode = Camera->FlashMode;
  TFlashModes SupportedFlashModes = Camera->SupportedFlashModes;
  for (int i = 0; i < sizeof(FlashModes) / sizeof(FlashModes[0]); ++i)
    if (SupportedFlashModes.Contains(FlashModes[i]))
    {
      ComboBoxFlashMode->Items->Add(FlashModeNames[i]);
      if (FlashModes[i] == CameraFlashMode)
        ComboBoxFlashMode->ItemIndex = ComboBoxFlashMode->Items->Count - 1;
    }
  ComboBoxFlashMode->Enabled = ComboBoxFlashMode->Items->Count > 1;
}
//---------------------------------------------------------------------------
TColorEffect ColorEffects[] =
{
  ceUnknown, ceNone, ceMono, ceNegative, ceSolarize, ceSepia, cePosterize,
  ceWhiteBoard, ceBlackBoard, ceAqua, ceEmboss, ceSketch, ceNeon
};

String ColorEffectNames[] =
{
  "Unknown", "None", "Mono", "Negative", "Solarize", "Sepia", "Posterize",
  "White board", "Black board", "Aqua", "Emboss", "Sketch", "Neon"
};

void __fastcall TFormSettings::SetComboBoxColorEffect(TACamera *Camera)
{
  ComboBoxColorEffect->ItemIndex = -1;
  ComboBoxColorEffect->Items->Clear();
  ComboBoxColorEffect->Enabled = false;

  TColorEffect CameraColorEffect = Camera->ColorEffect;
  TColorEffects SupportedColorEffects = Camera->SupportedColorEffects;
  for (int i = 0; i < sizeof(ColorEffects) / sizeof(ColorEffects[0]); ++i)
    if (SupportedColorEffects.Contains(ColorEffects[i]))
    {
      ComboBoxColorEffect->Items->Add(ColorEffectNames[i]);
      if (ColorEffects[i] == CameraColorEffect)
        ComboBoxColorEffect->ItemIndex = ComboBoxColorEffect->Items->Count - 1;
    }
  ComboBoxColorEffect->Enabled = ComboBoxColorEffect->Items->Count > 1;
}
//---------------------------------------------------------------------------
TAntibanding Antibandings[] = { abUnknown, abOff, abAuto, ab50Hz, ab60Hz };

String AntibandingNames[] = { "Unknown", "Off", "Auto", "50Hz", "60Hz" };

void __fastcall TFormSettings::SetComboBoxAntibanding(TACamera *Camera)
{
  ComboBoxAntibanding->ItemIndex = -1;
  ComboBoxAntibanding->Items->Clear();
  ComboBoxAntibanding->Enabled = false;

  TAntibanding CameraAntibanding = Camera->Antibanding;
  TAntibandings SupportedAntibandings = Camera->SupportedAntibandings;
  for (int i = 0; i < sizeof(Antibandings) / sizeof(Antibandings[0]); ++i)
    if (SupportedAntibandings.Contains(Antibandings[i]))
    {
      ComboBoxAntibanding->Items->Add(AntibandingNames[i]);
      if (Antibandings[i] == CameraAntibanding)
        ComboBoxAntibanding->ItemIndex = ComboBoxAntibanding->Items->Count - 1;
    }
  ComboBoxAntibanding->Enabled = ComboBoxAntibanding->Items->Count > 1;
}
//---------------------------------------------------------------------------
TWhiteBalance WhiteBalances[] =
{
  wbUnknown, wbAuto, wbCloudyDaylight, wbDaylight, wbFluorescent,
  wbIncandescent, wbShade, wbTwilight, wbWarmFluorescent
};

String WhiteBalanceNames[] =
{
  "Unknown", "Auto", "Cloudy daylight", "Daylight", "Fluorescent",
  "Incandescent", "Shade", "Twilight", "Warm fluorescent"
};

void __fastcall TFormSettings::SetComboBoxWhiteBalance(TACamera *Camera)
{
  ComboBoxWhiteBalance->ItemIndex = -1;
  ComboBoxWhiteBalance->Items->Clear();
  ComboBoxWhiteBalance->Enabled = false;

  TWhiteBalance CameraWhiteBalance = Camera->WhiteBalance;
  TWhiteBalances SupportedWhiteBalance = Camera->SupportedWhiteBalance;
  for (int i = 0; i < sizeof(WhiteBalances) / sizeof(WhiteBalances[0]); ++i)
    if (SupportedWhiteBalance.Contains(WhiteBalances[i]))
    {
      ComboBoxWhiteBalance->Items->Add(WhiteBalanceNames[i]);
      if (WhiteBalances[i] == CameraWhiteBalance)
        ComboBoxWhiteBalance->ItemIndex = ComboBoxWhiteBalance->Items->Count - 1;
    }
  ComboBoxWhiteBalance->Enabled = ComboBoxWhiteBalance->Items->Count > 1;
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::TabControlChange(TObject *Sender)
{
  if (TabControl->TabIndex == 1)
    SetCameraInfo();
}
//---------------------------------------------------------------------------
TTreeViewItem* __fastcall TFormSettings::AddItem(const String Text)
{
  TTreeViewItem* Result = new TTreeViewItem(TreeView);
  Result->Text = Text;
  Result->IsExpanded = true;
  TreeView->AddObject(Result);
  return Result;
}
//---------------------------------------------------------------------------
TTreeViewItem* __fastcall TFormSettings::AddItem(TTreeViewItem *TreeViewItem, const String Text)
{
  TTreeViewItem* Result = new TTreeViewItem(TreeViewItem);
  Result->Text = Text;
  TreeViewItem->AddObject(Result);
  return Result;
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::SetCameraInfo()
{
  TImageFormat ImageFormats[] =
  {
    ifUnknown, ifJPEG, ifNV16, ifNV21,
    ifRaw10, ifRaw12, ifRawSensor, ifRawPrivate,
    ifPrivate, ifDepth16, ifDepthPointCloud,
    ifRGB565, ifFlexRGB888, ifFlexRGBA8888,
    ifYUV420_888, ifYUV422_888, ifYUV444_888, ifYUY2, ifYV12
  };

  String ImageFormatNames[] =
  {
    "Unknown", "JPEG", "NV16", "NV21",
    "Raw10", "Raw12", "RawSensor", "RawPrivate",
    "Private", "Depth16", "DepthPointCloud",
    "RGB565", "FlexRGB888", "FlexRGBA8888",
    "YUV420_888", "YUV422_888", "YUV444_888", "YUY2", "YV12"
  };

  TreeView->Clear();

  TACamera *Camera = FormMain->ACamera;
  if (!Camera->Active)
    return;

  TCameraInfo CameraInfo = Camera->CameraInfo[ComboBoxCamera->ItemIndex];

  AddItem("Can disable shutter sound: " + BooleanToStr(CameraInfo.CanDisableShutterSound));
  AddItem("EV: " + FloatToStrF(Camera->EV, ffFixed, 10, 2));
  AddItem("Exposure compensation: " + IntToStr(Camera->ExposureCompensation));
  AddItem("Exposure compensation step: " + FloatToStrF(Camera->ExposureCompensationStep, ffFixed, 10, 2));
  AddItem("Focal length: " + FloatToStrF(Camera->FocalLength, ffFixed, 10, 2));
  AddItem("Horizontal view angle: " + FloatToStrF(Camera->HorizontalViewAngle, ffFixed, 10, 2));
  AddItem("JPEG quality: " + IntToStr(Camera->JpegQuality));
  AddItem("JPEG thumbnail quality: " + IntToStr(Camera->JpegThumbnailQuality));
  AddItem("JPEG thumbnail size: " + IntToStr(Camera->JpegThumbnailSize.Width) + " x " + IntToStr(Camera->JpegThumbnailSize.Height));
  AddItem("Max detected faces: " + IntToStr(Camera->MaxDetectedFaces));
  AddItem("Max exposure compensation: " + IntToStr(Camera->MaxExposureCompensation));
  if (Camera->ZoomSupported)
    AddItem("Max zoom: " + IntToStr(Camera->MaxZoom));
  AddItem("Min exposure compensation: " + IntToStr(Camera->MinExposureCompensation));
  AddItem("Orientation: " + IntToStr(CameraInfo.Orientation));
  if (!Camera->SupportedPictureFormats.Empty())
    AddItem("Picture format: " + ImageFormatNames[Camera->PictureFormat]);
  AddItem("Preferred preview size: " + IntToStr(Camera->PreferredPreviewSize.Width) + " x " + IntToStr(Camera->PreferredPreviewSize.Height));
  if (!Camera->SupportedPreviewFormats.Empty())
    AddItem("Preview format: " + ImageFormatNames[Camera->PreviewFormat]);
  AddItem("Preview FPS: " + FloatToStr(Camera->PreviewFps.Min / 1000.0) + " - " + FloatToStr(Camera->PreviewFps.Max / 1000.0));
  if (Camera->ZoomSupported)
    AddItem("Smooth zoom supported: " + BooleanToStr(Camera->SmoothZoomSupported));

  System::DynamicArray<Camera::TSize> Sizes = Camera->SupportedJpegThumbnailSizes;
  if (Sizes.Length > 0)
  {
    TTreeViewItem* Item = AddItem("Supported JPEG thumbnail sizes");
    for (int i = 0; i < Sizes.Length; ++i)
      AddItem(Item, IntToStr(Sizes[i].Width) + " x " + IntToStr(Sizes[i].Height));
  }

  if (!Camera->SupportedPictureFormats.Empty())
  {
    TTreeViewItem* Item = AddItem("Supported picture formats");
    TImageFormats Formats = Camera->SupportedPictureFormats;
    for (int i = 0; i < sizeof(ImageFormats) / sizeof(ImageFormats[0]); ++i)
      if (Formats.Contains(ImageFormats[i]))
        AddItem(Item, ImageFormatNames[i]);
  }

  if (!Camera->SupportedPreviewFormats.Empty())
  {
    TTreeViewItem* Item = AddItem("Supported preview formats");
    TImageFormats Formats = Camera->SupportedPreviewFormats;
    for (int i = 0; i < sizeof(ImageFormats) / sizeof(ImageFormats[0]); ++i)
      if (Formats.Contains(ImageFormats[i]))
        AddItem(Item, ImageFormatNames[i]);
  }

  Sizes = Camera->SupportedVideoSizes;
  if (Sizes.Length > 0)
  {
    TTreeViewItem* Item = AddItem("Supported video sizes");
    for (int i = 0; i < Sizes.Length; ++i)
      AddItem(Item, IntToStr(Sizes[i].Width) + " x " + IntToStr(Sizes[i].Height));
  }

  AddItem("Vertical view angle: " + FloatToStrF(Camera->VerticalViewAngle, ffFixed, 10, 2));

  if (Camera->VideoStabilizationSupported)
    AddItem("Video stabilization: " + BooleanToStr(Camera->VideoStabilization));
  else
    AddItem("Video stabilization suppported: False");

  if (Camera->ZoomSupported)
  {
    AddItem("Zoom: " + IntToStr(Camera->Zoom));
    TTreeViewItem* Item = AddItem("Zoom ratios");

    System::DynamicArray<int> ZoomRatios = Camera->ZoomRatios;
    for (int i = 0; i < ZoomRatios.Length; ++i)
      AddItem(Item, FloatToStr(ZoomRatios[i] / 100.0));
  }
  else
    AddItem("Zoom suppported: False");
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxPictureSizeChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxPictureSize->ItemIndex == -1)
    return;

  FormMain->ACamera->PictureSize = FormMain->ACamera->SupportedPictureSizes[ComboBoxPictureSize->ItemIndex];
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxPreviewSizeChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxPreviewSize->ItemIndex == -1)
    return;

  FormMain->ACamera->PreviewSize = FormMain->ACamera->SupportedPreviewSizes[ComboBoxPreviewSize->ItemIndex];
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxSceneModeChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxSceneMode->ItemIndex == -1)
    return;

  String SceneModeName = (*ComboBoxSceneMode->Items)[ComboBoxSceneMode->ItemIndex];
  for (int i = 0; i < sizeof(SceneModes) / sizeof(SceneModes[0]); ++i)
    if (SceneModeNames[i] == SceneModeName)
    {
      if (FormMain->ACamera->SceneMode != SceneModes[i])
      {
        FormMain->ACamera->SceneMode = SceneModes[i];

        ChangesDisabled = true;
        try
        {
          SetComboBoxPreviewSize(FormMain->ACamera);
          SetComboBoxPictureSize(FormMain->ACamera);
          SetComboBoxFocusMode(FormMain->ACamera);
          SetComboBoxFlashMode(FormMain->ACamera);
          SetComboBoxColorEffect(FormMain->ACamera);
          SetComboBoxAntibanding(FormMain->ACamera);
          SetComboBoxWhiteBalance(FormMain->ACamera);
        }
        __finally
        {
          ChangesDisabled = false;
        }
      }
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxFocusModeChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxFocusMode->ItemIndex == -1)
    return;

  String FocusModeName = (*ComboBoxFocusMode->Items)[ComboBoxFocusMode->ItemIndex];
  for (int i = 0; i < sizeof(FocusModes) / sizeof(FocusModes[0]); ++i)
    if (FocusModeNames[i] == FocusModeName)
    {
      FormMain->ACamera->FocusMode = FocusModes[i];
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxFlashModeChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxFlashMode->ItemIndex == -1)
    return;

  String FlashModeName = (*ComboBoxFlashMode->Items)[ComboBoxFlashMode->ItemIndex];
  for (int i = 0; i < sizeof(FlashModes) / sizeof(FlashModes[0]); ++i)
    if (FlashModeNames[i] == FlashModeName)
    {
      FormMain->ACamera->FlashMode = FlashModes[i];
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxColorEffectChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxColorEffect->ItemIndex == -1)
    return;

  String ColorEffectName = (*ComboBoxColorEffect->Items)[ComboBoxColorEffect->ItemIndex];
  for (int i = 0; i < sizeof(ColorEffects) / sizeof(ColorEffects[0]); ++i)
    if (ColorEffectNames[i] == ColorEffectName)
    {
      FormMain->ACamera->ColorEffect = ColorEffects[i];
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxAntibandingChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxAntibanding->ItemIndex == -1)
    return;

  String AntibandingName = (*ComboBoxAntibanding->Items)[ComboBoxAntibanding->ItemIndex];
  for (int i = 0; i < sizeof(Antibandings) / sizeof(Antibandings[0]); ++i)
    if (AntibandingNames[i] == AntibandingName)
    {
      FormMain->ACamera->Antibanding = Antibandings[i];
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ComboBoxWhiteBalanceChange(TObject *Sender)
{
  if (ChangesDisabled || ComboBoxWhiteBalance->ItemIndex == -1)
    return;

  String WhiteBalanceName = (*ComboBoxWhiteBalance->Items)[ComboBoxWhiteBalance->ItemIndex];
  for (int i = 0; i < sizeof(WhiteBalances) / sizeof(WhiteBalances[0]); ++i)
    if (WhiteBalanceNames[i] == WhiteBalanceName)
    {
      FormMain->ACamera->WhiteBalance = WhiteBalances[i];
      break;
    }
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::ApplySettings()
{
  ComboBoxSceneModeChange(NULL);
  ComboBoxPreviewSizeChange(NULL);
  ComboBoxPictureSizeChange(NULL);
  ComboBoxFocusModeChange(NULL);
  ComboBoxFlashModeChange(NULL);
  ComboBoxColorEffectChange(NULL);
  ComboBoxAntibandingChange(NULL);
  ComboBoxWhiteBalanceChange(NULL);
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::FormDeactivate(TObject *Sender)
{
  FormMain->Start();
}
//---------------------------------------------------------------------------
void __fastcall TFormSettings::FormShow(TObject *Sender)
{
  if (!Initialized)
  {
    Initialized = true;

    for (int i = 0; i < FormMain->ACamera->CameraCount; ++i)
    {
      String cameraText = "Camera " + IntToStr(i);

      if (FormMain->ACamera->CameraInfo[i].Facing == cfBack)
        cameraText += " (Back)";
      else
        cameraText += " (Front)";

      ComboBoxCamera->Items->Add(cameraText);
    }

    ComboBoxCamera->ItemIndex = 0;
  }
}
//---------------------------------------------------------------------------
