/*
 CaPriCe Forever - Amstrad CPC 464/664/6128 emulator
 Copyright (C) 2014-2018 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>
#include <Clipbrd.hpp>
#include <tchar.h>
#pragma hdrstop
#include "TFormFilesManager.h"
#include "TFormDSKViewer.h"
#include "TFormMain.h"
#include "..\..\Common\ASCII.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"


//=================================
// Options

#undef SHOW_ASCII
#define SHOW_ASCII

//=================================


static const AnsiString cTitle = "Files manager";

static const AnsiString cDriveALabel = "Drive A";
static const AnsiString cDriveBLabel = "Drive B";


#define COLOR_USED                  clWhite
#define COLOR_EMPTY                 clLtGray
#define COLOR_CATALOGUE             clYellow
#define COLOR_ENTRY_FIRST_SECTOR    TColor(RGB(255,128,240)) // Pastel Pink
#define COLOR_ENTRY_NEXT_SECTOR     TColor(RGB(255,170,35))  // Pastel Orange
#define COLOR_SIDE_1                clAqua
#define COLOR_SIDE_2                clLime


const AnsiString USEDSectorLabel = "USED";
const AnsiString EMPTYSectorLabel = "EMPTY";
const AnsiString CATALOGUESectorLabel = "CATALOGUE";
const AnsiString FIRSTSectorLabel = "FIRST SECTOR";
const AnsiString NEXTSectorLabel = "NEXT SECTOR";


TFormFilesManager *FormFilesManager;
//---------------------------------------------------------------------------
__fastcall TFormFilesManager::TFormFilesManager(TComponent* Owner)
  : TForm(Owner)
{
  mEmulatorP = NULL;
  mSettingsP = NULL;
  mStartDriveP = NULL;

  DoubleBuffered = true;
  StringGridSectors->DoubleBuffered = true;

  CheckBoxKeepHeader->Checked = true;

  mDiskOperationP = new tDiskOperation();
  memset(mDiskOperationP, 0, sizeof(tDiskOperation));
  ComboBoxFileSystem->ItemIndex = 0;

  mSelectedEntryCHRNList = new TList();
  mCatalogueCHRNList = new TList();

  LabelFileSystem->Height = ComboBoxFileSystem->Height;

  // Apply Theme
  Font->Name = "Amstrad CPC464 Regular";
  Font->Size = 6;
  PanelSectorState->Font->Color = clBlack;
}
//---------------------------------------------------------------------------
void __fastcall TFormFilesManager::FormDestroy(TObject *Sender)
{
  delete mDiskOperationP;
  delete mSelectedEntryCHRNList;
  delete mCatalogueCHRNList;

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


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

	FormMain->OnFilesManagerFormShow();

	// Allow files Drag and Drop
	DragAcceptFiles(Handle, true);

  Caption = Title;
  mDiskViewerSynchro = false;

  CheckBoxKeepHeader->Visible = false;
  PanelButtonAdd->Visible = false;
  PanelButtonDelete->Visible = false;
  PanelButtonExport->Visible = false;
  PanelButtonCopy->Visible = false;
  LabelFileSystem->Visible = false;
  ComboBoxFileSystem->Visible = false;

  memset(mDiskOperationP, 0, sizeof(tDiskOperation));
  ComboBoxFileSystem->ItemIndex = 0;

  // Force display update
  FormMain->NativeCPC->FDC->DriveA->signal_content_change++;
  OnDiskEvent(FormMain->NativeCPC->FDC->DriveA);

  if (mStartDriveP != NULL)
  {
    if (mStartDriveP == FormMain->NativeCPC->FDC->DriveA)
    {
      ComboBoxDrive->ItemIndex = ComboBoxDrive->Items->IndexOf(cDriveALabel);
    }
    else if (mStartDriveP == FormMain->NativeCPC->FDC->DriveB)
    {
      ComboBoxDrive->ItemIndex = ComboBoxDrive->Items->IndexOf(cDriveBLabel);
    }

    mStartDriveP = NULL;

    if (ComboBoxDrive->ItemIndex != -1)
    {
      ShowDriveContent();
    }
  }

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

  if (mSettingsP)
  {
    mSettingsP->FilesManagerFormVisible = true;

    // Reset Disk viewer button state
    PanelButtonViewer->Color = mSettingsP->ThemeButtonColor;
    PanelButtonViewer->Font->Color = mSettingsP->ThemeButtonTextColor;
  }

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


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

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

  //DragAcceptFiles(PageControlData->Handle, false);
  DragAcceptFiles(Handle, false);

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


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

  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ? FormMain->NativeCPC->FDC->DriveA : FormMain->NativeCPC->FDC->DriveB;
  if (DriveP)
  {
    if (DriveP->tracks)
    {
      if (ComboBoxDrive->Text == cDriveALabel)
      {
        Title += " - " + ExtractFileName(mEmulatorP->DiskAFilename);
      }
      else
      {
        Title += " - " + ExtractFileName(mEmulatorP->DiskBFilename);
      }
    }
  }

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


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

  if (    (mSettingsP->FilesManagerFormLeft != 0)
       || (mSettingsP->FilesManagerFormTop != 0)
       || (mSettingsP->FilesManagerFormWidth != 0)
       || (mSettingsP->FilesManagerFormHeight != 0) )
  {
    Position = poDesigned;
    Left = mSettingsP->FilesManagerFormLeft;
    Top = mSettingsP->FilesManagerFormTop;
    Width = mSettingsP->FilesManagerFormWidth;
    Height = mSettingsP->FilesManagerFormHeight;
  }

	// Apply theme
	Color = mSettingsP->ThemeBackgroundColor;
	ListBoxCatalogueEntries->Color = mSettingsP->ThemeBackgroundColor;
	Font->Color = mSettingsP->ThemeText1Color;
	StringGridSectors->Color = Color;
	tULong Threshold = (((Color & 0xff0000) >> 16) + ((Color & 0xff00) >> 8) + (Color & 0xff)) / 3;
	if (Threshold >= 0x80)
	{
		Threshold = 0x40;
	}
	else
	{
		Threshold = 0xC0;
	}
	mCellFrameColor = TColor((Threshold << 16) | (Threshold << 8) | Threshold);

	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;
		}
		else if (Components[Loop]->Name.Pos("Label") == 1)
		{
			((TLabel*)Components[Loop])->Font->Color = mSettingsP->ThemeText1Color;
		}

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

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


void __fastcall TFormFilesManager::FormResize(TObject *Sender)
{
  if ( (Visible == true) && (mSettingsP) )
  {
    mSettingsP->FilesManagerFormWidth = Width;
    mSettingsP->FilesManagerFormHeight = Height;
  }

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


void __fastcall TFormFilesManager::WMMove(TMessage &Message)
{
  if ( (Visible == true) && (mSettingsP) )
  {
    mSettingsP->FilesManagerFormLeft = Left;
    mSettingsP->FilesManagerFormTop = Top;
  }

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


void __fastcall TFormFilesManager::OnDiskEvent(tDrive* DriveP)
{
  tDrive* DisplayedDrive = NULL;
  if (ComboBoxDrive->Text == cDriveALabel) DisplayedDrive = FormMain->NativeCPC->FDC->DriveA;
  if (ComboBoxDrive->Text == cDriveBLabel) DisplayedDrive = FormMain->NativeCPC->FDC->DriveB;

  if ( (DriveP->signal_track_format) || (DriveP->signal_sector_write) )
  {
    if (DisplayedDrive == DriveP)
    {
      // Update graphic
      ShowDriveContent();
    }
  }

  if (DriveP->signal_content_change)
  {
    // Check available DSK
    ComboBoxDrive->Clear();
    if (FormMain->NativeCPC->FDC->DriveA->dataP != NULL) ComboBoxDrive->Items->Add(cDriveALabel);
    if (FormMain->NativeCPC->FDC->DriveB->dataP != NULL) ComboBoxDrive->Items->Add(cDriveBLabel);

    // No drives available
    if (ComboBoxDrive->Items->Count == 0)
    {
      ComboBoxDrive->Enabled = false;
      ComboBoxSides->Clear();
      ListBoxCatalogueEntries->Clear();
      Caption = Title;
      StringGridSectors->Visible = false;
      PanelSectorState->Visible = false;
      PanelButtonSectorViewExtent->Visible = false;
      ComboBoxSides->Enabled = false;
      ComboBoxFileSystem->Visible = false;
      LabelFileSystem->Visible = false;
      PanelFreeSpace->Visible = false;
      PanelButtonViewer->Visible = false;
      PanelButtonPreviousSector->Visible = false;
      PanelButtonNextSector->Visible = false;
      CheckBoxKeepHeader->Visible = false;
      PanelButtonAdd->Visible = false;
      PanelButtonDelete->Visible = false;
      PanelButtonExport->Visible = false;
      PanelButtonCopy->Visible = false;
      LabelFileSystem->Visible = false;
      ComboBoxFileSystem->Visible = false;
    }
    else
    {
      if (ComboBoxDrive->Items->Count == 1)
      {
        ComboBoxDrive->ItemIndex = 0;
        ComboBoxDrive->Enabled = false;
      }
      else
      {
        ComboBoxDrive->Enabled = true;
        if (DisplayedDrive == FormMain->NativeCPC->FDC->DriveB)
        {
          ComboBoxDrive->ItemIndex = 1;
        }
        else
        {
          ComboBoxDrive->ItemIndex = 0;
        }
      }

      if ( (DisplayedDrive == DriveP) || (DisplayedDrive == NULL) )
      {
        ComboBoxSides->Clear();
        ListBoxCatalogueEntries->Clear();

        memset(mDiskOperationP, 0, sizeof(tDiskOperation));
        ComboBoxFileSystem->ItemIndex = 0;
        ShowDriveContent();
      }

      if (ComboBoxDrive->Items->Count == 1)
      {
        PanelButtonCopy->Visible = false;
      }
      else
      {
        PanelButtonCopy->Visible = (ListBoxCatalogueEntries->ItemIndex != -1) ? true : false;
      }
    }
  }
}
//---------------------------------------------------------------------------


void __fastcall TFormFilesManager::ComboBoxDriveChange(TObject *Sender)
{
  memset(mDiskOperationP, 0, sizeof(tDiskOperation));
  ComboBoxFileSystem->ItemIndex = 0;
  ShowDriveContent();

  if (mDiskViewerSynchro == true)
  {
    tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
              FormMain->NativeCPC->FDC->DriveA :
              FormMain->NativeCPC->FDC->DriveB;

    FormDSKViewer->SelectSector(DriveP,
                                mCurrentSide,
                                StringGridSectors->Col,
                                StringGridSectors->Row);
  }

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

void __fastcall TFormFilesManager::ComboBoxDriveDrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State)
{
  TCanvas* Canvas = ComboBoxDrive->Canvas;

  if (State.Contains(odSelected))
  {
    Canvas->Brush->Color = clHighlight;
    Canvas->Font->Color = clWhite;
  }
  else
  {
    Canvas->Brush->Color = clWhite;
    Canvas->Font->Color = clBlack;
  }

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

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


void __fastcall TFormFilesManager::ComboBoxSidesChange(TObject *Sender)
{
  mCurrentSide = ComboBoxSides->ItemIndex;

  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
          FormMain->NativeCPC->FDC->DriveA :
          FormMain->NativeCPC->FDC->DriveB;

  if (DriveP->sides && DriveP->flipped)
  {
    mCurrentSide ^= 1;
  }

  ShowSideContent(0);

  if ( (mDiskViewerSynchro == true) && (Sender != NULL) )
  {
    FormDSKViewer->SelectSector(DriveP,
                                mCurrentSide,
                                StringGridSectors->Col,
                                StringGridSectors->Row);
  }

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

void __fastcall TFormFilesManager::ComboBoxSidesDrawItem(TWinControl *Control, int Index,
          TRect &Rect, TOwnerDrawState State)
{
  TCanvas* Canvas = ComboBoxSides->Canvas;

  if (State.Contains(odSelected))
  {
    Canvas->Brush->Color = clHighlight;
    Canvas->Font->Color = clWhite;
  }
  else
  {
    // Side color
    Canvas->Brush->Color = (Index == 0) ? COLOR_SIDE_1 : COLOR_SIDE_2;
    Canvas->Font->Color = clBlack;
  }

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

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


void __fastcall TFormFilesManager::ComboBoxFileSystemChange(
      TObject *Sender)
{
  if (ComboBoxFileSystem->ItemIndex >= 1)
  {
    memset(mDiskOperationP, 0, sizeof(tDiskOperation));
    mDiskOperationP->FormatType = ComboBoxFileSystem->ItemIndex;
  }
  else
  {
    // Detect filesystem
    memset(mDiskOperationP, 0, sizeof(tDiskOperation));
    mDiskOperationP->Drive = (ComboBoxDrive->Text == cDriveALabel) ?
                             FormMain->NativeCPC->FDC->DriveA : FormMain->NativeCPC->FDC->DriveB;
    (void)mEmulatorP->ReadDiskCatalogue(mDiskOperationP);
    ComboBoxFileSystem->ItemIndex = mDiskOperationP->FormatType;
  }

  // Update drive content
  ShowDriveContent();
  
  NOT_USED(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TFormFilesManager::ComboBoxFileSystemDrawItem(
      TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State)
{
  TCanvas* Canvas = ComboBoxFileSystem->Canvas;

  if (State.Contains(odSelected))
  {
    Canvas->Brush->Color = clHighlight;
    Canvas->Font->Color = clWhite;
  }
  else
  {
    Canvas->Brush->Color = (Index == 0) ? clRed : clWhite;
    Canvas->Font->Color = (Index == 0) ? clWhite : clBlack;
  }

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

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


void __fastcall TFormFilesManager::ShowDriveContent(void)
{
  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
                   FormMain->NativeCPC->FDC->DriveA :
                   FormMain->NativeCPC->FDC->DriveB;

  if (DriveP->tracks)
  {
    Caption = Title;
    PanelButtonViewer->Visible = true;
    LabelFileSystem->Visible = true;
    ComboBoxFileSystem->Visible = true;
    CheckBoxKeepHeader->Visible = true;
    PanelButtonAdd->Visible = true;
    PanelButtonDelete->Visible = false;
    PanelButtonExport->Visible = false;
    PanelButtonCopy->Visible = false;

    if (StringGridSectors->Col > (int)DriveP->tracks)
    {
      StringGridSectors->Col = 0;
    }

    // Update sides
    if ( ((int)(DriveP->sides+1) != ComboBoxSides->Items->Count)
         || (StringGridSectors->Col == 0) )
    {
      ComboBoxSides->Clear();
      for (int Loop=0; Loop < (int)(DriveP->sides+1); Loop++)
      {
        AnsiString SideTitle = "Side " + AnsiString(Loop+1);
        ComboBoxSides->Items->Add(SideTitle);
      }
      mCurrentSide = 0;
    }
    ComboBoxSides->ItemIndex = mCurrentSide;
    ComboBoxSides->Enabled = (ComboBoxSides->Items->Count > 1) ? true : false;

    if (DriveP->sides && DriveP->flipped)
    {
      mCurrentSide ^= 1;
    }

    //
    // Show Catalog
    //
    // Clear list of sectors
    mSelectedEntryCHRNList->Clear();
    memset(mDiskOperationP, 0, sizeof(tDiskOperation));
    mDiskOperationP->FormatType = ComboBoxFileSystem->ItemIndex;
    mDiskOperationP->Drive = (ComboBoxDrive->Text == cDriveALabel) ?
                             FormMain->NativeCPC->FDC->DriveA : FormMain->NativeCPC->FDC->DriveB;
    int NbCatalogEntries = mEmulatorP->ReadDiskCatalogue(mDiskOperationP);
    ListBoxCatalogueEntries->Clear();
    if (NbCatalogEntries)
    {
      for (int Loop=0; Loop < NbCatalogEntries; Loop++)
      {
        AnsiString Entry = (char*)mDiskOperationP->CatalogueEntries[Loop];
        AnsiString Filename = Entry.SubString(1, 8).Trim();
        if (Filename.Length() > 0)
        {
          AnsiString Extension = Entry.SubString(9, 3).Trim();
          // Add User + filename
          Entry = AnsiString::IntToHex(mDiskOperationP->CatalogueEntryUser[Loop], 2) + ": " + Filename;
          if (Extension.Length() > 0)
          {
            Entry += "." + Extension;
          }

          // Add spaces before size
          for (int Loop=Entry.Length(); Loop < 17; Loop++)
          {
            Entry += " ";
          }

          // Add Size
          int EntrySize = mDiskOperationP->CatalogueEntrySize[Loop] / 1024;
          if (mDiskOperationP->CatalogueEntrySize[Loop] & 1023)
          {
            EntrySize++;
          }
          Entry += AnsiString(EntrySize) + "K";

          ListBoxCatalogueEntries->Items->Add(Entry);
        }
      }
    }

    ComboBoxFileSystem->ItemIndex = mDiskOperationP->FormatType;

    // Populate catalogue sectors list
    mCatalogueCHRNList->Clear();
    tULong CHRN = mEmulatorP->GetCatalogueFirstSector(mDiskOperationP);
    if (CHRN)
    {
      mCatalogueCHRNList->Add((void*)CHRN);

      do
      {
        CHRN = mEmulatorP->GetCatalogueNextSector(mDiskOperationP);
        if (CHRN)
        {
          mCatalogueCHRNList->Add((void*)CHRN);
        }
      }
      while (CHRN);
    }

    ShowSideContent(StringGridSectors->Col);

    // Show Free space
    AnsiString FreeSpace = "Free: ";
    FreeSpace += (mEmulatorP->GetDiskFreeSpace(mDiskOperationP) / 1024);
    FreeSpace += "K";
    PanelFreeSpace->Caption = FreeSpace;
    PanelFreeSpace->Visible = true;
  }
  else
  {
    // Not formatted disk
    StringGridSectors->Visible = false;
    PanelSectorState->Visible = false;
    PanelButtonSectorViewExtent->Visible = false;
    PanelFreeSpace->Visible = false;
    CheckBoxKeepHeader->Visible = false;
    PanelButtonAdd->Visible = false;
    PanelButtonDelete->Visible = false;
    PanelButtonExport->Visible = false;
    PanelButtonCopy->Visible = false;
    LabelFileSystem->Visible = false;
    ComboBoxFileSystem->Visible = false;
  }
}
//---------------------------------------------------------------------------


void __fastcall TFormFilesManager::ShowSideContent(int TrackSelected)
{
tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
            FormMain->NativeCPC->FDC->DriveA :
            FormMain->NativeCPC->FDC->DriveB;

  StringGridSectors->Visible = true;
  PanelSectorState->Visible = true;
  PanelButtonSectorViewExtent->Visible = true;
  StringGridSectors->ColCount = DriveP->tracks;

  tULong NbMaxSectors = 0;

  for (tULong Loop=0; Loop < DriveP->tracks; Loop++)
  {
    StringGridSectors->Cells[Loop][0] = AnsiString(Loop);
    if (DriveP->track[Loop]->sectors > NbMaxSectors)
    {
      NbMaxSectors = DriveP->track[Loop][mCurrentSide].sectors;
    }
  }

  StringGridSectors->RowCount = NbMaxSectors + 1; // Add header row
  StringGridSectors->Col = TrackSelected;
  if ( ((int)DriveP->current_track == TrackSelected)
       && (StringGridSectors->RowCount > 1) )
  {
    StringGridSectors->Row = 1;
  }

  // Any sectors ?
  if (StringGridSectors->RowCount > 1)
  {
    ShowSectorInfo(StringGridSectors->Col, StringGridSectors->Row - 1);

    if (StringGridSectors->Enabled == true)
    {
      ActiveControl = StringGridSectors;
      StringGridSectors->Invalidate();
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TFormFilesManager::StringGridSectorsDrawCell(TObject *Sender,
    int ACol, int ARow, TRect &Rect, TGridDrawState State) 
{
  TRect CellRect;
#if (__BORLANDC__ == 0x651)
  CellRect.Left = Rect.Left + 1 - 4; // Fix Left issue with RADStudio XE3
#else /* __BORLANDC__ */
  CellRect.Left = Rect.Left + 1;
