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

© Copyright 2019 by Mark DiVecchio

    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
//---------------------------------------------------------------------------
/*
MainForm, DB and NumberQuery and Command_Query_Form are auto created
All of the rest of the forms are manually created

There may be a bug in Borland C++ Builder which causes a stack overflow
if the overridder constructor only has one additional parameter, an int.

All overrider constructors should have at least two additional int paramters

*/
//---------------------------------------------------------------------------
#ifndef Train_ControlH
#define Train_ControlH
//---------------------------------------------------------------------------

// https://learn.microsoft.com/en-us/windows/win32/secauthn/using-sspi-with-a-windows-sockets-client
#define SECURITY_WIN32

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <Menus.hpp>
#include <Dialogs.hpp>
#include <Registry.hpp>
#include "_GClass.hpp"
#include "AbOpHour.hpp"
#include "AbClock.hpp"
#include "AbLED.hpp"
#include "AbSwitch.hpp"
#include "AbNumEdit.hpp"
#include "AbDial.hpp"
#include "AbVSlide.hpp"
#include "AbHSlide.hpp"
#include "AbDBCtrls.hpp"
#include "AbCBitBt.hpp"
#include "AbPanel.hpp"
#include <Graphics.hpp>
#include <Grids.hpp>
#include <ImgList.hpp>
#include <Tabnotbk.hpp>
#include <Mask.hpp>
#include <ActnList.hpp>
// Differences between BCB4.0/BCB6.0 and CB10.1
#include "OverbyteIcsWndControl.hpp"
#include "OverbyteIcsWSocket.hpp"
#include <System.Actions.hpp>
#include <System.ImageList.hpp>
#include "OverbyteIcsWSocketS.hpp"
#pragma link "OverbyteIcsWndControl"
#pragma link "OverbyteIcsWSocket"
//
#define ENABLENOTIFICATIONS false   // Notifications do not clear on CancelAll()
//
#if __BORLANDC__ >= 0x720 && ENABLENOTIFICATIONS
#include <System.Notification.hpp>
#endif
//
// remain at end of buffer
//
// Method 1 does not work under CB10.1  --------------------------------
//DB->Debug_Messages->SelStart = Debug_Messages->GetTextLen();
//DB->Debug_Messages->Perform(EM_SCROLLCARET, 0, 0);
// Method 2 does not work under CB10.1  --------------------------------
//DB->Debug_Messages->SelStart = Debug_Messages->Text.Length();
//SendMessage(Debug_Messages->Handle, EM_SCROLLCARET,0,0);
// Method 3 works under both BCB 4.0 and CB10.1  --------------------------------
// But sometimes line down doesn't get to end of buffer
//DB->Debug_Messages->Perform(EM_SCROLL, SB_LINEDOWN, 0);	// remain at end of buffer
// Method 4 works under CB10.1 but not BCB 4.0  --------------------------------
//http://codeverge.com/embarcadero.delphi.general/d2009-richedit/1040993
//RecordingBuffer->HideSelection = false;
//RecordingBuffer->Perform(EM_SCROLLCARET,0 ,0);	// remain at end of Recording Buffer
//RecordingBuffer->HideSelection = true;
// Method 5 works under CB10.01  --------------------------------
//https://stackoverflow.com/questions/6372193/how-to-autoscroll-to-the-end-of-richedit
//DB->Debug_Messages->Perform(EM_SCROLL, SB_BOTTOM, 0);	// remain at end of buffer
//
// remain at end of buffer
#if __BORLANDC__ >= 0x720
    #define ScrollEnd(X) {X->Perform(EM_SCROLL, SB_BOTTOM, 0);}
#else
    #define ScrollEnd(X) {X->Perform(EM_SCROLLCARET, 0, 0);}
#endif
//
//
// Enable Debugging Output, 0 = debugger on screen but no messages displayed
//                          1-9 = debugger message level. A larger number means more messages
#define DEBUGGING (MainForm->bDebug && DB && (MainForm->GlobalDBLevel >= 1))
#define DEBUGGINGX(X) ((MainForm->bDebug) && DB && (MainForm->GlobalDBLevel >= X))
//
// from Help:
// If you place the #define NDEBUG directive ("no debugging") in the source code
// before the #include <assert.h> directive, the effect is to comment out the assert statement
//#define NDEBUG		// define to turn off the assert() command
#include <assert.h>
//
//
#include "lua.hpp"	// extern C wrapper
//---------------------------------------------------------------------------
// Main Size Definitions
//
#define ABSOLUTEMAX 121	// Number of Engines & LashUps Plus 1
#define LASHUPMAX 120	// Highest Lashup Number - LashUps 101-120 (always DCS #102)
#define LASHUPDCSNO 102	// in commands, lashups are always DCS #102
#define LASHUPMIN 101	// Lowest Lashup Number - LashUps 101-120 (always DCS #102)
#define MAXLASHUP 10    // maximum number of engines in a LashUp
#define MAXMIDDLE 8     // maximum number of middle engines in a LashUp
#define ALLENGINE 100	// All Engine Operation Number - All Engine Operation 100 (DCS 101)
#define DISABLE_ALL_ENGINE_RECORDING false
#define ENGINEMAX 99	// Highest Engine Number - Real Engines 1-99 (DCS 2-100)
#define ENGINEMIN 1		// Lowest Engine Number - Real Engines 1-99 (DCS 2-100)
#define FACTORYRESET 0	// Factory Reset Engine - 0
#define TMCCENGINEMAX 100	// Maximum number of TMCC Engines
#define RFIDMAX 50      // Maximum number of RFID detectors
//
#define TIUMAX 5	// Number of TIU - (5 or 8 : 0-7 in the command itself) accepted (1-5) are supported by the Remote - 3 bits in Command (0-7)
#define AIUMAX 5	// Number of AIU per TIU - (1-10 : 0-9 in the command itself) acceptable but I don't know what would set the limit.
#define CHANMAX 10	// Number of ports per AIU
#define TOTALCHANMAX (AIUMAX * CHANMAX)	// Total number of AIU channels supported
#define CONVMAX 2	    // Number of Conventional mode windows per TIU
#define REMOTEMAX 15	// Number of Remotes
#define CMDMAX 512	    // max size of any comand to/from the TIU in characters
#define RWDATAMAX 8192  // max size of 'R' or 'W' packet to/from the TIU in characters
#define PCMAX 10		// max number of Program Control Windows
#define TSMAX 100       // highest track signal value
#define TYPEMAX 1       // highest type of switch/accy in Route/Scene
#define TYPEACCY 0      // accessory type in Route/Scene
#define TYPESW 1        // switch type in Route/Scene
#define RSMAX 256       // max number of Route/Scenes
#define SIGNALMAX 100   // max number of Signals
//
#define SPEEDMAX 120	// max speed in Smph
#define VOLMAX 100		// max volume in %
#define HOTPAGEMAX 5	// Number of hot button pages
#define QUICKPAGEMAX 5  // Number of Quick Control pages
//
#define MRUMAX 10		// max items in MRU lists
//
#define MAXINTERFACES 10 // max number of IP on the computer
//
#define UIPOPUPTIMEOUT 2000 // number of ms to hold UI popup messages on screen
//
#define WAITAFTERSTARTUP 2000    // number of ms to wait after startup before next command
#define USED0ANDS0AFTERSTARTUP true // allow d0 and s0 commands after WAITAFTERSTARTUP ms
#define m4DELAY 100			// ms to delay after m4 command
//
// constants used in DCH, DOD and DTO calculations
//
/*
19 Sep 2019

Wall Clock		raw value
07:51			29476094    diff:   minutes sec/min     ticks/sec
10:02			29229921	246173 / (131  *  60)     = 31.3197

*/
#define DCHFACTOR 31.3197
#define DTOFACTOR (110.0/10.0)
//
// Equations used in DCH, DOD, and DTO calculations
//
#define DTOEQUATION(RawValue, ScaleFactor) ((RawValue) / ((ScaleFactor) * (DTOFACTOR)))

//#define DODEQUATION(RawValue, ScaleFactor) (((DODFACTOR) * (RawValue)) / (ScaleFactor))
#define DODEQUATION(RawValue, ScaleFactor) (((RawValue) << 9) / ((ScaleFactor) * (DTOFACTOR)))

#define DCHEQUATION(RawValue) ((RawValue) / (DCHFACTOR))

// Which program is running in PC_Thread
//
enum PROGRAMNO {NOT_RUNNING = 0, RUN_LUASCRIPT, COMPILE_LUASCRIPT, RUN_LUAINTERACTIVE};

//---------------------------------------------------------------------------
// Definition Limit checks
//
#if TIUMAX > 8
#error TIUMAX cannot be greater than 8 (3 bits in Command, coded as 0-7)
#endif
#if AIUMAX < 1 || AIUMAX > 10
#error AIUMAX must be 1 - 10 (1 decimal digit in Command, coded as 0-9)
#endif
#if CONVMAX > 2
#error CONVMAX cannot be greater than 2
#endif
#if REMOTEMAX > 15
#error REMOTEMAX cannot be greater than 15
#endif
#if PCMAX > 10
#error PCMAX cannot be greater than 10
#endif
//---------------------------------------------------------------------------
#define FAIL 1
#define SUCCESS 0
#define UNKNOWN -1

