//---------------------------------------------------------------------------
#include <vcl.h>
#include <tchar.h>
#pragma hdrstop

#include "RTCMegaMaster.h"		// Dispatch List

#include "Train_Control.h"
#include "Debug_Controls.h"
#include "Setup_Control.h"
#include "Comm_Thread.h"
#include "Watchdog_Thread.h"

#pragma package(smart_init)

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

//---------------------------------------------------------------------------
//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall Watchdog_Thread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------
__fastcall Watchdog_Thread::Watchdog_Thread(bool CreateSuspended)
    : TThread(CreateSuspended)
{
assert(false);	// never called since I used the overloaded constructor below
}
//---------------------------------------------------------------------------
__fastcall Watchdog_Thread::Watchdog_Thread(bool CreateSuspended, int Remote, int TIU, int Engine, int InteractiveMode)
    : TThread(CreateSuspended)
{
MyTIUNo = TIU;
assert(MyTIUNo >= 1 && MyTIUNo <= TIUMAX);
MyEngineNo = Engine;
assert(MyEngineNo >= FACTORYRESET && MyEngineNo <= ENGINEMAX);
MyRemoteNo = Remote;
assert(MyRemoteNo >= 1 && MyRemoteNo <= REMOTEMAX);
MyInteractiveMode = InteractiveMode;
//
FreeOnTerminate = true;			// thread will free itself on exit
}
//---------------------------------------------------------------------------
void __fastcall Watchdog_Thread::Execute()
{
// this does not seem to work in BCB4.0 and Thread view not available in CB10.1
// it does work on BCB6.0
// http://docwiki.embarcadero.com/RADStudio/Rio/en/Converting_an_Unnamed_Thread_to_a_Named_Thread
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = "Watchdog_Thread";
info.dwThreadID = -1;
info.dwFlags = 0;
__try {
    RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD),
        (DWORD*)&info);
    }
__except (EXCEPTION_CONTINUE_EXECUTION) {
    }

if (Terminated) {
	return;						// in case we are terminated
    }    

if (MyInteractiveMode) {
    SleepEx(WATCHDOGDELAY, false);
    MessageBeep(MB_ICONEXCLAMATION);
    SleepEx(WATCHDOGWAIT * 2, false);  // Manual power on - by experimentation, I found that a short delay works best
    }
// this sends an "I0" and updates the engine list and active engine counts
Synchronize(FindEngines);
}
//---------------------------------------------------------------------------
// Count Active Engines - counts the number of active and inactive engines
//
// Called using Synchronize()
//
// Params:
// none
//
//---------------------------------------------------------------------------
void __fastcall Watchdog_Thread::CountActiveEngines(void) {
// Update Active/Inactive Engine Counts
MainForm->CountActiveEngines();
}
//---------------------------------------------------------------------------
// FindEngines - Send watchdog signal then update the engine list and active engine counts.
//
// Called using Synchronize()
//
// Params:
// MyTIUNo - the TIU Number to use
//
//---------------------------------------------------------------------------
void __fastcall Watchdog_Thread::FindEngines(void) {
// this sends an "I0" and updates the engine list and active engine counts
MainForm->FindEngines(MyTIUNo);
}
//---------------------------------------------------------------------------