#endif /* __BORLANDC__ */
  CellRect.Right = Rect.Right - 1;
  CellRect.Top = Rect.Top + 1;
  CellRect.Bottom = Rect.Bottom - 1;

  // Draw headers ?
  if (ARow == 0)
  {
    // Side color
    StringGridSectors->Canvas->Brush->Color = (mCurrentSide == 0) ? COLOR_SIDE_1 : COLOR_SIDE_2;
    StringGridSectors->Canvas->Font->Color = clBlack;
    StringGridSectors->Canvas->FillRect(CellRect);
    
    String CellText = StringGridSectors->Cells[ACol][ARow];
    int TextWidth = StringGridSectors->Canvas->TextWidth(CellText);
    int TextPosH = (StringGridSectors->ColWidths[ACol] - TextWidth) / 2;
    int TextHeight = StringGridSectors->Canvas->TextHeight(CellText);
    int TextPosV = (StringGridSectors->RowHeights[ARow] - TextHeight) / 2;
    StringGridSectors->Canvas->TextOut(CellRect.Left + TextPosH - 1,
        CellRect.Top + TextPosV, CellText);
  }
  else
  {
    // Selected cell ?
    if (State.Contains(gdSelected))
    {
      StringGridSectors->Canvas->Brush->Color = clHighlight;
      StringGridSectors->Canvas->FillRect(CellRect);
    }
    else
    {
      tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
                FormMain->NativeCPC->FDC->DriveA :
                FormMain->NativeCPC->FDC->DriveB;
      tTrack* CurrentTrack = &DriveP->track[ACol][mCurrentSide];

      if (ARow <= (int)CurrentTrack->sectors)
      {
        tSector* SectorP = &CurrentTrack->sector[ARow-1];
        
        tULong CHRN = SectorP->CHRN[0] << 24;
        CHRN |= SectorP->CHRN[1] << 16;
        CHRN |= SectorP->CHRN[2] << 8;
        CHRN |= SectorP->CHRN[3] << 0;
        bool Catalogue = false;
        for (int Loop=0; Loop < mCatalogueCHRNList->Count; Loop++)
        {
          if (CHRN == (tULong)mCatalogueCHRNList->Items[Loop])
          {
            Catalogue = true;
            break;
          }
        }
        bool SelectedSector = false;
        bool FirstSector = false;
        for (int Loop=0; Loop < mSelectedEntryCHRNList->Count; Loop++)
        {
          if (CHRN == (tULong)mSelectedEntryCHRNList->Items[Loop])
          {
            SelectedSector = true;
            FirstSector = (Loop == 0) ? true : false;
            break;
          }
        }

        if (Catalogue == true)
        {
          StringGridSectors->Canvas->Brush->Color = COLOR_CATALOGUE;
        }
        else if (SelectedSector == true)
        {
          if (FirstSector == true)
          {
            StringGridSectors->Canvas->Brush->Color = COLOR_ENTRY_FIRST_SECTOR;
          }
          else
          {
            StringGridSectors->Canvas->Brush->Color = COLOR_ENTRY_NEXT_SECTOR;
          }
        }
        else if (SectorP->empty == cTrue)
        {
          StringGridSectors->Canvas->Brush->Color = COLOR_EMPTY;
        }
        else
        {
          StringGridSectors->Canvas->Brush->Color = COLOR_USED;
        }

        StringGridSectors->Canvas->FillRect(CellRect);

        // Draw border
        StringGridSectors->Canvas->Brush->Color = mCellFrameColor;
        StringGridSectors->Canvas->FrameRect(CellRect);
      }
    }
  }

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