// Times are in milliseconds
#define SHORTTOOT 400L
#define LONGTOOT 1500L
#define VERYLONGTOOT 2500	// should only be used at the end of a sequence
#define SHORTPAUSE 900L
#define MFACTOR 1.5			// MTH engines don't respond if horn/whistle commands are too close together

//Decode
struct Cmd {
	unsigned char Str [CMDMAX];
    int idx;
    bool ready;
    };
//---------------------------------------------------------------------------
// Event Codes for the PC Threads
//---------------------------------------------------------------------------
#define NOEVENT 0;
#define RUNTOEVENT 1;
#define STARTUPENGINE 2;
#define SHUTDOWNENGINE 3;
#define ONSHEET 4;
#define BLOCK_OCCUPANCY_EVENT 5;
#define TAG_EVENT 6;
//---------------------------------------------------------------------------
// Response codes from Comm_Thread.cpp functions
//
//	0x0T	Engine returned 0x0T Status Byte - where T is the TIU Number (0-4)
//          Usually means Engine Not Found or non-Engine specific request (like "q", "Dq", "I0", "Ixxx", "x" or "!")
//			Only an error if expected count is 11 in which case, code is translated to 0x9T.
//	0x1T	Engine returned 0x1T Status Byte where T = TIU Number (0 based) This is usually an ACK
//
//	0x80	Undetermined
#define UNDETERMINED 0x80
//	0x81	Too many bytes returned
#define TOMANYBYTES 0x82
//	0x82	OK response "55554D" not received
#define OKMISSED 0x82
//	0x83	Too few bytes returned
#define TOOFEWBYTES 0x83
//	0x84	CRC error in returned packet
#define CRCERROR 0x84
//  0x85	Got zero bytes (timedout)
#define TIMEDOUT 0x85
//	0x86	WTIU Failure Code
#define ILLEGALCOMMAND 0x86
//  0x87    WTIU Illegal Command
#define WTIUFAILURE 0x87
//  0x88    WTIU Failure
#define WTIUERROR 0x88
//  0x89    WTIU Error
#define WTIURESET 0x89
//  0x8A    PC Connection not available
#define WTIUNOTAVAILABLE 0x8A
//  0x8B    TCP Connection Lost
#define WTIUDISCONNECT 0x8B
//  0x8C    TCP command echo error
#define WTIUECHO 0x8C
//  0x9T	WTIU NAK Response
#define NAKRESPONSE 0x90
//
//---------------------------------------------------------------------------
// Engine Data File Columns - NOTE that all of these columns are Strings
// https://stackoverflow.com/questions/53671394/c-builder-allows-string-comparison-with-int-why
// "As RemyLebeau said: Note that String is not an actual type, it is an
// alias for either AnsiString (C++Builder 2007 and earlier) or UnicodeString
// (C++Builder 2009 and later). Both do implement implicit conversions from numeric types."
#define ENG_NUM 0
#define ENG_NAME 1
#define ENG_HDLT 2
#define ENG_PS 3
	#define UDEF0 0
    #define UDEF1 1
    #define PS2	2
    #define PS3 3
    #define PS4 4
#define ENG_SMOKE 4
#define ENG_FCC 5
#define ENG_SMOKELEVEL 6
#define ENG_CHAT 7
#define ENG_PROTOCHUFF 8
#define ENG_CHUFFRATE 9
#define ENG_BRAKES 10
#define ENG_DITCH 11
#define ENG_AUX1 12
#define ENG_AUX2 13
#define ENG_BEACON 14
#define ENG_AUX3 15
#define ENG_MARKER 16
#define ENG_TYPE 17 	// Engine Type
	#define STEAM_ENGINE 0
	#define DIESEL_ENGINE 1
	#define ELECTRIC_ENGINE 2
#define ENG_MAXSPEED 18
#define ENG_STATE 19	// State
	#define ACTIVE 0
	#define INACTIVE 1

#define VOLUMESTART 20
#define VOL_MASTER (VOLUMESTART+0)
#define VOL_ENGINE (VOLUMESTART+1)
#define VOL_ACCENT (VOLUMESTART+2)
#define VOL_HORN   (VOLUMESTART+3)
#define VOL_BELL   (VOLUMESTART+4)

#define TIU_NUMBER (VOLUMESTART+5)
#define SPARE1 (VOLUMESTART+6)
#define SPARE2 (VOLUMESTART+7)

// Engine Data File Rows
#define ENG_LABEL_ROW 0
#define ENG_TOPROW 1
#define ENG_ALLROW 100

// Engine Data File Initial Values (use TIUNo = 0 to indicate a [Read] is necessary)
// Field                0       1                             2           3         4          5       6                         7        8      9         10         11         12       13       14         15       16         17       18            19           20         21          22          23        24        25       26       27
#define ENGDAT_TITLE "\"#\",\"Name ----------------------\",\"17-HDLT\",\"PS\",   \"Smoke\", \"FCC\",\"AutoLabor-Smoke Level\",\"Chat\",\"PC\",\"Rate\", \"Brake\", \"Ditch\", \"AUX1\",\"AUX2\",\"Beacon\",\"AUX3\",\"Marker\",\"Type\",\"Max Speed\",\"Inactive\",\"Master\",\"Engine\", \"Accent\", \"Horn\", \"Bell\", \"TIU\", \"SP1\", \"SP2\""
#define ENGDAT_INIT       ",*,                                01,         0,        0,         0,      01,                       0,       1,     0,        1,         1,         1,       1,       1,         1,       1,         0,       120,          1,           100,       100,        100,        100,      100,      1,       0,       0"
#define ENGDAT_COUNT 28
//---------------------------------------------------------------------------

// new messages  (WM_APP == 0x8000)
#define CM_SHUTDOWN      (WM_APP + 400)
#define CM_STOPPLAYBACK  (WM_APP + 401)
#define CM_STOPPFA       (WM_APP + 402)
#define CM_EMERGENCYSTOP (WM_APP + 403)
#define CM_LASHUPSTARTUP (WM_APP + 404)
#define CM_LASHUPSOUNDCTRLS  (WM_APP + 405)
#define CM_TMCCSHUTDOWN  (WM_APP + 406)
#define CM_SPARE         (WM_APP + 407)
#define CM_TIUCHAR       (WM_APP + 408)		//33176
#define CM_LABORREVUP    (WM_APP + 409)
#define CM_DRIFTREVDN    (WM_APP + 410)
#define CM_WHISTLE       (WM_APP + 411)
                                // 412 not  used
#define CM_CPLRF         (WM_APP + 413)
#define CM_CPLRR         (WM_APP + 414)
#define CM_BELL          (WM_APP + 415)
#define CM_DIR           (WM_APP + 416)
#define CM_SFS           (WM_APP + 417)
#define CM_SRS           (WM_APP + 418)
#define CM_SXS           (WM_APP + 419)

#define CM_TIUCOMM       (WM_APP + 420)

#define CM_ACT			 (WM_APP + 421)
#define CM_SOUNDCONTROL	 (WM_APP + 422)
#define CM_OPCONTROL	 (WM_APP + 423)

#define CM_SAH              (WM_APP + 424)
#define CM_TIUASCIICHAR     (WM_APP + 425)	// 33193 (0x8000 + 0x01AA)
#define CM_RFIDASCIICHAR    (WM_APP + 426)	// 33194 (0x8000 + 0x01AB)
//#define CM_PROCESSASCIIDATA (WM_APP + 427)	// 33195 (0x8000 + 0x01AC) Never Used
#define CM_PROCESSRFIDDATA  (WM_APP + 428)
#define CM_RADIOCOMSTATUS   (WM_APP + 429)
#define CM_RFIDCOMSTATUS    (WM_APP + 430)
#define CM_UI				(WM_APP + 431)

#define CM_PROGCTRLSTOP		(WM_APP + 432)
#define CM_HOTCOM			(WM_APP + 433)
#define CM_PCWINDOWOPEN		(WM_APP + 434)

#define CM_REENABLE			(WM_APP + 435)
#define CM_AIU				(WM_APP + 436)
#define CM_QUICK			(WM_APP + 437)

#define CM_PROCESSRADIODATA	(WM_APP + 438)
#define CM_SENDWIFIPACKET	(WM_APP + 439)

