/*
 CaPriCe Forever - Amstrad CPC 464/664/6128 emulator
 Copyright (C) 2014-2016 by Frédéric Coste

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <vcl.h>
#pragma hdrstop

#include "TFormDrivesCatalogue.h"
#include "TFormMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


static const AnsiString cTitle = "Drives catalogue";

TFormDrivesCatalogue *FormDrivesCatalogue;
//---------------------------------------------------------------------------
__fastcall TFormDrivesCatalogue::TFormDrivesCatalogue(TComponent* Owner)
  : TForm(Owner)
{
  mEmulatorP = NULL;
  mSettingsP = NULL;
  mUser = 0;

  mNbMinEntries = ListBoxCatalogEntries->Items->Count;
  mSizeDiff = ClientHeight - ListBoxCatalogEntries->Height;

  // Apply theme
  Font->Name = "Amstrad CPC464 Regular";
  Font->Size = 6;
  //PanelFormatUser->Font->Size = 12;
  PanelFormatUser->Font->Color = clBlack;
  //EditUser->Font->Size = 12;
  EditUser->Height = 10;
  EditUser->Font->Color = clBlack;
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::FormShow(TObject *Sender)
{
  if (FormMain == NULL)
  {
    Close();
    return;
  }

	FormMain->OnDrivesCatalogueFormShow();

	Caption = Title;
	EditUser->Text = AnsiString(mUser);

	// Subscribe to events
	FormMain->SubscribeToDiskEvents(OnDiskEvent);

	DisplayCatalogue();

	if (mSettingsP)
	{
		mSettingsP->DrivesCatalogueFormVisible = true;
	}

	NOT_USED(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::FormHide(TObject *Sender)
{
	// Unsubscribe to events
	if (FormMain != NULL)
	{
		FormMain->UnsubscribeToDiskEvents(OnDiskEvent);
		FormMain->OnDrivesCatalogueFormHide();
	}

  if (mSettingsP)
  {
    mSettingsP->DrivesCatalogueFormVisible = false;
  }

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------


AnsiString __fastcall TFormDrivesCatalogue::GetTitle(void)
{
  AnsiString Title = cTitle;

  return Title;
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::SetSettings(TSettings* Value)
{
  mSettingsP = Value;

  if (    (mSettingsP->DrivesCatalogueFormLeft != 0)
       || (mSettingsP->DrivesCatalogueFormTop != 0)
       || (mSettingsP->DrivesCatalogueFormWidth != 0)
       || (mSettingsP->DrivesCatalogueFormHeight != 0) )
  {
    Position = poDesigned;
    Left = mSettingsP->DrivesCatalogueFormLeft;
    Top = mSettingsP->DrivesCatalogueFormTop;
    Width = mSettingsP->DrivesCatalogueFormWidth;
    Height = mSettingsP->DrivesCatalogueFormHeight;
  }

  Color = mSettingsP->ThemeBackgroundColor;
  Font->Color = mSettingsP->ThemeText1Color;
  ListBoxCatalogEntries->Color = mSettingsP->ThemeBackgroundColor;
  CheckBoxReset->Checked = mSettingsP->AutoStartWithReset;

  for (int Loop=0; Loop < ComponentCount; Loop++)
  {
    if (Components[Loop]->Name.Pos("PanelButton") == 1)
    {
      ((TPanel*)Components[Loop])->Color = mSettingsP->ThemeButtonColor;
      ((TPanel*)Components[Loop])->Font->Color = mSettingsP->ThemeButtonTextColor;
    }

  	// Refresh display
		if ( (Visible == true) && (((TControl*)Components[Loop])->Visible == true) )
		{
			((TControl*)Components[Loop])->Invalidate();
		}
	}

	if (mSettingsP->HideAll == false)
  {
    Visible = mSettingsP->DrivesCatalogueFormVisible;
  }
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::FormResize(TObject *Sender)
{
  if ( (Visible == true) && (mSettingsP) )
  {
    mSettingsP->DrivesCatalogueFormWidth = Width;
    mSettingsP->DrivesCatalogueFormHeight = Height;
  }

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::WMMove(TMessage &Message)
{
  if ( (Visible == true) && (mSettingsP) )
  {
    mSettingsP->DrivesCatalogueFormLeft = Left;
    mSettingsP->DrivesCatalogueFormTop = Top;
  }

  NOT_USED(Message);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::FormActivate(TObject *Sender)
{
  if (ListBoxCatalogEntries->Items->Count)
  {
    ActiveControl = ListBoxCatalogEntries;
  }

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::OnDiskEvent(tDrive* DriveP)
{
  if (DriveP->signal_content_change)
  {
    DisplayCatalogue();
  }
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::TabControlCatalogueDrawTab(TCustomTabControl *Control,
          int TabIndex, const TRect &Rect, bool Active)
{
  TCanvas* Canvas = TabControlCatalogue->Canvas;

  if (Active == true)
  {
    Canvas->Font->Color = mSettingsP->ThemeText2Color;
  }
  else
  {
    Canvas->Font->Color = mSettingsP->ThemeText1Color;
  }

  // Draw tab
  Canvas->FillRect(Rect);
  AnsiString Text = TabControlCatalogue->Tabs->Strings[TabIndex];
  int TextWidth = Canvas->TextWidth(Text);
  int TextHeight = Canvas->TextHeight(Text);
  int TextPosX = (Rect.Width() - TextWidth) / 2;
  int TextPosY = (TabControlCatalogue->TabHeight - TextHeight) / 2;
  Canvas->TextOut(Rect.Left+TextPosX, Rect.Top+TextPosY, Text);

  NOT_USED(Control);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::ListBoxCatalogEntriesDrawItem(TWinControl *Control,
          int Index, TRect &Rect, TOwnerDrawState State)
{
  TCanvas* Canvas = ListBoxCatalogEntries->Canvas;

  if (State.Contains(odSelected))
  {
    Canvas->Font->Color = clWhite;
  }
  else
  {
    Canvas->Brush->Color = mSettingsP->ThemeBackgroundColor;
    Canvas->Font->Color = mSettingsP->ThemeText1Color;
  }

  // Draw cell
  Canvas->FillRect(Rect);
  AnsiString Text = ListBoxCatalogEntries->Items->Strings[Index];
  int TextHeight = Canvas->TextHeight(Text);
  int TextPos = (ListBoxCatalogEntries->ItemHeight - TextHeight) / 2;
  Canvas->TextOut(Rect.Left+5, Rect.Top+TextPos, Text);
  if (State.Contains(odFocused))
  {
    Canvas->DrawFocusRect(Rect);
  }

  NOT_USED(Index);
  NOT_USED(Control);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::DisplayCatalogue(void)
{
  // Populate files list
  ListBoxCatalogEntries->Clear();
  mEmulatorP->ReadDiskCatalogue((TabControlCatalogue->TabIndex == 0) ? DriveA : DriveB, (tUChar)mUser);
  for (int Loop=0; Loop < mEmulatorP->NbCatalogEntries; Loop++)
  {
    ListBoxCatalogEntries->Items->Add(mEmulatorP->CatalogEntry[Loop]);
  }

  // Select Autostart entry
  AnsiString AutoStartCommand = mEmulatorP->DetectAutoStart(DriveA, (tUChar)0);
  if (AutoStartCommand.Pos("RUN\"") > 0)
  {
    AnsiString AutoStartEntry = AutoStartCommand.SubString(5, AutoStartCommand.Length() - 5);
    ListBoxCatalogEntries->ItemIndex = ListBoxCatalogEntries->Items->IndexOf(AutoStartEntry);
  }

  if (ListBoxCatalogEntries->Items->Count)
  {
    if (ListBoxCatalogEntries->ItemIndex == -1)
    {
      ListBoxCatalogEntries->ItemIndex = 0;
    }

    PanelButtonRUN->Visible = true;
    PanelButtonLOAD->Visible = true;
  }
  else
  {
    PanelButtonRUN->Visible = false;
    PanelButtonLOAD->Visible = false;
  }
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::TabControlCatalogueChange(TObject *Sender)
{
  DisplayCatalogue();

  if (ListBoxCatalogEntries->Items->Count)
  {
    ActiveControl = ListBoxCatalogEntries;
  }

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::PanelButtonRUNClick(TObject *Sender)
{
  AnsiString Filename = ListBoxCatalogEntries->Items->Strings[ListBoxCatalogEntries->ItemIndex];

  if (CheckBoxReset->Checked == true)
  {
    FormMain->Reset(true);
    mEmulatorP->RestartAutoTypeResetDelay();
  }

  mEmulatorP->RUNFilename(Filename);

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonLOADClick(TObject *Sender)
{
  AnsiString Filename = ListBoxCatalogEntries->Items->Strings[ListBoxCatalogEntries->ItemIndex];
  mEmulatorP->LOADFilename(Filename);

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonCPMClick(TObject *Sender)
{
  if (CheckBoxReset->Checked == true)
  {
    FormMain->Reset(true);
    mEmulatorP->RestartAutoTypeResetDelay();
  }

  mEmulatorP->ExecuteCPM();

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonDriveAClick(TObject *Sender)
{
  mEmulatorP->StartAutoType("|A\n");

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonDriveBClick(TObject *Sender)
{
  mEmulatorP->StartAutoType("|B\n");

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonCATClick(TObject *Sender)
{
  mEmulatorP->StartAutoType("CAT\n");

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonDIRClick(TObject *Sender)
{
  mEmulatorP->StartAutoType("|DIR\n");

  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
{
  ((TPanel*)Sender)->Color = mSettingsP->ThemeButtonTextColor;
  ((TPanel*)Sender)->Font->Color = mSettingsP->ThemeButtonColor;

  NOT_USED(Button);
  NOT_USED(Shift);
  NOT_USED(X);
  NOT_USED(Y);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelButtonMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
{
  ((TPanel*)Sender)->Color = mSettingsP->ThemeButtonColor;
  ((TPanel*)Sender)->Font->Color = mSettingsP->ThemeButtonTextColor;

  NOT_USED(Button);
  NOT_USED(Shift);
  NOT_USED(X);
  NOT_USED(Y);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::PanelFormatUserClick(TObject *Sender)
{
  if (PanelFormatUser->Caption == "")
  {
    PanelFormatUser->Caption = "&&";
    EditUser->Text = AnsiString::IntToHex(mUser, 2);
  }
  else
  {
    PanelFormatUser->Caption = "";
    EditUser->Text = mUser;
  }

  EditUser->SetFocus();
  EditUser->SelectAll();

	NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormDrivesCatalogue::EditUserChange(TObject *Sender)
{
  if (EditUser->Text.Length() > 0)
  {
    try
    {
      if (PanelFormatUser->Caption == "")
      {
        mUser = EditUser->Text.ToInt();
      }
      else
      {
        mUser = StrToInt("0x" + EditUser->Text);
      }

      DisplayCatalogue();
    }
    catch (...)
    {
      mUser = 0;
    }
  }
  else
  {
    // Clear catalogue
    ListBoxCatalogEntries->Clear();
  }

	NOT_USED(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TFormDrivesCatalogue::CheckBoxResetClick(TObject *Sender)
{
  if (mSettingsP)
  {
    mSettingsP->AutoStartWithReset = CheckBoxReset->Checked;
  }

	NOT_USED(Sender);
}
//---------------------------------------------------------------------------