void __fastcall TFormFilesManager::StringGridSectorsSelectCell(
      TObject *Sender, int ACol, int ARow, bool &CanSelect)
{
  if (StringGridSectors->Focused() == true)
  {
    tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
              FormMain->NativeCPC->FDC->DriveA :
              FormMain->NativeCPC->FDC->DriveB;
    tTrack* TrackP = &DriveP->track[ACol][mCurrentSide];

    // Header selected ?
    if (ARow == 0)
    {
      CanSelect = false;
      return;
    }

    // Show Sector info
    if (ARow <= (int)TrackP->sectors)
    {
      PanelSectorState->Visible = true;
      PanelButtonSectorViewExtent->Visible = true;
      ShowSectorInfo(ACol, ARow - 1);
    }
    else
    {
      PanelSectorState->Visible = false;
      PanelButtonSectorViewExtent->Visible = false;
    }

    if (mDiskViewerSynchro == true)
    {
      FormDSKViewer->SelectSector(DriveP, mCurrentSide, ACol, ARow);
    }
  }

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


void __fastcall TFormFilesManager::ShowSectorInfo(int TrackNumber, int SectorNumber)
{
  bool PreviousSector = false;
  bool NextSector = false;

  if (StringGridSectors->Visible == true)
  {
    tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
              FormMain->NativeCPC->FDC->DriveA :
              FormMain->NativeCPC->FDC->DriveB;
    tTrack* TrackP = &DriveP->track[TrackNumber][mCurrentSide];
    tSector* SectorP = &TrackP->sector[SectorNumber];

    tULong CHRN = SectorP->CHRN[0] << 24;
    CHRN |= SectorP->CHRN[1] << 16;
    CHRN |= SectorP->CHRN[2] << 8;
    CHRN |= SectorP->CHRN[3] << 0;
    bool Catalogue = false;
    for (int Loop=0; Loop < mCatalogueCHRNList->Count; Loop++)
    {
      if (CHRN == (tULong)mCatalogueCHRNList->Items[Loop])
      {
        Catalogue = true;
        break;
      }
    }
    bool SelectedSector = false;
    bool FirstSector = false;
    for (int Loop=0; Loop < mSelectedEntryCHRNList->Count; Loop++)
    {
      if (CHRN == (tULong)mSelectedEntryCHRNList->Items[Loop])
      {
        SelectedSector = true;
        FirstSector = (Loop == 0) ? true : false;
        if (Loop > 0)
        {
          PreviousSector = true;
        }
        if (Loop < (mSelectedEntryCHRNList->Count - 1))
        {
          NextSector = true;
        }
        break;
      }
    }

    //
    // Show sector state
    //
    PanelSectorState->Visible = true;
    PanelButtonSectorViewExtent->Visible = true;
    if (SectorP->empty == cTrue)
    {
      PanelSectorState->Color = COLOR_EMPTY;
      PanelSectorState->Caption = EMPTYSectorLabel;
    }
    else if (Catalogue == true)
    {
      PanelSectorState->Color = COLOR_CATALOGUE;
      PanelSectorState->Caption = CATALOGUESectorLabel;
    }
    else if (SelectedSector == true)
    {
      if (FirstSector == true)
      {
        PanelSectorState->Color = COLOR_ENTRY_FIRST_SECTOR;
        PanelSectorState->Caption = FIRSTSectorLabel;
      }
      else
      {
        PanelSectorState->Color = COLOR_ENTRY_NEXT_SECTOR;
        PanelSectorState->Caption = NEXTSectorLabel;
      }
    }
    else
    {
      PanelSectorState->Color = COLOR_USED;
      PanelSectorState->Caption = USEDSectorLabel;
    }
  }

  // Update controls
  PanelButtonPreviousSector->Visible = PreviousSector;
  PanelButtonNextSector->Visible = NextSector;
}
//---------------------------------------------------------------------------

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

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

  // Get sheet corresponding to TabIndex
  int TabCount=0;
  for (int Loop=0; Loop < PageControlData->PageCount; Loop++)
  {
    if (PageControlData->Pages[Loop]->TabVisible == true)
    {
      if (TabCount == TabIndex)
      {
        // Draw tab
        TTabSheet* Sheet = PageControlData->Pages[Loop];
        Canvas->FillRect(Rect);
        AnsiString Text = Sheet->Caption;
        int TextWidth = Canvas->TextWidth(Text);
        int TextHeight = Canvas->TextHeight(Text);
        int TextPosX = (Rect.Width() - TextWidth) / 2;
        int TextPosY = (PageControlData->TabHeight - TextHeight) / 2;
        Canvas->TextOut(Rect.Left+TextPosX, Rect.Top+TextPosY, Text);
        break;
      }

      TabCount++;
    }
  }

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


void __fastcall TFormFilesManager::ListBoxCatalogueEntriesDrawItem(TWinControl *Control,
          int Index, TRect &Rect, TOwnerDrawState State)
{
  TCanvas* Canvas = ListBoxCatalogueEntries->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 = ListBoxCatalogueEntries->Items->Strings[Index];
  int TextPos = (ListBoxCatalogueEntries->ItemHeight - Canvas->TextHeight(Text)) / 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 TFormFilesManager::ListBoxCatalogueEntriesClick(
      TObject *Sender)
{
  // Clear list of sectors
  mSelectedEntryCHRNList->Clear();

  // Populate sectors list
  mDiskOperationP->CatalogueEntryIndex = ListBoxCatalogueEntries->ItemIndex;
  if (mDiskOperationP->CatalogueEntrySize[mDiskOperationP->CatalogueEntryIndex] > 0)
  {
    tULong CHRN = mEmulatorP->GetCatalogueEntryFirstSector(mDiskOperationP);
    if (CHRN)
    {
      // CHRN already exists ?
      if (mSelectedEntryCHRNList->IndexOf((void*)CHRN) != -1)
      {
        // Clear list of sectors
        mSelectedEntryCHRNList->Clear();
      }
      else
      {
        mSelectedEntryCHRNList->Add((void*)CHRN);

        do
        {
          CHRN = mEmulatorP->GetCatalogueEntryNextSector(mDiskOperationP);
          if (CHRN)
          {
            // CHRN already exists ?
            if (mSelectedEntryCHRNList->IndexOf((void*)CHRN) != -1)
            {
              // Clear list of sectors
              mSelectedEntryCHRNList->Clear();
              CHRN = 0L;
            }
            else
            {
              mSelectedEntryCHRNList->Add((void*)CHRN);
            }
          }
        }
        while (CHRN);
      }
    }
  }

  // Select first sector
  if (mSelectedEntryCHRNList->Count > 0)
  {
    SelectSector((tULong)mSelectedEntryCHRNList->Items[0]);
  }

  // Refresh display
  StringGridSectors->Invalidate();
  ShowSectorInfo(StringGridSectors->Col, StringGridSectors->Row - 1);

  // Update control accesses
  CheckBoxKeepHeader->Visible = true;
  PanelButtonAdd->Visible = true;
  PanelButtonDelete->Visible = true;
  PanelButtonExport->Visible = true;
  PanelButtonCopy->Visible = (ComboBoxDrive->Items->Count == 2) ? true : false;
  LabelFileSystem->Visible = true;
  ComboBoxFileSystem->Visible = true;

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

void __fastcall TFormFilesManager::PanelButtonViewerClick(TObject *Sender)
{
  // Change state
  mDiskViewerSynchro = (mDiskViewerSynchro == false) ? true : false;

  if (mDiskViewerSynchro == true)
  {
    // Refresh display
    PanelButtonViewer->Color = mSettingsP->ThemeButtonTextColor;
    PanelButtonViewer->Font->Color = mSettingsP->ThemeButtonColor;

    tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
              FormMain->NativeCPC->FDC->DriveA :
              FormMain->NativeCPC->FDC->DriveB;

    // Show Disk viewer
	  FormDSKViewer->Visible = true;
    FormDSKViewer->SelectSector(DriveP,
                                mCurrentSide,
                                StringGridSectors->Col,
                                StringGridSectors->Row);
  }
  else
  {
    // Refresh display
    PanelButtonViewer->Color = mSettingsP->ThemeButtonColor;
    PanelButtonViewer->Font->Color = mSettingsP->ThemeButtonTextColor;
  }

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


void __fastcall TFormFilesManager::SelectSector(tULong CHRN)
{
  tUChar Cylinder = (CHRN >> 24) & 0xff;
  tUChar Head     = (CHRN >> 16) & 0xff;

  // Look for sector CHRN
  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
            FormMain->NativeCPC->FDC->DriveA :
            FormMain->NativeCPC->FDC->DriveB;
  tTrack* CurrentTrack = &DriveP->track[Cylinder][Head];
  for (tULong sectorLoop=0; sectorLoop < CurrentTrack->sectors; sectorLoop++)
  {
    tSector* SectorP = &CurrentTrack->sector[sectorLoop];
    tULong sectorCHRN = SectorP->CHRN[0] << 24;
    sectorCHRN |= SectorP->CHRN[1] << 16;
    sectorCHRN |= SectorP->CHRN[2] << 8;
    sectorCHRN |= SectorP->CHRN[3] << 0;

    // Sector found ?
    if (sectorCHRN == CHRN)
    {
      // Select side
      if (mCurrentSide != Head)
      {
        mCurrentSide = Head;
        ComboBoxSides->ItemIndex = mCurrentSide;
        ComboBoxSidesChange(NULL);
      }

      // Select sector
      StringGridSectors->Col = Cylinder;
      StringGridSectors->Row = sectorLoop + 1;

      PanelSectorState->Visible = true;
      PanelButtonSectorViewExtent->Visible = true;
      ShowSectorInfo(StringGridSectors->Col, StringGridSectors->Row - 1);

      if (mDiskViewerSynchro == true)
      {
        FormDSKViewer->SelectSector(DriveP, mCurrentSide, StringGridSectors->Col, StringGridSectors->Row);
      }

      break;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TFormFilesManager::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 TFormFilesManager::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 TFormFilesManager::PanelButtonPreviousSectorClick(TObject *Sender)

{
  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
            FormMain->NativeCPC->FDC->DriveA :
            FormMain->NativeCPC->FDC->DriveB;
  tTrack* TrackP = &DriveP->track[StringGridSectors->Col][mCurrentSide];
  tSector* SectorP = &TrackP->sector[StringGridSectors->Row-1];

  tULong CHRN = SectorP->CHRN[0] << 24;
  CHRN |= SectorP->CHRN[1] << 16;
  CHRN |= SectorP->CHRN[2] << 8;
  CHRN |= SectorP->CHRN[3] << 0;

  for (int Loop=0; Loop < mSelectedEntryCHRNList->Count; Loop++)
  {
    if (CHRN == (tULong)mSelectedEntryCHRNList->Items[Loop])
    {
      // Select next sector
      SelectSector((tULong)mSelectedEntryCHRNList->Items[Loop-1]);
      break;
    }
  }

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

void __fastcall TFormFilesManager::PanelButtonNextSectorClick(TObject *Sender)
{
  tDrive* DriveP = (ComboBoxDrive->Text == cDriveALabel) ?
            FormMain->NativeCPC->FDC->DriveA :
            FormMain->NativeCPC->FDC->DriveB;
  tTrack* TrackP = &DriveP->track[StringGridSectors->Col][mCurrentSide];
  tSector* SectorP = &TrackP->sector[StringGridSectors->Row-1];

  tULong CHRN = SectorP->CHRN[0] << 24;
  CHRN |= SectorP->CHRN[1] << 16;
  CHRN |= SectorP->CHRN[2] << 8;
  CHRN |= SectorP->CHRN[3] << 0;

  for (int Loop=0; Loop < mSelectedEntryCHRNList->Count; Loop++)
  {
    if (CHRN == (tULong)mSelectedEntryCHRNList->Items[Loop])
    {
      // Select next sector
      SelectSector((tULong)mSelectedEntryCHRNList->Items[Loop+1]);
      break;
    }
  }

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


void __fastcall TFormFilesManager::PanelButtonExportClick(TObject *Sender)
{
  // Create filename
  AnsiString Entry = (char*)mDiskOperationP->CatalogueEntries[mDiskOperationP->CatalogueEntryIndex];
  AnsiString Filename = Entry.SubString(1, 8).Trim();
  AnsiString Extension = Entry.SubString(9, 3).Trim();
  if (Extension.Length() > 0)
  {
    Filename += "." + Extension;
  }

  // Prepare export
  SaveDialogFile->FileName = Filename;
  SaveDialogFile->InitialDir = mSettingsP->DiscDirectory;
  if (SaveDialogFile->Execute() == true)
  {
    // Export file
    if (mEmulatorP->ExportFile(mDiskOperationP,
                               SaveDialogFile->FileName,
                               CheckBoxKeepHeader->Checked) == false)
    {
      Application->MessageBox(_T("Problems while exporting file."),
                              _T("Error"),
                              MB_OK | MB_ICONEXCLAMATION);
    }
  }

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


void __fastcall TFormFilesManager::PanelButtonAddClick(TObject *Sender)
{
  // Prepare add
  OpenDialogFile->InitialDir = mSettingsP->DiscDirectory;
  if (OpenDialogFile->Execute() == true)
  {
    AddFile(OpenDialogFile->FileName);
  }

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

void __fastcall TFormFilesManager::AddFile(AnsiString Filename)
{
  // Read file
  tUChar* FileDataP = NULL;
  int FileSize = 0;
  int iFileHandle = FileOpen(Filename, fmOpenRead | fmShareDenyNone);
  if (iFileHandle != -1)
  {
    // Get file size
    FileSize = FileSeek(iFileHandle, 0, 2);
    FileSeek(iFileHandle, 0, 0); // Back to beginning of the file.

    // Allocate memory and read entire file.
    FileDataP = new tUChar[FileSize];
    FileRead(iFileHandle, FileDataP, FileSize);
    FileClose(iFileHandle);
  }

  if (FileSize > 0)
  {
    // Read file header
    tFileHeader FileHeader;
    if (mEmulatorP->ReadFileHeader(FileDataP, FileSize, &FileHeader) == true)
    {
      if (CheckBoxKeepHeader->Checked == false)
      {
        // Remove header.
        FileSize -= AMSDOS_HEADER_SIZE;
        FileDataP += AMSDOS_HEADER_SIZE;
      }
    }

    // Prepare File add
    tDiskOperation* DiskOperationP = new tDiskOperation();
    memset(DiskOperationP, 0, sizeof(tDiskOperation));
    DiskOperationP->FormatType = ComboBoxFileSystem->ItemIndex;
    DiskOperationP->NativeCPC = FormMain->NativeCPC;
    DiskOperationP->Drive = (ComboBoxDrive->Text == cDriveALabel) ?
                            FormMain->NativeCPC->FDC->DriveA : FormMain->NativeCPC->FDC->DriveB;
    mEmulatorP->ConvertFilenameToCatalogueEntry(ExtractFileName(Filename), DiskOperationP);
    DiskOperationP->FileContentP = FileDataP;
    DiskOperationP->FileSize = FileSize;

    // Add file
    if (mEmulatorP->AddDriveFile(DiskOperationP) == false)
    {
      Application->MessageBox(_T("Not enought free space into drive disk."),
                              _T("Disk full"),
                              MB_OK | MB_ICONEXCLAMATION);
    }
  }
  else
  {
    Application->MessageBox(_T("Not able to read selected file."),
                            OpenDialogFile->FileName.c_str(),
                            MB_OK | MB_ICONEXCLAMATION);
  }

  delete [] FileDataP;
}
//---------------------------------------------------------------------------


void __fastcall TFormFilesManager::PanelButtonDeleteClick(TObject *Sender)
{
  if (Application->MessageBox(_T("Sure to delete this file ?"),
                              _T("Delete selected file"),
                              MB_YESNO | MB_DEFBUTTON2) == IDYES)
  {
    mDiskOperationP->NativeCPC = FormMain->NativeCPC;
    memcpy(mDiskOperationP->FileName,
           mDiskOperationP->CatalogueEntries[mDiskOperationP->CatalogueEntryIndex],
           CATALOGUE_FILENAME_SIZE+CATALOGUE_FILEEXT_SIZE);

    mEmulatorP->DeleteDriveFile(mDiskOperationP);
  }

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


void __fastcall TFormFilesManager::PanelButtonCopyClick(TObject *Sender)
{
  if (Application->MessageBox(_T("Sure to copy this file to the other drive ?"),
                              _T("Copy selected file"),
                              MB_YESNO | MB_DEFBUTTON2) == IDYES)
  {
    // Prepare destination disk operation
    tDiskOperation* DestOperationP = new tDiskOperation();
    memset(DestOperationP, 0, sizeof(tDiskOperation));
    DestOperationP->NativeCPC = FormMain->NativeCPC;
    memcpy(DestOperationP->FileName,
           mDiskOperationP->CatalogueEntries[mDiskOperationP->CatalogueEntryIndex],
           CATALOGUE_FILENAME_SIZE+CATALOGUE_FILEEXT_SIZE);
    // Other drive
    DestOperationP->Drive = (ComboBoxDrive->Text == cDriveALabel) ?
                            FormMain->NativeCPC->FDC->DriveB : FormMain->NativeCPC->FDC->DriveA;

    // Read source catalogue
    mEmulatorP->ReadDiskCatalogue(mDiskOperationP);
    // Read destination catalogue
    mEmulatorP->ReadDiskCatalogue(DestOperationP);

    // Check destination filesystem format
    if (DestOperationP->FormatType == DISK_FORMAT_UNKNOWN)
    {
        Application->MessageBox(_T("Unknown destination filesystem"),
                                _T("Error"),
                                MB_OK | MB_ICONEXCLAMATION);
    }
    else
    {
      // Copy file
      if (mEmulatorP->CopyDriveFile(mDiskOperationP, DestOperationP) == false)
      {
        Application->MessageBox(_T("Not enought free space into destination disk."),
                                _T("Disk full"),
                                MB_OK | MB_ICONEXCLAMATION);
      }
    }

    delete DestOperationP;
  }

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


void __fastcall TFormFilesManager::PanelButtonSectorViewExtentClick(TObject *Sender)

{
  // Sector view minimized ?
  if (StringGridSectors->Width == StringGridSectors->Constraints->MinWidth)
  {
    // Get monitor size
    int ScreenWidth = Screen->Width;
    // Max sectorview width
    int MaxSectorViewSize = ScreenWidth - Left - (Width - ClientWidth) - PanelSectorData->Width;
    int MaxTracks = MaxSectorViewSize / 20;

    // Expand to max
    if (MaxTracks > StringGridSectors->ColCount)
    {
      ClientWidth = PanelSectorData->Width + (StringGridSectors->ColCount * 20);
    }
    else
    {
      ClientWidth = PanelSectorData->Width + MaxSectorViewSize;
    }
  }
  else
  {
    // Reduce to min
    Width = PanelSectorData->Width + StringGridSectors->Constraints->MinWidth;
  }

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


void __fastcall TFormFilesManager::DropFile(TWMDropFiles &Message)
{
  HDROP hDrop = (HDROP)Message.Drop;
  int FileCount = DragQueryFile(hDrop, -1, NULL, 0 );

  // Create file list from Drop message
  for (int file = 0; file < FileCount; file++)
  {
    int CharacterCount = DragQueryFile(hDrop, file, NULL, 0) + 1; // account for NULL terminator

    _TCHAR* FileName = new _TCHAR[CharacterCount];
    DragQueryFile(hDrop, file, FileName, CharacterCount);

    if (PanelButtonAdd->Visible == true)
    {
      AddFile(AnsiString(FileName));
    }

    delete [] FileName;
  }

  DragFinish(hDrop);
}
//---------------------------------------------------------------------------


void __fastcall TFormFilesManager::ListBoxCatalogueEntriesKeyDown(TObject *Sender,
		  WORD &Key, TShiftState Shift)
{
  switch (Key)
  {
    case VK_BACK:
    case VK_DELETE:
    {
      if (PanelButtonDelete->Visible == true)
      {
        PanelButtonDeleteClick(Sender);
      }

      // Key has been treated
      //Key = 0;
    }
    break;
  }

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