#define CM_PCTHREADTERM		(WM_APP + 440)
#define CM_LASHUPSHUTDOWN   (WM_APP + 441)
#define CM_SHOWWATCHDOG	    (WM_APP + 442)
#define CM_SENDWATCHDOG     (WM_APP + 443)
//---------------------------------------------------------------------------
// User Interface Message (CM_UI) Types
//
#define M_PrintItem 1
#define M_Bump 2
#define M_SetColor 3
#define M_SetTextValue 4
#define M_GetTextValue 5
#define M_SetRecordingTextValue 6
#define M_ShowinTIUBuffer 7
#define M_PopupItem 8
#define M_ShowinBuffer 9
#define M_SetSpinnerValue 10	// needs to be tested
#define M_SetNumEditValue 11
#define M_Dec 12
#define M_GetCntrValue 13
#define M_SetPCLED 14
#define M_SetNumEditColor 15
#define M_GetComboBoxText 16
#define M_ClearCntr 17
#define M_SetCntr 18
#define M_OpenAIUWindow 19
#define M_GetAIUSwitchState 20
#define M_GetAIUAccState 21
#define M_GetAIUSwitchName 22
#define M_GetAIUAccName 23
#define M_MakeItSo 24
#define M_SetVirtualAIUAccState 25
#define M_GetStringGridText 26
#define M_SetLabelText 27
#define M_PopupMessage 28
// Layout Flags
#define M_GetFlag 29
#define M_SetFlag 30
#define M_GetFlagName 31
#define M_SetFlagName 32
//#define M_ShowLayout 33  // deleted, duplicate of 38
// Fixed Signals
#define M_GetAspect 34
#define M_SetAspect 35
#define M_GetSignalName 36
#define M_CreateSignal 37
#define M_ShowLayout 38
#define M_DeleteAllSignals 39
// HUD
#define M_SetCabAspect 40
#define M_SetCabLabels 41
#define M_CreateCab 42
#define M_GetCabAspect 43
// LED
#define M_SetLED 44
//
#define M_AddCntr 45
#define M_GetListBoxText 46
#define M_GetTIUNo 47
#define M_RockerSwitch 48
#define M_SetButtonCaption 49
//
#define M_GetSpinnerValue 50
#define M_RouteScene 51
//---------------------------------------------------------------------------
// Radio port Wait Times in milliseconds (if this is changed, reflect the change in RTCSnoop and RTCUnAdapter)
enum Wait_Times {NO_WAIT=0, SHORT_WAIT=300, MED_WAIT=400, LONG_WAIT=600, QUERY_WAIT=600, AIU_WAIT=800, VERY_LONG_WAIT=2000, AIU_LONG_WAIT=3200, I_WAIT=10500};

// Record Flags
#define RECORD_OK true
#define NO_RECORD false

// Playsound WAV files in Remote_Control.rc
#define RELAY_CLICK 100 // "Relay Clicking.wav"
#define TOY_WHISTLE 101 // "toy-train-whistle.wav"
#define MOUSE_CLICK 102 // "positive-interface-click.wav"
#define N_O_SQUARE 103    // "Disneyland New Orleans Square Telegraph (-75%).wav"
#define AIR_HOSE 104      // "air-hose-disconnect.wav"

// OnOffImage List
#define IMAGE_OFF 0
#define IMAGE_ON 1
#define IMAGE_DIVERGE 2
#define IMAGE_STRAIGHT 3

#define LASHUP_ENGINE_LIST_LENGTH 128

// serial comm parameters
#define DELAYSTEP 10		// milliseconds
#define OKRESPONSE 3
#define MINRESPONSE 11

#define LISTLEFTOFFSET 3    // to better center the text in the Engine Lists

// A bug in BCB4.0 - when this routine is called, the value of Position has
// already changed. Correct operation in CB10.1 "use the OnClick event handler
//to respond to changes just before the value of Position is changed."
#if __BORLANDC__ >= 0x720
#define UPDOWNBUGFIX 1
#else
#define UPDOWNBUGFIX 0
#endif

// Define this to use direct calls to Send_String_FIFO rather than using PostMessage()
#define BUTTONMETHOD
//
// Avoid reentrancy by disabling the component - works ok for same button pushes
// https://stackoverflow.com/questions/31649315/c-builder-button-click-function-reentry
struct locker {
    bool &b;
    locker(bool &b): b(b) {}
    bool lockold() { return b++; }
    // improved version of lock() by chatGPT
    bool lock() {
        if (!b) { b = true; return false; }  // first time: acquire lock
        else { return true; }                // already locked
        }

    ~locker() {
        b = false;
        }
    };
#define LOCKEM() { \
    static bool reentry_flag = false;\
    locker reentry_lock(reentry_flag);\
    if ( reentry_lock.lock() ) {\
        MainForm->ReentrantErrors->Value ++;\
        return; }\
    }    // Already in this function at an earlier stack level


// This worked but I never used these functions
#ifdef ASSERTINGFUNCTIONS
// An Improved assert() for C++ Builder
// https://edn.embarcadero.com/article/28432
int HandleAsserting(TCHAR *testStr,TCHAR *msgStr,TCHAR *fileStr,int line,int *callFlag);
// https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-debugbreak
// Win XP and newer
// "Ignore non-user breakpoints"  in  Tools > Options > Debugger Options > Embarcadero Debuggers must be false
#ifdef NDEBUG
  #define ASSERTING(p,x) ((void)0)
  #pragma message ("*** COMPILING WITH DEBUG OFF ! (NDEBUG defined) ***")
