//---------------------------------------------------------------------------
/*
Remote Train Control Program for Windows

© Copyright 2024 by Mark DiVecchio
Active Engine List © Copyright 2026 by Carl K. Ross

    This file is part of Remote Train Control.

    Remote Train Control 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.

    Remote Train Control 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 Remote Train Control.  If not, see <http://www.gnu.org/licenses/>.

*/
// Home Page : http://www.silogic.com/trains/RTC_Running.html
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

// RTC Near Field Communications
#include "RTCMegaMaster.h"
#include "RTC_NFC.h"
#include "Engine_Commands.h"
#include "Train_Control.h"
#include "Comm_Thread.h"
#include "Debug_Controls.h"
#include "Clipbrd.hpp"
#include "EngineListPopOut.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "HideButton"
#pragma resource "*.dfm"
TPopOutEngineList *PopOutEngineList;

extern TOp * ptrOp[ABSOLUTEMAX];   		// Operation Control Pointers indexed by actual engine number because 0 is a factory reset engine

extern TCommThread * ptrTIUCommThread;	// pointer to TIU communications thread

//---------------------------------------------------------------------------
__fastcall TPopOutEngineList::TPopOutEngineList(TComponent* Owner)
    : TForm(Owner)
{
// Required for multiple monitors and save/restore position/size
Position=poDesigned;
DefaultMonitor=dmDesktop;
//
// read Preferences from registry if they exist
RegFileRootKey =  MainForm->RegFileRootKey;
//
TRegIniFile * const RegFile = new TRegIniFile(RegFileRootKey);
assert(RegFile != NULL);
__try {
    // read window position
    Top = RegFile->ReadInteger("EngineList", "Top", Top);
    Height = RegFile->ReadInteger("EngineList", "Height", Height);
    Left = RegFile->ReadInteger("EngineList", "Left", Left);
    Width = RegFile->ReadInteger("EngineList", "Width", Width);
    // if using multiple monitors and one was removed, pull the window
    // back onto the remaining monitor
    int MC = Screen->MonitorCount;
    if (MC == 1) {
        if (Left < 0 ) Left = 0;
        int Wth = Screen->Monitors[0]->Width;
		if (Left > Wth) Left -= Wth;
        if (Top < 0 ) Top = 0;
        int Hth = Screen->Monitors[0]->Height;
        if (Top > Hth) Top -= Hth;
        }
	}
__finally {
	// Deallocate RegFile
	delete RegFile;
	}
//
if (DEBUGGING) {
    EngineData->DefaultColWidth = 60;		// default column width for invisible columns
    ActEngLst->DefaultColWidth = 60;		// default column width for invisible columns
    } else {
    EngineData->DefaultColWidth = 30;       // debugging column width for invisible columns
    ActEngLst->DefaultColWidth = 30;        // debugging column width for invisible columns
    }
EngineData->ColWidths[ENG_NUM] = 30;
ActEngLst->ColWidths[ENG_NUM] = 30;
EngineData->ColWidths[ENG_NAME] = MainForm->EngineData->Width - EngineData->ColWidths[ENG_NUM];	// lots of space for the engine name
ActEngLst->ColWidths[ENG_NAME] = MainForm->ActEngLst->Width - ActEngLst->ColWidths[ENG_NUM];	// lots of space for the engine name
}
//---------------------------------------------------------------------------

__fastcall TPopOutEngineList::~TPopOutEngineList(void)
{
if (MainForm->bSaveRegistryInfo) {
    TRegIniFile * const RegFile = new TRegIniFile(RegFileRootKey);
    assert(RegFile != NULL);
    __try {	    // erase EngineList key
        RegFile->EraseSection("EngineList");
        // save window position
        RegFile->WriteInteger("EngineList", "Top", Top > 0 ? Top : 0);
        RegFile->WriteInteger("EngineList", "Height", Height);
        RegFile->WriteInteger("EngineList", "Left", Left);
        RegFile->WriteInteger("EngineList", "Width", Width);
        }
    __finally {
        // Deallocate RegFile
        delete RegFile;
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::EngineDataDrawCell(TObject *Sender,
      int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
// Draw the contents of each cell
EngineData->Canvas->Font->Size = 12;
// http://bcbjournal.org/articles/vol3/9904/Dealing_with_sets.htm?PHPSESSID=2f96cbddf92baa7dc77f7a33591f59b5
EngineData->Canvas->Font->Style = EngineData->Canvas->Font->Style >> fsItalic;
// if the cell is selected, highlight it
if( State.Contains(gdSelected) ) {
    EngineData->Canvas->Font->Color = clWhite;
	EngineData->Canvas->Brush->Color = clBlue;		// White on Blue
	} else {
    if (ptrOp[ARow] != NULL) {
		EngineData->Canvas->Font->Color = clBlack;	// Started up Engines are Black on Lime
		EngineData->Canvas->Brush->Color = clLime;
    	} else {
		EngineData->Canvas->Font->Color = clBlack;	// Normal Black on White
		EngineData->Canvas->Brush->Color = clWhite;
        }
	}
if ((ARow != 0) && (ARow != ALLENGINE) && (ACol == ENG_NAME) && (EngineData->Cells[ENG_STATE][ARow] == INACTIVE)) {
	// if Engine is inactive make the cell Italic.
    // Skip the column title (Row 0) and All Engine Operation (Row 100)
    EngineData->Canvas->Font->Style = EngineData->Canvas->Font->Style << fsItalic;
	}
// move a little to the right
Rect.Left = Rect.Left + LISTLEFTOFFSET;
// fill the rectangle
EngineData->Canvas->FillRect(Rect);
// draw the text
String text;
if ((ACol == ENG_NAME) && (ARow != ENG_LABEL_ROW) && (ARow != ENG_ALLROW) && (EngineData->Cells[ENG_NAME][ARow] != "*")) {
    text = EngineData->Cells[ACol][ARow] + "  TIU" + String(EngineData->Cells[TIU_NUMBER][ARow]);
    } else {
    text = EngineData->Cells[ACol][ARow];
    }
EngineData->Canvas->TextRect(Rect, Rect.Left, Rect.Top, text);
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::EngineDataClick(TObject *Sender)
{
// Reflect new row to MainForm->EngineData
if (MainForm && (MainForm->EngineData->Row != EngineData->Row)) MainForm->EngineData->Row = EngineData->Row;
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetConsistState(int Consist, int State)
{
// set the active/inactive state of an Engine
//
assert((State == ACTIVE) || (State == INACTIVE));
if (Consist == 0) return;	// factory reset engine not allowed
assert((Consist >= 1) && (Consist <= ENGINEMAX));	// 1-99
if (EngineData->Cells[ENG_STATE][Consist] == ACTIVE) {		// Adjust Counts
	if (State == INACTIVE) {
        MainForm->ActiveEngineCount->Value--;
		MainForm->InactiveEngineCount->Value++;
    	}
	}
if (EngineData->Cells[ENG_STATE][Consist] == INACTIVE) {	// Adjust Counts
	if (State == ACTIVE) {
        MainForm->ActiveEngineCount->Value++;
		MainForm->InactiveEngineCount->Value--;
    	}
	}

EngineData->Cells[ENG_STATE][Consist] = State;	// set active or inactive
MainForm->EngineData->Cells[ENG_STATE][Consist] = State;	// set active or inactive
// redraw the control
EngineData->Repaint();
MainForm->EngineData->Repaint();
return;
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesActiveClick(TObject *Sender)
{
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        SetConsistState(EngineNo, ACTIVE);
        }
    }
// update users of the Engine List
MainForm->UpdateEngDataUsers();
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesInactiveClick(TObject *Sender)
{
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        SetConsistState(EngineNo, INACTIVE);		// set inactive
        }
    }
// update users of the Engine List
MainForm->UpdateEngDataUsers();
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesintoCommandModeClick(
      TObject *Sender)
{
RemoteNo = MainForm->RemoteSpin->ValueAsInt;
// if TIU Port is not connected fail
if (!MainForm->IsTIUConnected()) {
	MainForm->DebugMessagePopup("Warning", MainForm->ConnectMsg, "");
	return;
    }
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*" && EngineData->Cells[ENG_STATE][EngineNo] == ACTIVE) {
        (void)ptrTIUCommThread->Send_String_FIFO(EngineNo, "m4", EngineData->Cells[TIU_NUMBER][EngineNo].ToInt(), RemoteNo, 11, SHORT_WAIT, RECORD_OK);
		MainForm->Delay(m4DELAY);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesintoConventionalModeClick(
      TObject *Sender)
{
RemoteNo = MainForm->RemoteSpin->ValueAsInt;
// if TIU Port is not connected fail
if (!MainForm->IsTIUConnected()) {
	MainForm->DebugMessagePopup("Warning", MainForm->ConnectMsg, "");
	return;
    }
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*" && EngineData->Cells[ENG_STATE][EngineNo] == ACTIVE) {
        (void)ptrTIUCommThread->Send_String_FIFO(EngineNo, "m2", EngineData->Cells[TIU_NUMBER][EngineNo].ToIntDef(0), RemoteNo, 11, SHORT_WAIT, RECORD_OK);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesintoLegacyModeClick(
      TObject *Sender)
{
RemoteNo = MainForm->RemoteSpin->ValueAsInt;
// if TIU Port is not connected fail
if (!MainForm->IsTIUConnected()) {
	MainForm->DebugMessagePopup("Warning", MainForm->ConnectMsg, "");
	return;
    }
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*" && EngineData->Cells[ENG_STATE][EngineNo] == ACTIVE) {
        (void)ptrTIUCommThread->Send_String_FIFO(EngineNo, "m8", EngineData->Cells[TIU_NUMBER][EngineNo].ToIntDef(0), RemoteNo, 11, SHORT_WAIT, RECORD_OK);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesPS2Click(TObject *Sender)
{
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        SetEnginesPS2->Checked = true;
        SetEnginesPS3->Checked = false;
        EngineData->Cells[ENG_PS][EngineNo] = PS2;
        MainForm->SetEnginePS2->Checked = true;
        MainForm->SetEnginePS3->Checked = false;
        MainForm->EngineData->Cells[ENG_PS][EngineNo] = PS2;
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::SetEnginesPS3Click(TObject *Sender)
{
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        SetEnginesPS2->Checked = false;
        SetEnginesPS3->Checked = true;
        EngineData->Cells[ENG_PS][EngineNo] = PS3;
        MainForm->SetEnginePS2->Checked = false;
        MainForm->SetEnginePS3->Checked = true;
        MainForm->EngineData->Cells[ENG_PS][EngineNo] = PS3;
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::StartUpSelectedEngines1Click(
      TObject *Sender)
{
// if TIU Port is not connected fail
if (!MainForm->IsTIUConnected()) {
	MainForm->DebugMessagePopup("Warning", MainForm->ConnectMsg, "");
	return;
    }
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        MainForm->EngineData->Row = EngineNo;
        MainForm->StartupButtonClick(Sender);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ShutdownSelectedEngines1Click(
      TObject *Sender)
{
// if TIU Port is not connected fail
if (!MainForm->IsTIUConnected()) {
	MainForm->DebugMessagePopup("Warning", MainForm->ConnectMsg, "");
	return;
    }
for (int EngineNo = EngineData->Selection.Top; EngineNo <= EngineData->Selection.Bottom ; EngineNo++) {
    if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
        // You can shutdown an engine even it was not started up
        MainForm->EngineData->Row = EngineNo;
        MainForm->ShutdownButtonClick(Sender);        
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::HideButton1Click(TObject *Sender)
{
Visible = false;    
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::EngineDataDblClick(TObject *Sender)
{
if (EngineData->Cells[ENG_NAME][EngineNo] != "*") {
    MainForm->EngineDataDblClick(Sender);
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::EngineDataKeyDown(TObject *Sender,
      WORD &Key, TShiftState Shift)
{
// if ENTER is pressed, startup the selected engines
if (Key == VK_RETURN) {
	if (EngineData->Cells[ENG_NAME][EngineData->Row] != "*") {
		StartUpSelectedEngines1Click(Sender);
   		}
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::CopyrightClick(TObject *Sender)
{
// Copy the Form to the clipboard.
// In BCB4.0, there is no SetSize method associated with TBitmap
// so we have to use Width and Height separately.
//
// see:
// https://stackoverflow.com/questions/3190777/how-do-i-copy-a-form-as-an-image-to-the-clipboard
//
Graphics::TBitmap * bm;
bm = new Graphics::TBitmap;
try
	{
    #if __BORLANDC__ >= 0x720
	// Defined for CB10.1 C++ programs that use the VCL.
	bm->SetSize(ClientWidth, ClientHeight);
    #else
    bm->Width = ClientWidth;
    bm->Height = ClientHeight;
    #endif
	BitBlt(bm->Canvas->Handle, 0, 0, ClientWidth, ClientHeight, Canvas->Handle, 0, 0, SRCCOPY);
    Clipboard()->Assign(bm);
    }
__finally
	{
	delete bm;
    }    
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::AllEngineButtonClick(TObject *Sender)
{
//
// Select Row 100 for All Engine
EngineData->Row = ALLENGINE;
if (MainForm->EngineData->Row != EngineData->Row) MainForm->EngineData->Row = EngineData->Row;
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::RefreshClick(TObject *Sender)
{
//
// cannot assign a TStringGrid to a TStringGrid : PopOutEngineList->EngineData->Assign(EngineData);
// We have to do it column by column or row by row
//
for (int I = 0; I < EngineData->ColCount; I++)
    EngineData->Cols[I]->Assign(MainForm->EngineData->Cols[I]);
EngineData->Row = MainForm->EngineData->Row;
EngineData->Col = MainForm->EngineData->Col;
Engine_List_Label->Caption = MainForm->Engine_List_Label->Caption;
//
FillActEngLst();			// MCD  fill the active engine list
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngLstClick(TObject *Sender)
{
// Reflect new row to EngineData
// CKR - get the equivalent row in the EngineData list
if(ActEngLst->Cells[ENG_NAME][ActEngLst->Row] == "*") {           //CKR - if no engine name, just return
	return;
	}

String EngNum = ActEngLst->Cells[ENG_NUM][ActEngLst->Row];      //CKR - get the engine number, MCD rewrote for efficiency
if (ActEngLst->Row > 0) {
    EngineData->Row = EngNum.ToInt();
    }

EngineDataClick(Sender); //CKR Pretend that the EngineData list has been clicked

// Reflect new row to MainForm->EngineData
if (MainForm && (MainForm->EngineData->Row != EngineData->Row)) MainForm->EngineData->Row = EngineData->Row;
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngLstDblClick(TObject *Sender)
{
//
// double clicking in column header or row header is ignored
if (ActEngLst->Col == ENG_NUM || ActEngLst->Row == ENG_LABEL_ROW) return;

    MainForm->ActEngLstDblClick(Sender);
    }
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngLstDrawCell(TObject *Sender,
      int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
//
// Draw the contents of each cell
ActEngLst->Canvas->Font->Size = 12;
// http://bcbjournal.org/articles/vol3/9904/Dealing_with_sets.htm?PHPSESSID=2f96cbddf92baa7dc77f7a33591f59b5
ActEngLst->Canvas->Font->Style = ActEngLst->Canvas->Font->Style >> fsItalic;
// if the cell is selected, highlight it
if( State.Contains(gdSelected) ) {
    ActEngLst->Canvas->Font->Color = clWhite;
	ActEngLst->Canvas->Brush->Color = clBlue;		// White on Blue
	} else {
    //if (ptrOp[ARow] != NULL) {
    String EngNum = ActEngLst->Cells[ENG_NUM][ARow];
    if (ARow > 0 && ptrOp[EngNum.ToInt()] != NULL) {
		ActEngLst->Canvas->Font->Color = clBlack;	// Started up Engines are Black on Lime
		ActEngLst->Canvas->Brush->Color = clLime;
    	} else {
		ActEngLst->Canvas->Font->Color = clBlack;	// Normal Black on White
		ActEngLst->Canvas->Brush->Color = clWhite;
        }
	}

// move a little to the right
Rect.Left = Rect.Left + LISTLEFTOFFSET;
// fill the rectangle
ActEngLst->Canvas->FillRect(Rect);
// draw the text
String text;
if ((ACol == ENG_NAME) && (ARow != ENG_LABEL_ROW) && (ARow != ENG_ALLROW) && (ActEngLst->Cells[ENG_NAME][ARow] != "*")) {
    text = ActEngLst->Cells[ACol][ARow] + "  TIU" + String(ActEngLst->Cells[TIU_NUMBER][ARow]);
    } else {
    text = ActEngLst->Cells[ACol][ARow];
    }
ActEngLst->Canvas->TextRect(Rect, Rect.Left, Rect.Top, text);
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngLstKeyDown(TObject *Sender,
      WORD &Key, TShiftState Shift)
{
//
// if ENTER is pressed, startup the selected engines
if (Key == VK_RETURN) {
	if (EngineData->Cells[ENG_NAME][EngineData->Row] != "*") {
		StartUpSelectedEngines1Click(Sender);
   		}
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngLstMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
int ARow, ACol;
if (Button == mbRight || Button == mbMiddle) {
	ActEngLst->MouseToCell(X, Y, ACol, ARow);
    ActEngLst->Row = ARow;
	ActEngLst->Col = ACol;
    }

ActEngLstClick(Sender);
// Popup the PopupMenu
if (Button == mbRight) {
	ActEngLst->PopupMenu->Popup(Left + X, Top + Y);
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::ActEngChckBoxClick(TObject *Sender)
{
//
// MCD  use Visible property which would be slightly more efficent as the
// invisible box is not drawn until actually displayed
if(ActEngChckBox->Checked) {
	ActEngLst->Visible = true;;
	EngineData->Visible = false;
	FillActEngLst();            	// MCD  fill the active engine list
    }  else {
	EngineData->Visible = true;
	ActEngLst->Visible = false;
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::FillActEngLst(void)
{
// CKR Routine to populate the active engine list

/*
I found that, with one form on top of the other, one saw bits of characters
in both StringGrids. As per a recommendation from ChatGPT, I turned on double buffering
for the MainForm, using the Object Inspector. This fixed the problem.
*/

// Only needed if Active Engine List is Visible
if(!ActEngLst->Visible) return;

// CKR - make sure the headers are written
ActEngLst->Rows[ENG_LABEL_ROW]->CommaText = ENGDAT_TITLE;

// CKR - clear the active engine list

ActEngLst->RowCount = ENGINEMAX + 2;  // MCD reconstitute the Active Eng List
for (int i = ENG_TOPROW; i < ActEngLst->RowCount; i++) {
    ActEngLst->Rows[i]->CommaText = "*, *";
    }

// Scan EngineData list looking for active engines MCD Rewrote
int ActEngCount = 0;        // Active Eng Count
int ActEng = ENG_TOPROW;
for (int EngNum = ENG_TOPROW; EngNum < EngineData->RowCount ; EngNum++) {
	if(EngineData->Cells[ENG_STATE][EngNum] == ACTIVE) {
		ActEngLst->Rows[ActEng++]->Assign(EngineData->Rows[EngNum]);
        ActEngCount++;  // Increment Active Eng Count
        if (EngNum == EngineData->Row) {
            ActEngLst->Row = ActEngCount;
   		}
    }
}
ActEngLst->RowCount = ActEngCount + 1;  // resize the Active Eng List
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::EngineDataPopOutMenuPopup(
      TObject *Sender)
{
// Perform right click function then bring up the popup menu
//
if (!ActEngChckBox->Checked) {
    // When showing the complete Engine List, use these settings
    //
    StartUpSelectedEngines1->Caption = "Startup all selected engines";
    ShutdownSelectedEngines1->Caption = "Shutdown all selected engines";
    SetEnginesintoCommandMode->Caption = "Set Engines into Command Mode";
    SetEnginesintoLegacyMode->Caption = "Set Engines into Legacy Mode";
    SetEnginesintoConventionalMode->Caption = "Set Engines into Conventional Mode";
    SetEnginesActive->Caption = "Set Engines Active";
    SetEnginesInactive->Caption = "Set Engines Inactive";
    SetEnginesPS2->Caption = "Set Engines as PS2";
    SetEnginesPS2->Checked = (MainForm->EngineData->Cells[ENG_PS][EngineNo] == PS2);
    SetEnginesPS3->Caption = "Set Engines as PS3";
    SetEnginesPS3->Checked = (MainForm->EngineData->Cells[ENG_PS][EngineNo] == PS3);

    StartUpSelectedEngines1->Visible = true;
    ShutdownSelectedEngines1->Visible = true;
    SetEnginesintoCommandMode->Visible = true;
    SetEnginesintoLegacyMode->Visible = true;
    SetEnginesintoConventionalMode->Visible = true;
    SetEnginesActive->Visible = true;
    SetEnginesInactive->Visible = true;
    SetEnginesPS2->Visible = true;
    SetEnginesPS3->Visible = true;
    } else {
    // When showing the Active Engine List, use these settings
    //
    StartUpSelectedEngines1->Caption = "Startup all selected engines";
    ShutdownSelectedEngines1->Caption = "Shutdown all selected engines";
    StartUpSelectedEngines1->Visible = true;
    ShutdownSelectedEngines1->Visible = true;
    SetEnginesintoCommandMode->Visible = false;
    SetEnginesintoLegacyMode->Visible = false;
    SetEnginesintoConventionalMode->Visible = false;
    SetEnginesActive->Visible = false;
    SetEnginesInactive->Visible = false;
    SetEnginesPS2->Visible = false;
    SetEnginesPS3->Visible = false;
    }
}
//---------------------------------------------------------------------------
   
void __fastcall TPopOutEngineList::EngineDataMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
//
int ARow, ACol;
if (Button == mbRight || Button == mbMiddle) {
	EngineData->MouseToCell(X, Y, ACol, ARow);
    EngineData->Row = ARow;
	EngineData->Col = ACol;
    }

EngineDataClick(Sender);
// Popup the PopupMenu
if (Button == mbRight) {
	EngineData->PopupMenu->Popup(Left + X, Top + Y);
    }
}
//---------------------------------------------------------------------------

void __fastcall TPopOutEngineList::RestorethescrollbarontheEngineList1Click(
      TObject *Sender)
{
EngineData->ScrollBars = ssBoth;
ActEngLst->ScrollBars = ssBoth;    
}
//---------------------------------------------------------------------------