#else
#define ASSERTING(test, msg) { \
    if (!(test)) { \
      static int callIt=1; \
	  if (callIt) { \
        if (HandleAsserting(TEXT(#test), msg, TEXT(__FILE__), __LINE__, &callIt)) \
          { DebugBreak(); } \
        } \
      } \
    }
#endif
#endif

// Serial Port ID's
#define TIU_PORT 1
#define RFID_PORT 2

// Status line fields
#define TIU_PORT_STATUS 0
#define TIU_STATUS 1
#define RFID_PORT_STATUS 2

#define TAG_READER_BAUD_RATE 115200      // Arduino boards with RFID readers attached 

// SetLayeredWindowAttributes() used to make transparent windows
// There is a work around that involves getting a pointer to the API function at runtime yourself.
// Also you must declare all the macros as well, as your headers will not have them declared.

//https://cboard.cprogramming.com/cplusplus-programming/14240-transparent-windows-setlayeredwindowattributes.html

/* Declare Macros*/
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED           0x00080000
#define LWA_COLORKEY            0x00000001
#define LWA_ALPHA               0x00000002
#endif 

/*typedef a pointer to the API function*/
typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);

// for setting the thread name
typedef struct tagTHREADNAME_INFO
{
	DWORD dwType;        // must be 0x1000
	LPCSTR szName;       // pointer to name (in same addr space)
	DWORD dwThreadID;    // thread ID (-1 caller thread)
	DWORD dwFlags;       // reserved for future use, most be zero
} THREADNAME_INFO;

// Cab Signals
#define HOMESIGNAL 0
#define DISTANTSIGNAL 1

//---------------------------------------------------------------------------
int RXLookUp(unsigned int EncodedWord);
int cvt8B4B(unsigned char b);
int TXLookUp(unsigned char BinaryWord);
int cvt4B8B(unsigned char b);
unsigned char Part1By1(unsigned char x);
unsigned char RXMorton(unsigned char MortonWord);
unsigned char Compact1By1(unsigned char x);
unsigned char TXMorton(unsigned char BinaryWord);

// Forward Declarations
class TEngineInfo;
// original
String __fastcall byteBinaryStringToBinaryString(byte * Cmd, int Count = 4);
String __fastcall byteBinaryStringToASCIIString(byte *, int Count = 4);
String __fastcall byteBinaryStringToHexString(byte * Cmd, int Count = 4);
String __fastcall byteDecodeBinaryString(byte *, int, bool PrinttoCRCBuffer = false);
//new
String __fastcall byteCharacterStringToBinaryString(byte * Cmd, int Count);
void __fastcall byteCharacterStringTobyteHexString(byte * Cmd, byte * Result, int Count);
String __fastcall byteCharacterStringToCharacterString(byte * Cmd, int Count);
//

void __fastcall byteEncodeAString(Cmd * CS);
String __fastcall byteHextoString(byte * str);

// A convenient message dialog for C++ Builder
// Code in Message_Popup.cpp
void MyMessageDlg(TForm *parent, TMsgDlgType DlgType, const char *format, ...);
BOOL askDlg(TForm *parent, BOOL& isCancel, const char *format, ...);

struct AIU_EMU{		 // Flags to indicate an AIU Emulator is attached to an emulated TIU
	bool Found;
    String IP;
	int Port;
    String Name;
	int AIU;
	int Chan;
	};

struct MSG_DISPLAY{		 // Flags to indicate a Message Display is available
	bool Found;
    String IP;
	int Port;
    String Name;
	};

struct SIGNAL{          // Flags to indicate Signal is available
    bool Found;
    String Addr;
    int Port;
    };

struct DETECTOR{        // Flags to indicate Detector is available
    bool Found;
    String Addr;
    int Port;
    int NumReaders;
    };
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// TTcpSrvClient is the class which will be instanciated by server component
// for each new client. N simultaneous clients means N TTcpSrvClient will be
// instanciated. Each being used to handle only a signle client.
// We can add any data that has to be private for each client, such as
// receive buffer or any other data needed for processing.
class TTcpSrvClient : public TWSocketClient
{
public:
	// RcvdLine must be AnsiString because the c_str() taken needs to be a char type.
	AnsiString RcvdLine;
    TDateTime  ConnectTime;
    __fastcall TTcpSrvClient(TComponent* Owner);
};
//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published:	// IDE-managed Components
	TButton *ConnectButton;
	TButton *Send_ASCII_TIU;
	TButton *DisconnectButton;
	TEdit *Encoded_CommandA;
	TButton *ExitButton;
	TStatusBar *StatusBar;
	TButton *WriteRFID;
	TButton *STOPem;
	TEdit *TIU_Char_Count;
	TButton *ResetTIUCCButton;
	TLabel *Label1;
	TButton *ClearRemoteButton;
	TEdit *Encoded_CommandB;
	TButton *Send_Hex_TIU;
	TButton *Encode_TIU;
	TEdit *FileNameSuffix;
	TEdit *FileNamePrefix;
	TEdit *EngNo;
	TLabel *Label6;
	TPopupMenu *RFID_Buffer_Menu;
	TEdit *Command;
	TLabel *Label7;
	TEdit *Data1;
	TLabel *Label8;
	TEdit *Data2;
	TEdit *Data3;
	TEdit *Data4;
	TEdit *D_EngNo;
	TEdit *D_Command;
	TEdit *Seq_Count;
	TLabel *Label9;
	TLabel *Label10;
	TLabel *Label11;
	TLabel *Label12;
	TLabel *Label13;
	TEdit *CRC_LSB;
	TEdit *CRC_MSB;
	TLabel *Label14;
	TLabel *Label15;
    TButton *ReadRFID;
	TMenuItem *PasteIntoRFIDBuffer;
	TMenuItem *CopyIntoRFIDBuffer;
	TOpenDialog *OpenDialog1;
	TSaveDialog *SaveDialog1;
	TMenuItem *SelAllRFIDBuffer;
	TEdit *D_Seq_Count;
	TEdit *D_CRC_LSB;
	TEdit *D_CRC_MSB;
	TEdit *D_Data1;
	TEdit *D_Data2;
	TEdit *D_Data3;
	TEdit *D_Data4;
	TEdit *H_Data2;
	TEdit *H_Data1;
	TEdit *H_Data4;
	TEdit *H_Data3;
	TLabel *ResultWin;
	TEdit *TIU_Remote;
	TEdit *D_TIU_Remote;
	TLabel *Label16;
	TButton *Encode_Remote;
	TButton *Send_Hex_RFID;
	TButton *Send_ASCII_RFID;
	TEdit *H_Seq_Count;
	TLabel *Label19;
	TButton *ClearCRCButton;
	TEdit *H_Command;
	TLabel *Label24;
	TLabel *Label25;
	TLabel *Label26;
	TEdit *H_CRC_LSB;
	TEdit *H_CRC_MSB;
	TLabel *Label27;
	TEdit *H_TIU_Remote;
	TLabel *Label31;
	TLabel *Label32;
	TLabel *Label33;
	TLabel *Label34;
	TLabel *Label35;
	TLabel *Label36;
	TEdit *H_EngNo;
	TLabel *Label23;
	TEdit *A_Command;
	TEdit *A_Data1;
	TEdit *A_Data2;
	TEdit *A_Data3;
	TEdit *A_Data4;
	TEdit *RFID_Char_Count;
	TLabel *Label17;
	TButton *ClearTIUButton;
	TLabel *Label22;
	TLabel *TIUBufferLabel;
	TLabel *RFIDBufferLabel;
	TRichEdit *RFIDBuffer;
	TRichEdit *TIUBuffer;
	TRichEdit *CRCBuffer;
	TCheckBox *PlainTextFile;
	TLabel *Label43;
	TLabel *Label44;
	TButton *ResetRFIDCCButton;
	TLabel *Label38;
	TLabel *Label39;
	TButton *Clear_Decode_Button;
	TLabel *Label45;
	TPopupMenu *CRC_Buffer_Popup_Menu;
	TPopupMenu *TIU_Buffer_Menu;
	TMenuItem *CopyFromCRCBuffer;
	TMenuItem *PasteIntoCRCBuffer;
	TMenuItem *SelectAllCRCBuffer;
	TMenuItem *CopyFromTIUBuffer;
	TMenuItem *PasteIntoTIUBuffer;
	TMenuItem *SelectAllTIUBuffer;
	TMenuItem *AppendCRCBuffertoRemoteBuffer1;
	TMenuItem *CutFromRFIDBuffer;
	TLabel *Label46;
	TLabel *Label47;
    TAbNumSpin *TIUSpin;
	TAbNumSpin *RemoteSpin;
	TAbNumSpin *EngineSpin;
	TButton *SoundCtrlsButton;
	TButton *SetupButton;
    TAbLED *ConnectedWiFiRadioLED;
	TAbLED *ConnectedRFIDLED;
	TImage *Copyright;
    TBevel *Bevel1;
    TButton *OpButton;
	TButton *StartupButton;
	TButton *ShutdownButton;
	TEdit *Last_Response;
	TEdit *NameofEngine;
	TPopupMenu *EngineDataPopupMenu;
	TMenuItem *EditEngineName;
	TButton *ReadEnginesButton;
	TAbNumSpin *AIUSpin;
	TLabel *Label18;
	TLabel *Label3;
	TButton *AIUButton;
	TLabel *Label4;
	TAbColBitBtn *ESTOP;
	TLabel *Hidden;
	TLabel *Label5;
	TEdit *Last_Response_Decoded;
	TMenuItem *EditEngineNumber;
	TMenuItem *DeleteEngine;
	TMenuItem *DecodeTIUBuffer;
	TMenuItem *DecodeTIUBuffer1;
	TLabel *Date_Time;
	TButton *WriteTIU;
	TButton *ReadTIU;
	TMenuItem *UndoRFIDBuffer;
	TMenuItem *UndoTIUBuffer;
	TMenuItem *UndoCRCBuffer;
	TEdit *Last_Message;
	TMenuItem *DecodeTIUBufferCommand;
	TMenuItem *DecodeTIUBufferString;
	TAbNumEdit *PacketsSent;
	TAbNumEdit *Retries;
	TAbNumEdit *NAKLen;
	TAbNumEdit *NAKShort;
	TLabel *Label21;
    TLabel *RetriesCountLabel;
	TLabel *Label29;
	TLabel *Label30;
	TAbNumEdit *sendDataBusy;
	TLabel *BusyLabel;
	TLabel *Label37;
	TMenuItem *SaveCRC;
	TButton *StopAllButton;
	TImageList *ToolbarList5;
	TAbNumEdit *ReentrantErrors;
	TLabel *Label20;
    TButton *DecodeLast_ResponseButton;
	TAbNumEdit *CaughtErrors;
	TLabel *Label40;
	TAbNumEdit *Tags;
	TLabel *Label48;
	TButton *LashUpButton;
	TAbNumEdit *NAK0T;
	TLabel *Label49;
	TLabel *Label50;
	TAbNumEdit *NAKCRC;
	TButton *ResetSetupButton;
	TMenuItem *SetEngineintoCommandMode;
	TMenuItem *SetEngineintoLegacyMode;
	TMenuItem *SetEngineintoConventionalMode;
	TPopupMenu *RTCPopupMenu;
	TMenuItem *DCSSetup1;
	TMenuItem *AboutRTC;
	TMenuItem *ResetSetupOptions1;
	TTimer *IdleTimer;
	TButton *QuickButton;
	TMenuItem *SetEngineActive1;
	TMenuItem *SetEngineInactive1;
	TLabel *ProgName;
	TMenuItem *MuteAll;
	TPopupMenu *EStopPopupMenu;
	TMenuItem *StopAll1;
	TMenuItem *StartupAll1;
    TMenuItem *StartupActiveEngines1;
	TMenuItem *ShutdownAllEngines1;
	TAbNumEdit *DL_FIFO_Count;
	TLabel *Label41;
	TMenuItem *EditTIUNumber1;
	TMenuItem *SaveTIUtoFile;
	TMenuItem *SaveRFIDtoDisk1;
	TAbNumEdit *EngNotFound;
	TLabel *Label42;
	TAbNumEdit *StartedConsists;
    TLabel *StartedCountLabel;
	TMenuItem *RTCHelpMenu;
	TMenuItem *SetAllEnginesActive;
	TMenuItem *SetupActivateRoutesandScenes1;
	TButton *RSButton;
	TImageList *OnOffImageList;
	TPopupMenu *EditEngineNumberPopupMenu;
	TMenuItem *EditEngineNumber1;
	TPopupMenu *EditTIUNumberPopupMenu;
	TMenuItem *EditTIUNumber2;
	TActionList *ActionList1;
	TAction *EditEngineNumberAction;
	TAction *EditTIUNumberAction;
	TButton *WriteCRC;
	TImageList *ToolbarList4;
	TPageControl *DebugPageControl;
	TTabSheet *WorkingTabSheet;
	TButton *DebugButton;
	TButton *UtilitiesButton;
	TButton *InfoButton;
	TButton *FeatureResetButton;
	TButton *FactoryResetButton;
	TButton *DCSSetup;
	TTabSheet *InfoTabSheet;
	TLabel *AccLabel;
	TLabel *DecLabel;
	TButton *ADButton;
	TButton *I0Button;
	TButton *DTVButton;
	TButton *TIUVerButton;
	TButton *AIUCountButton;
	TButton *DODButton;
	TButton *DTOButton;
	TButton *DCHButton;
	TTabSheet *DebugTabSheet;
    TButton *CMDButton;
	TButton *RelaySoundButton;
	TButton *TMCCButton;
	TButton *TIUFeatureResetButton;
	TButton *TIUFactoryResetButton;
	TTabSheet *MiscTabSheet;
	TPopupMenu *StartupPopupMenu;
	TMenuItem *AlreadyStarted;
    TMenuItem *StartupActiveEngines2;
	TMenuItem *RTCWebPage1;
	TButton *HotButton;
	TButton *HotCommandButton;
	TAbNumEdit *TIU_Total_Byte_Count;
	TLabel *Label52;
	TLabel *Label53;
	TPopupMenu *HotButtonPopup;
	TMenuItem *HotButtons1;
	TMenuItem *HotButtons2;
	TMenuItem *HotButtons3;
	TMenuItem *HotButtons4;
	TMenuItem *HotButtons5;
	TButton *ReadEEPROMButton;
	TMenuItem *EngineInformation1;
	TButton *FRMButton;
	TMenuItem *RestorethescrollbarontheEngineList1;
	TButton *DecodeStringsButton;
	TMenuItem *CutFromTIUBuffer;
	TMenuItem *CutFromCRCBuffer;
	TButton *BatteryStatusButton;
	TAbNumEdit *Dispatched_Cmd_Count;
	TLabel *Label2;
	TButton *Var1ModeButton;
	TButton *Var2ModeButton;
	TButton *Prog_Control_Button;
	TMenuItem *VariableControls1;
	TMenuItem *Channel1;
	TMenuItem *Channel2;
	TMenuItem *SetAllEnginesInactive;
	TAbNumEdit *FIFO_Count;
	TLabel *Label54;
	TLabel *Label55;
	TAbNumEdit *DL_FIFO_Total;
    TAbNumEdit *ActiveEngineCount;
    TAbNumEdit *InactiveEngineCount;
    TLabel *ActiveCountLabel;
    TLabel *InActiveCountLabel;
	TMenuItem *EngineStatus1;
	TButton *DumpMemoryButton;
	TAbNumSpin *FirstLine;
	TAbNumSpin *LastLine;
	TMenuItem *SetEnginePS2;
	TMenuItem *SetEnginePS3;
	TLabel *Label58;
	TLabel *Label59;
	TButton *VButton;
	TButton *ComponentButton;
	TMenuItem *EmailAuthor;
	TRichEdit *RecordingBuffer;
	TPopupMenu *RecordingBufferPopupMenu;
	TMenuItem *ExpandRecordingBuffer;
	TMenuItem *ShrinkRecordingBuffer;
	TPopupMenu *PCPopupMenu;
	TMenuItem *ProgramControl1;
	TButton *BreakButton;
	TComboBox *CarModelComboBox;
	TComboBox *EngineModelComboBox;
	TComboBox *RailroadNameComboBox;
	TButton *ComboBoxButton;
	TComboBox *TagLocationComboBox;
	TComboBox *CouplerComboBox;
	TComboBox *EngineTypeComboBox;
	TPopupMenu *AIUPopupMenu;
	TMenuItem *AIUControl1;
	TMenuItem *AIUControl2;
	TMenuItem *AIUControl3;
	TMenuItem *AIUControl4;
	TMenuItem *AIUControl5;
	TMenuItem *FactoryReset1;
	TMenuItem *FeatureReset1;
	TMenuItem *TIUFactoryReset1;
	TMenuItem *TIUFeatureReset1;
	TMenuItem *EngineTrackSignal1;
	TMenuItem *ShowDetectedTags;
	TPopupMenu *ReadPopupMenu;
    TMenuItem *AddFactoryResetEngine;
	TMenuItem *PrintthisWindow1;
	TMenuItem *ShowLayoutWindow;
	TButton *EngTypeButton;
	TButton *EngType2Button;
    TWSocket *RFIDudpRX;
	TAbLED *ConnectedTIULED;
	TMenuItem *MarksTrainLayouts1;
	TButton *RegButton;
	TPopupMenu *TIUPopupMenu;
	TMenuItem *TIU11;
	TMenuItem *TIU21;
	TMenuItem *TIU31;
	TMenuItem *TIU41;
	TMenuItem *TIU51;
	TMenuItem *SaveSetupOptions;
	TMenuItem *TIU61;
	TMenuItem *TIU71;
	TMenuItem *AIU6Control1;
	TMenuItem *AIU7Control1;
	TMenuItem *TIU81;
	TMenuItem *AIU8Control1;
	TMenuItem *AIU9Control1;
	TMenuItem *AIU10Control1;
    TCheckBox *RFIDLog;
    TCheckBox *TIULog;
    TLabel *Label60;
    TLabel *TIULineCount;
    TWSocketServer *RFIDtcpRX;
    TAbNumEdit *NumDetectors;
    TLabel *DetLabel;
    TLabel *RdrLabel;
    TAbNumEdit *NumReaders;
    TPageControl *LEDPageControl;
    TTabSheet *LEDTabSheet;
    TTabSheet *CRCTabSheet;
    TTabSheet *SerialTabSheet;
    TRadioGroup *CRCSel;
    TButton *ProcessCRCButton;
    TAbLED *Break;
    TAbLED *Err;
    TAbLED *CD;
    TAbLED *DSR;
    TAbLED *CTS;
    TAbLED *Ring;
    TEdit *CTS_Counter;
    TEdit *DSR_Counter;
    TEdit *CD_Counter;
    TAbRockerSwitch *RTSSwitch;
    TAbRockerSwitch *DTRSwitch;
    TAbLED *StatusLED1;
    TAbLED *StatusLED2;
    TAbLED *SpareLED1;
    TAbLED *StatusLED5;
    TAbLED *StatusLED6;
    TAbLED *StatusLED8;
    TAbLED *CommThreadLED;
    TAbLED *TimerThreadLED;
    TAbLED *DLThreadLED;
    TAbLED *mDNSLED;
    TButton *LayoutPowerOffButton;
    TButton *LayoutPowerOnButton;
    TButton *QButton;
    TLabel *Engine_List_Label;
    TUpDown *EngineUpDown;
    TStringGrid *EngineData;
    TMenuItem *OpenPopOutEngineList1;
    TPopupMenu *SetupPopupMenu;
    TMenuItem *OpentheActiveTIUSelectionWindow;
    TMenuItem *OpentheSuperTIUModeWindow;
    TAbNumEdit *WiFiTO;
    TAbNumEdit *CKSum;
    TLabel *Label64;
    TLabel *Label65;
    TButton *QualityButton;
    TMenuItem *ViewStartFolder;
    TButton *FindEnginesButton;
    TMenuItem *ShowWatchdogTIUSpinnerMenuItem;
    TMenuItem *ShowWatchdogMenuItem;
    TMenuItem *EditTIUNumber;
    TButton *IxxxButton;
    TButton *I1xxButton;
    TMenuItem *TIUVersion1;
    TAbNumEdit *WiFiTIUCount;
    TLabel *WTIUCountLabel;
    TButton *FBSButton1;
    TButton *FPRButton1;
    TMenuItem *DisplayVar1;
    TMenuItem *DisplayVar2;
    TMenuItem *DCSSetupforSelectedTIU1;
    TStringGrid *ActEngLst;
    TUpDown *ActEngUpDown;
    TCheckBox *ActEngChckBox;
    TLabel *SigLabel;
    TAbNumEdit *NumSignals;

	void __fastcall Send_ASCII_TIUClick(TObject *Sender);
	void __fastcall DisconnectButtonClick(TObject *Sender);
	void __fastcall ExitButtonClick(TObject *Sender);
	void __fastcall WritetoDiskClick(TObject *Sender);
	void __fastcall STOPemClick(TObject *Sender);
	void __fastcall ResetTIUCCButtonClick(TObject *Sender);
	void __fastcall ClearRemoteButtonClick(TObject *Sender);
	void __fastcall Send_Hex_TIUClick(TObject *Sender);
	void __fastcall ReadfromDiskClick(TObject *Sender);
	void __fastcall PasteIntoRFIDBufferClick(TObject *Sender);
	void __fastcall CopyIntoRFIDBufferClick(TObject *Sender);
	void __fastcall SendHexFromRemoteBufferClick(TObject *Sender);
	void __fastcall ExpandRemoteCommandClick(TObject *Sender);
	void __fastcall ExpandRemoteBufferClick(TObject *Sender);
	void __fastcall SelAllRFIDBufferClick(TObject *Sender);
	void __fastcall Encode_TIUClick(TObject *Sender);
	void __fastcall Encode_RemoteClick(TObject *Sender);
	void __fastcall Send_Hex_RFIDClick(TObject *Sender);
	void __fastcall Send_ASCII_RFIDClick(TObject *Sender);
	void __fastcall DecodeCommandBufferClick(TObject *Sender);
	void __fastcall DecodeCommandClick(TObject *Sender);
	void __fastcall ProcessCRCButtonClick(TObject *Sender);
	void __fastcall ClearCRCButtonClick(TObject *Sender);
	void __fastcall ProcessCRCIntoCRCBufferClick(TObject *Sender);
	void __fastcall H_Seq_CountChange(TObject *Sender);
	void __fastcall H_CommandChange(TObject *Sender);
	void __fastcall H_EngNoChange(TObject *Sender);
	void __fastcall H_TIU_RemoteChange(TObject *Sender);
	void __fastcall H_CRC_LSBChange(TObject *Sender);
	void __fastcall H_CRC_MSBChange(TObject *Sender);
	void __fastcall H_Data1Change(TObject *Sender);
	void __fastcall H_Data2Change(TObject *Sender);
	void __fastcall H_Data3Change(TObject *Sender);
	void __fastcall H_Data4Change(TObject *Sender);
	void __fastcall ClearTIUButtonClick(TObject *Sender);
	void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
	void __fastcall ResetRFIDCCButtonClick(TObject *Sender);
	void __fastcall Clear_Decode_ButtonClick(TObject *Sender);
	void __fastcall CopyFromCRCBufferClick(TObject *Sender);
	void __fastcall PasteIntoCRCBufferClick(TObject *Sender);
	void __fastcall SelectAllCRCBufferClick(TObject *Sender);
	void __fastcall CopyFromTIUBufferClick(TObject *Sender);
	void __fastcall PasteIntoTIUBufferClick(TObject *Sender);
	void __fastcall SelectAllTIUBufferClick(TObject *Sender);
	void __fastcall CutFromRFIDBufferClick(TObject *Sender);
	void __fastcall AppendCRCBuffertoRemoteBuffer1Click(TObject *Sender);
	void __fastcall DecodeStringClick(TObject *Sender);
	void __fastcall DecodeStringBufferClick(TObject *Sender);
	void __fastcall RTSSwitchClick(TObject *Sender);
	void __fastcall DTRSwitchClick(TObject *Sender);
	void __fastcall UtilitiesButtonClick(TObject *Sender);
	void __fastcall SoundCtrlsButtonClick(TObject *Sender);
	void __fastcall SetupButtonClick(TObject *Sender);
    void __fastcall DebugButtonClick(TObject *Sender);
    void __fastcall OpButtonClick(TObject *Sender);
	void __fastcall StartupButtonClick(TObject *Sender);
	void __fastcall ShutdownButtonClick(TObject *Sender);
	void __fastcall EditEngineNameClick(TObject *Sender);
	void __fastcall EngineDataPopupMenuPopup(TObject *Sender);
	void __fastcall EngineDataDrawCell(TObject *Sender, int ACol, int ARow,
          TRect &Rect, TGridDrawState State);
	void __fastcall EngineDataKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
	void __fastcall ReadEnginesButtonClick(TObject *Sender);
	void __fastcall AIUButtonClick(TObject *Sender);
	void __fastcall ESTOPClick(TObject *Sender);
	void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
	void __fastcall HiddenDblClick(TObject *Sender);
	void __fastcall AIUCountButtonClick(TObject *Sender);
	void __fastcall ADButtonClick(TObject *Sender);
	void __fastcall EditEngineNumberClick(TObject *Sender);
	void __fastcall DeleteEngineClick(TObject *Sender);
	void __fastcall FactoryResetButtonClick(TObject *Sender);
	void __fastcall UndoRFIDBufferClick(TObject *Sender);
	void __fastcall UndoTIUBufferClick(TObject *Sender);
	void __fastcall UndoCRCBufferClick(TObject *Sender);
	void __fastcall I0ButtonClick(TObject *Sender);
	void __fastcall EngineSpinValueChanged(TObject *Sender);
	void __fastcall SaveCRCClick(TObject *Sender);
	void __fastcall DTVButtonClick(TObject *Sender);
	void __fastcall DecodeLast_ResponseButtonClick(TObject *Sender);
	void __fastcall TIUVerButtonClick(TObject *Sender);
	void __fastcall VarModeButtonClick(TObject *Sender);
	void __fastcall DCSSetupClick(TObject *Sender);
	void __fastcall LashUpButtonClick(TObject *Sender);
	void __fastcall InfoButtonClick(TObject *Sender);
	void __fastcall FeatureResetButtonClick(TObject *Sender);
	void __fastcall ResetSetupButtonClick(TObject *Sender);
	void __fastcall SetEngineintoCommandModeClick(TObject *Sender);
	void __fastcall SetEngineintoLegacyModeClick(TObject *Sender);
	void __fastcall SetEngineintoConventionalModeClick(TObject *Sender);
	void __fastcall BatteryStatusButtonClick(TObject *Sender);
	void __fastcall DTOButtonClick(TObject *Sender);
	void __fastcall TMCCButtonClick(TObject *Sender);
	void __fastcall IdleTimerTimer(TObject *Sender);
	void __fastcall DTRSwitchStatusChanged(TObject *Sender);
	void __fastcall RTSSwitchStatusChanged(TObject *Sender);
	void __fastcall QuickButtonClick(TObject *Sender);
	void __fastcall SetEngineActive1Click(TObject *Sender);
	void __fastcall SetEngineInactive1Click(TObject *Sender);
	void __fastcall CMDButtonClick(TObject *Sender);
	void __fastcall RelaySoundButtonClick(TObject *Sender);
	void __fastcall TIUFeatureResetButtonClick(TObject *Sender);
	void __fastcall TIUFactoryResetButtonClick(TObject *Sender);
	void __fastcall StopAllButtonClick(TObject *Sender);
	void __fastcall DODButtonClick(TObject *Sender);
	void __fastcall FormShow(TObject *Sender);
	void __fastcall StartupActiveEngines1Click(TObject *Sender);
	void __fastcall ShutdownAllEngines1Click(TObject *Sender);
	void __fastcall MuteAllClick(TObject *Sender);
	void __fastcall DCHButtonClick(TObject *Sender);
	void __fastcall EditTIUNumber1Click(TObject *Sender);
	void __fastcall RTCHelpMenuClick(TObject *Sender);
	void __fastcall SetAllEnginesActiveClick(TObject *Sender);
	void __fastcall RSButtonClick(TObject *Sender);
	void __fastcall SetupActivateRoutesandScenes1Click(TObject *Sender);
	void __fastcall EngineDataDblClick(TObject *Sender);
	void __fastcall StartupActiveEngines2Click(TObject *Sender);
	void __fastcall AlreadyStartedClick(TObject *Sender);
	void __fastcall RTCWebPage1Click(TObject *Sender);
	void __fastcall HotButtonClick(TObject *Sender);
	void __fastcall HotButtons1Click(TObject *Sender);
	void __fastcall HotButtons2Click(TObject *Sender);
	void __fastcall HotButtons3Click(TObject *Sender);
	void __fastcall HotButtons4Click(TObject *Sender);
	void __fastcall HotButtons5Click(TObject *Sender);
	void __fastcall ReadEEPROMButtonClick(TObject *Sender);
	void __fastcall CopyrightClick(TObject *Sender);
	void __fastcall EngineInformation1Click(TObject *Sender);
	void __fastcall FRMButtonClick(TObject *Sender);
	void __fastcall EngineUpDownClick(TObject *Sender, TUDBtnType Button);
	void __fastcall RestorethescrollbarontheEngineList1Click(TObject *Sender);
	void __fastcall DecodeStringsButtonClick(TObject *Sender);
	void __fastcall CutFromTIUBufferClick(TObject *Sender);
	void __fastcall CutFromCRCBufferClick(TObject *Sender);
	void __fastcall FormDeactivate(TObject *Sender);
	void __fastcall FormActivate(TObject *Sender);
	void __fastcall Engine_List_LabelClick(TObject *Sender);
	void __fastcall Prog_Control_ButtonClick(TObject *Sender);
	void __fastcall AIUSpinValueChanged(TObject *Sender);
	void __fastcall RemoteSpinValueChanged(TObject *Sender);
	void __fastcall ConnectButtonClick(TObject *Sender);
	void __fastcall Channel1Click(TObject *Sender);
	void __fastcall Channel2Click(TObject *Sender);
	void __fastcall SetAllEnginesInactiveClick(TObject *Sender);
	void __fastcall EngineStatus1Click(TObject *Sender);
	void __fastcall DumpMemoryButtonClick(TObject *Sender);
	void __fastcall FirstLineValueChanged(TObject *Sender);
	void __fastcall LastLineValueChanged(TObject *Sender);
	void __fastcall SetEnginePS2Click(TObject *Sender);
	void __fastcall SetEnginePS3Click(TObject *Sender);
	void __fastcall EngineDataMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
	void __fastcall EngineDataClick(TObject *Sender);
	void __fastcall VButtonClick(TObject *Sender);
	void __fastcall ComponentButtonClick(TObject *Sender);
	void __fastcall EmailAuthorClick(TObject *Sender);
	void __fastcall ShrinkRecordingBufferClick(TObject *Sender);
	void __fastcall ExpandRecordingBufferClick(TObject *Sender);
	void __fastcall ProgramControlClick(TObject *Sender);
	void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
	void __fastcall BreakButtonClick(TObject *Sender);
	void __fastcall ComboBoxButtonClick(TObject *Sender);
	void __fastcall NameofEngineChange(TObject *Sender);
	void __fastcall NameofEngineExit(TObject *Sender);
	void __fastcall NameofEngineKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
	void __fastcall AIUControl1Click(TObject *Sender);
	void __fastcall AIUControl2Click(TObject *Sender);
	void __fastcall AIUControl3Click(TObject *Sender);
	void __fastcall AIUControl4Click(TObject *Sender);
	void __fastcall AIUControl5Click(TObject *Sender);
	void __fastcall ShowDetectedTagsClick(TObject *Sender);
	void __fastcall EngineTrackSignal1Click(TObject *Sender);
	void __fastcall AddFactoryResetEngineClick(TObject *Sender);
	void __fastcall PrintthisWindow1Click(TObject *Sender);
	void __fastcall ShowLayoutWindowClick(TObject *Sender);
	void __fastcall QButtonClick(TObject *Sender);
	void __fastcall EngTypeButtonClick(TObject *Sender);
	void __fastcall EngType2ButtonClick(TObject *Sender);
	void __fastcall RFIDudpRXChangeState(TObject *Sender, TSocketState OldState,
          TSocketState NewState);
	void __fastcall RFIDudpRXSessionConnected(TObject *Sender, WORD ErrCode);
	void __fastcall RFIDudpRXSessionClosed(TObject *Sender, WORD ErrCode);
	void __fastcall RFIDudpRXDataAvailable(TObject *Sender, WORD ErrCode);
	void __fastcall MarksTrainLayouts1Click(TObject *Sender);
	void __fastcall RegButtonClick(TObject *Sender);
	void __fastcall TIU11Click(TObject *Sender);
	void __fastcall TIU21Click(TObject *Sender);
	void __fastcall TIU31Click(TObject *Sender);
	void __fastcall TIU41Click(TObject *Sender);
	void __fastcall TIU51Click(TObject *Sender);
	void __fastcall TIU61Click(TObject *Sender);
	void __fastcall TIU71Click(TObject *Sender);
	void __fastcall AIU6Control1Click(TObject *Sender);
	void __fastcall AIU7Control1Click(TObject *Sender);
	void __fastcall AIU8Control1Click(TObject *Sender);
	void __fastcall AIU9Control1Click(TObject *Sender);
	void __fastcall AIU10Control1Click(TObject *Sender);
	void __fastcall TIU81Click(TObject *Sender);
    void __fastcall TIULineCountClick(TObject *Sender);
    void __fastcall RFIDtcpRXChangeState(TObject *Sender,
          TSocketState OldState, TSocketState NewState);
    void __fastcall RFIDtcpRXSessionClosed(TObject *Sender, WORD ErrCode);
    void __fastcall RFIDtcpRXSessionConnected(TObject *Sender, WORD ErrCode);
    void __fastcall RFIDtcpRXDataAvailable(TObject *Sender, WORD ErrCode);
    void __fastcall RFIDtcpRXClientConnect(TObject *Sender,
          TWSocketClient *Client, WORD Error);
    void __fastcall RFIDtcpRXClientDisconnect(TObject *Sender,
          TWSocketClient *Client, WORD Error);
    void __fastcall RFIDtcpRXBgException(TObject *Sender, Exception *E,
          bool &CanClose);
    void __fastcall RFIDtcpRXSessionAvailable(TObject *Sender, WORD ErrCode);
    void __fastcall NumDetectorsClick(TObject *Sender);
    void __fastcall LayoutPowerOffButtonClick(TObject *Sender);
    void __fastcall LayoutPowerOnButtonClick(TObject *Sender);
    void __fastcall TIUSpinValueChanged(TObject *Sender);
    void __fastcall OpenPopOutEngineList1Click(TObject *Sender);
    void __fastcall OpentheActiveTIUSelectionWindowClick(TObject *Sender);
    void __fastcall OpentheSuperTIUModeWindowClick(TObject *Sender);
    void __fastcall TIUSpinChange(TObject *Sender);
    void __fastcall AIUSpinChange(TObject *Sender);
    void __fastcall QualityButtonClick(TObject *Sender);
    void __fastcall ViewStartFolderClick(TObject *Sender);
    void __fastcall FindEnginesButtonClick(TObject *Sender);
    void __fastcall ShowWatchdogTIUSpinnerMenuItemClick(TObject *Sender);
    void __fastcall ShowWatchdogMenuItemClick(TObject *Sender);
    void __fastcall EditTIUNumberPopupMenuPopup(TObject *Sender);
    void __fastcall FormKeyUp(TObject *Sender, WORD &Key,
          TShiftState Shift);
    void __fastcall EditTIUNumberClick(TObject *Sender);
    void __fastcall IxxxButtonClick(TObject *Sender);
    void __fastcall I1xxButtonClick(TObject *Sender);
    void __fastcall FBSButton1Click(TObject *Sender);
    void __fastcall FPRButton1Click(TObject *Sender);
    void __fastcall DisplayVarClick(TObject *Sender);
    void __fastcall ActEngUpDownClick(TObject *Sender, TUDBtnType Button);
    void __fastcall ActEngLstClick(TObject *Sender);
    void __fastcall ActEngLstDblClick(TObject *Sender);
    void __fastcall ActEngLstDrawCell(TObject *Sender, int ACol, int ARow,
          TRect &Rect, TGridDrawState State);
    void __fastcall ActEngLstKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
    void __fastcall ActEngLstMouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
    void __fastcall ActEngChckBoxClick(TObject *Sender);

protected:
	// Message Routines
    void __fastcall CMShutDown(TMessage &Message);
	void __fastcall CMEmergencyStop(TMessage &Message);
    void __fastcall CMLashUpStartUp(TMessage &Message);
    void __fastcall CMLashUpShutdown(TMessage &Message);
    void __fastcall CMLashUpSoundCtrls(TMessage &Message);
    void __fastcall CMTMCCShutdown(TMessage &Message);
    void __fastcall CMTIUChar(TMessage &Message);
    void __fastcall CMTIUASCIIChar(TMessage &Message);
    void __fastcall CMRFIDASCIIChar(TMessage &Message);
    void __fastcall CMTIUComm(TMessage &Message);
    void __fastcall CMSoundControl(TMessage &Message);
    void __fastcall CMOpControl(TMessage &Message);
    void __fastcall CMRadioCOMStatus(TMessage &Message);
    void __fastcall CMRFIDCOMStatus(TMessage &Message);
    void __fastcall CMUI(TMessage &Message);
    void __fastcall CMProcessRFIDData(TMessage &Message);
    void __fastcall CMHotCom(TMessage &Message);
    void __fastcall CMAIU(TMessage &Message);
    void __fastcall CMPCWindowOpen(TMessage &Message);
    void __fastcall CMQuick(TMessage &Message);
    void __fastcall CMProcessRadioData(TMessage &Message);
    void __fastcall CMSendWiFiPacket(TMessage &Message);
    void __fastcall CMShowWatchdog(TMessage &Message);
    void __fastcall CMSendWatchdog(TMessage &Message);

    BEGIN_MESSAGE_MAP
    	MESSAGE_HANDLER(CM_SHUTDOWN, TMessage, CMShutDown)
    	MESSAGE_HANDLER(CM_EMERGENCYSTOP, TMessage, CMEmergencyStop)
       	MESSAGE_HANDLER(CM_LASHUPSTARTUP, TMessage, CMLashUpStartUp)
        MESSAGE_HANDLER(CM_LASHUPSHUTDOWN, TMessage, CMLashUpShutdown)
       	MESSAGE_HANDLER(CM_LASHUPSOUNDCTRLS, TMessage, CMLashUpSoundCtrls)
       	MESSAGE_HANDLER(CM_TMCCSHUTDOWN, TMessage, CMTMCCShutdown)
        MESSAGE_HANDLER(CM_TIUCHAR, TMessage, CMTIUChar)
        MESSAGE_HANDLER(CM_TIUASCIICHAR, TMessage, CMTIUASCIIChar)
        MESSAGE_HANDLER(CM_RFIDASCIICHAR, TMessage, CMRFIDASCIIChar)
        MESSAGE_HANDLER(CM_TIUCOMM, TMessage, CMTIUComm)
        MESSAGE_HANDLER(CM_SOUNDCONTROL, TMessage, CMSoundControl)
        MESSAGE_HANDLER(CM_OPCONTROL, TMessage, CMOpControl)
        MESSAGE_HANDLER(CM_RADIOCOMSTATUS, TMessage, CMRadioCOMStatus)
        MESSAGE_HANDLER(CM_RFIDCOMSTATUS, TMessage, CMRFIDCOMStatus)
        MESSAGE_HANDLER(CM_UI, TMessage, CMUI)
        MESSAGE_HANDLER(CM_PROCESSRFIDDATA, TMessage, CMProcessRFIDData)
        MESSAGE_HANDLER(CM_HOTCOM, TMessage, CMHotCom)
        MESSAGE_HANDLER(CM_AIU, TMessage, CMAIU)
        MESSAGE_HANDLER(CM_PCWINDOWOPEN, TMessage, CMPCWindowOpen)
        MESSAGE_HANDLER(CM_QUICK, TMessage, CMQuick)
        MESSAGE_HANDLER(CM_PROCESSRADIODATA, TMessage, CMProcessRadioData)
        MESSAGE_HANDLER(CM_SENDWIFIPACKET, TMessage, CMSendWiFiPacket)
        MESSAGE_HANDLER(CM_SHOWWATCHDOG, TMessage, CMShowWatchdog)
        MESSAGE_HANDLER(CM_SENDWATCHDOG, TMessage, CMSendWatchdog)
    END_MESSAGE_MAP(TForm)

private:	// User declarations
	bool __fastcall DecodeMyCommand(String);
    unsigned int __fastcall CRCEvaluation(Cmd *, int , int, bool);
    unsigned int __fastcall crc752(byte message[], byte nBytes, bool Direction);
    bool __fastcall PrintCommandString(String);
    void __fastcall DecodePrint(String);
    void __fastcall PrintCommand(void);
    int __fastcall CreateCommandString(Cmd *);
	String __fastcall ExpandCommand(String);
	String __fastcall CleanUpCommand(String);
    int ChannelNo;

    bool CommandDecoded;
    void __fastcall ClearDecode();
//------------------
	String __fastcall sExtractEngineName(String);
    String __fastcall sEncodedStringToASCIIString(String);
    String __fastcall sEncodedStringToBinaryString(String);
    String __fastcall sEncodedStringToHexString(String);
	void __fastcall sBinaryDump(String Response, String);
	String __fastcall byteExtractEngineName(byte * Cmd);
//------------------
    void __fastcall CloseAllWindows(void);
	void __fastcall SetRadioGroup (TRadioGroup *, int);

	void __fastcall SetSlider (TAbVSlider *, float);
	void __fastcall SetLED (TAbLED *, int);
	void __fastcall SetToggle(TAbToggleSwitch *, int);
    void __fastcall SetNumSpin(TAbNumSpin *, int);

	unsigned int __fastcall EncodedStringToDecimalInt(String, int, int);

    void __fastcall LoadEngineData(TStringGrid * ED);
    void __fastcall SaveEngineData(TStringGrid * ED);
    int __fastcall ValidateEngineData(TStringGrid * ED, int EngNum);

    void __fastcall OpenSoundControl(int Consist, int TIU);

    int __fastcall OneBitsinBinaryString(String);
    int __fastcall OneBitsinHexString(String);

	String TXMsg;

    unsigned char  __fastcallHexStringtoInt(unsigned char *);

    int SavedDebugHeight, SavedDebugWidth;

    bool __fastcall GetTIUNoAIUCount(int);
    bool __fastcall GetTIUVer(int);
	void __fastcall StartUpVarControl(int Chan);
	//
	void __fastcall DoHotButton(TObject *Sender, int Page);
    void __fastcall DoQuickButton(int NewPageNo);
    void __fastcall ShowWatchdogButton(int NewTIUNo, int NewEngineNo);
   	void __fastcall MyIdleHandler(TObject *Sender, bool &Done);

    bool LocalTransparencyOverride;

    void __fastcall StartProgramControl(TObject *Sender, int PCNo);
    void __fastcall StartAIUControl(TObject *Sender, int iTIUNo, int iAIUNo);

    #ifdef NOTNEEDED
    #if __BORLANDC__ >= 0x720
	// Defined for CB10.1 C++ programs that use the VCL.
  	//Overbyteicswinsock::TInAddr FServerAddr;
    #else
    //TInAddr FServerAddr;
    #endif
	#endif

	int NewTop, NewLeft;

	void __fastcall (__closure *SpeedSliderOnValueChange)(TObject *Sender);

    void __fastcall FillActEngLst(void);    // CKR

public:		// User declarations
	__fastcall TMainForm(TComponent* Owner);
    __fastcall ~TMainForm(void);
    int iSS;		// Splash Window if == 1
    bool DebugCommandLine;

	// debug enabled flag and debug level
    bool bDebug;
	int GlobalDBLevel;
	// global MPH Scaling
	int GlobalMPHScaling;
    //
    String RegFileRootKey;
    TCHAR cStartDir[MAX_PATH];	// Directory for *.ini files
    String WorkingDir;			// Directory for save/load file Dialogs
	String ConnectMsg, DisconnectMsg, TIUVerMsg, WTIUOnlyMsg;
    String WTIUMsg, TIUActiveMsg, TIUNoLashupMsg, TIUNoEngineMsg, TIUSelMsg, RFIDWiFiMsg;
    //
    // used by Op_Control
   	void __fastcall SetSwitch (TAbRockerSwitch *, int);
	void __fastcall SetComboBox (TComboBox *, int);
    
    String __fastcall sDecodeString(String, bool);

    bool __fastcall IsTIUConnected();
    
	bool __fastcall IsRFIDCOMConnected(void);
    bool __fastcall IsRadioCOMConnected(void);
	bool __fastcall IsRFIDWiFiConnected(void);
    bool __fastcall IsRadioConnected();
	bool __fastcall IsRFIDConnected();
    bool __fastcall IsWTIUWiFiConnected();

    bool bPlayingBack, bPlaybackCommError, bRecording;
    int iPlayingBackCounter;

    void __fastcall Delay(DWORD dwDelayMs);

    int iSavedHeight, iSavedWidth;	// used by Debug_Controls.cpp

    void __fastcall SetConsistState(int Consist, int State);	// used by LashUp_Selection.cpp
    int __fastcall QueryConsistState(int Consist);
    bool __fastcall IsConsistRunning(int Consist);
    
    bool __fastcall IsLashUpRunning(int LUNo);
    void __fastcall LashUpShow(int LashUp);

	bool bSaveRegistryInfo;

    void __fastcall DebugMessagePopup(String Caption, String MessageLine, String StatusLine = "", int dly = UIPOPUPTIMEOUT);
    void __fastcall DebugMessage(String MessageLine, String Caption = "Information", String StatusLine = "", int dly = UIPOPUPTIMEOUT);

   	void __fastcall EmergencyStopAllEngines(void);
   	bool __fastcall ValidCommand(String);

    bool bEngineDataCorrupt, bEngineDataLoaded;
	void __fastcall MyProcessMessages(void);
	void __fastcall charstringtobinary(char * Command, char * Packet, int Len);

	unsigned int __fastcall CRCGen(Cmd *, int, int, bool);
    unsigned int __fastcall CRCCheck(Cmd *, int , int, bool);
    unsigned int __fastcall CRCEvaluation(byte *, int , int, bool);
	void __fastcall byteBinaryDump(byte * Response, String);
    bool __fastcall Query(char *, byte * QBuf, int Engine, int TIU, int Remote);
    DWORD TIUPortCE, RFIDPortCE;

   	bool __fastcall GetAccDecValues(int, int, int *, int *);
    bool EncodedRecordFormat;	// copy of switch on setup screen

	HANDLE DispatchListReqEvent;	// for event communications with Dispatch_List_Thread
	HANDLE TerminationCTEvent;		// for event communications with CommThread
	HANDLE TerminationDLEvent;		// for event communications with Dispatch List Thread
	HANDLE TerminationPBEvent;		// for event communications with Playback File Thread

    void __fastcall EngineStartUp(int Engine, int TIU, bool AlrdyStrted, int iDelayTimeSeconds = 0);
	void __fastcall ConsistShutDown(int Consist, int TIU, char * LashUpEngineList = NULL, int iDelayTimeSeconds = 0);
   	void __fastcall ShutDownActiveEngines(int iDelayTimeSeconds = 0);
    void __fastcall ShutdownAllEngines(int iDelayTimeSeconds = 0);
    void __fastcall StartupAllActiveEngines(int iDelayTimeSeconds = 0);
    
    int RemoteNo;

    bool __fastcall IsEngineActive(int iEngineNo);
    bool __fastcall DoesEngineExist(int iEngineNo);

    bool __fastcall FetchByte(unsigned int addr, byte * value, byte Eng, byte TIU);
    bool __fastcall FetchWord(unsigned int addr, unsigned short * value, byte Eng, byte TIU);
    bool __fastcall FetchInt(unsigned int addr, unsigned long * value, byte Eng, byte TIU);

    int __fastcall GetLashUpEngine(char * LashUpEngineList, int Spot);
    String __fastcall CreateJ13HexString(void);

    // Lua Configuration Script
    lua_State *M;
    bool ConfigurationSuccess;

	int LastHotComPage;	// last page displayed by HotCom

    // Critical Section to protect Program Control window's Flags and Global integers & strings
    CRITICAL_SECTION Global_Flag_CS;
    // Critical Section to protect the Fixed Signals
    CRITICAL_SECTION Signals_CS;

    int MsgNum;		// message number for each message displayed

    String SavedNameofEngine;   // used during engine name edit

    TCHAR Version[128];	// holds program version number

    // OneHundredBitString can be a String as .c_str() is never taken
    String OneHundredBitString;

    void __fastcall UpdateEngDataUsers(void);
    void __fastcall CountActiveEngines(void);    

    // These globals can be shared between all PC and Layout windows. They can be used
    // for flags or for passing status information between threads. They are
    // protected by CRITICALSECTION calls to prevent concurrent access of
    // their shared membory
	#define GLOBALINTLIMIT 100
	#define GLOBALSTRINGLIMIT 100
    int GlobalInt[GLOBALINTLIMIT];
    String GlobalString[GLOBALSTRINGLIMIT];

	// key pressed =  0xFF8X
	// key not pressed = 0x000X
	// "X" can be 0 or 1 - indicated key was toggled
	SHORT ShiftKeyState;
	SHORT AltKeyState;
	SHORT CtrlKeyState;

    bool __fastcall ConnecttoTIU(int TIU);
    String SavedCaption;

    bool __fastcall FindEngines(void);
    bool __fastcall FindEngines(int TIU);

    void __fastcall ShowNotification(String Msg);
    #if __BORLANDC__ >= 0x720 && ENABLENOTIFICATIONS
    TNotificationCenter * RTCNotificationCenter;
    #endif

    void __fastcall LoadConfig();
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif


