--[[
---------------------------------------------------------------------------
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
---------------------------------------------------------------------------]]
-- Semicolons are not required in Lua code
title = "Dispatcher - Run To"
--
-- Dispatcher runs on PC1
--
require("defines");
require("functions");

local Layout4
-- Instrumented Layout 4
Layout4 = require([[Layout4]]);		-- All of the details about the Layout

-- Counter Labels
Counter01Label = "Events";
Counter02Label = "Engine Window";
Counter03Label = "Destination";
Counter04Label = "OS";
Counter05Label = "--";
-- These labels appear on each of the tabs for the Function Buttons
Tab01Label = "Start";
Tab02Label = "Engine";
Tab03Label = "Destination";
--[[---------------------------------------------------------------------------------------]]

--
-- Engines to participate in this run
--
ENGINE1 = 11;
ENGINE2 = 12;
ENGINE3 = 13;
EngNum = { ENGINE1, ENGINE2, ENGINE3};
EngCount = 3;
--
-- Program Control windows to use in this run
--
PCNum = {3, 4, 5};

--
TargetPCNO = 0;	-- PC window to send event

StartTime = os.time();

-- Form A Sent Flag
FormA = {};
--[[---------------------------------------------------------------------------------------]]
function setup(Engine, TIU)
	-- this function is called once when the [Run Script] button is pushed
	-- Engine : Engine number selected on the RTC Main window
	-- TIU : TIU number selected on the RTC Main window
	print("setup()");
		
	print("TIU : " .. TIU);
	assert((TIU >= 1 and TIU <= 5),"TIU Number out of range");
	
	-- make sure that RFID is connected
	TIUSerialPortConnected, TIUConnected, RFIDSerialPortConnected = CommStatus();	
	--print("TIUSerialPortConnected : " .. tostring(TIUSerialPortConnected) .. " - TIUConnected : " .. tostring(TIUConnected) .. " - RFIDSerialPortConnected : " .. tostring(RFIDSerialPortConnected));
	if (not RFIDSerialPortConnected) then
		print("RFID Port must be enabled for this script");
		return false;	-- false=setup failed
		end
	MyEngineNo1 = Engine;	-- Engine number selected on the RTC Main window
	SetCounter(COUNTER02, 0);	
	SM = IDLE;
	print([[Run this script with "RunTo Test.lua in PC Windows #3, #4, and #5 with engines 11, 12, and 13"]]);
	print(string.format("RunTime = %.2f seconds", RunTime()));
	print(string.format("The Dispatcher will use engines %d, %d and %d", EngNum[1], EngNum[2], EngNum[3])); 
	print("Startup, Select Engine and then select a destination....");
	return true;		-- false=setup failed, true=setup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
-- no loop() function	
--[[---------------------------------------------------------------------------------------]]
function cleanup()
	-- this function is called once when the user presses the [STOP] button		
	print(string.format("cleanup() Complete at %.2f", RunTime()));
	return true;		-- false=cleanup failed, true=cleanup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function FormAA()
	SendFormA(TargetPCNO, ALIQUIPPA, WB);
	TargetPCNO = 0;
	return true;
end
Function21Name, Function21Label = FormAA, "->Aliquippa";
--[[---------------------------------------------------------------------------------------]]
function FormAC()
	SendFormA(TargetPCNO, COLLEGE, WB);
	TargetPCNO = 0;
	return true;
end
Function22Name, Function22Label = FormAC, "->College";
--[[---------------------------------------------------------------------------------------]]
function FormANC()
	SendFormA(TargetPCNO, NEWCASTLE, WB);
	TargetPCNO = 0;
	return true;
end
Function23Name, Function23Label = FormANC, "->New Castle";
--[[---------------------------------------------------------------------------------------]]
function FormAWestA()
	SendFormA(TargetPCNO, WESTALIQUIPPA, WB);
	TargetPCNO = 0;
	return true;
end
Function25Name, Function25Label = FormAWestA, "->West Aliquipa";
--[[---------------------------------------------------------------------------------------]]
function FormAS()
	SendFormA(TargetPCNO, STRUTHERS, WB);
	TargetPCNO = 0;	
	return true;
end
Function26Name, Function26Label = FormAS, "->Struthers";
--[[---------------------------------------------------------------------------------------]]
function FormAY()
	SendFormA(TargetPCNO, YOUNGSTOWN, WB);
	TargetPCNO = 0;	
	return true;
end
Function27Name, Function27Label = FormAY, "->Youngstown";
--[[---------------------------------------------------------------------------------------]]
function FormAMCKEES_ROCKS()
	SendFormA(TargetPCNO, MCKEES_ROCKS, WB);
	TargetPCNO = 0;	
	return true;
end
Function28Name, Function28Label = FormAMCKEES_ROCKS, "->McKees Rocks";
--[[---------------------------------------------------------------------------------------]]
function FormAYY1()
	SendFormA(TargetPCNO, GATEWAY_YARD1, WB);
	TargetPCNO = 0;	
	return true;
end
Function29Name, Function29Label = FormAYY1, "->Youngstown Yard 1";
--[[---------------------------------------------------------------------------------------]]
function FormAYY2()
	SendFormA(TargetPCNO, GATEWAY_YARD2, WB);
	TargetPCNO = 0;
	return true;
end
Function30Name, Function30Label = FormAMCKEES_ROCKS, "->Youngstown Yard 2";
--[[---------------------------------------------------------------------------------------]]
function SendFormA(PCNo, Dest, Dir)
	print("Run To ", StationName[Dest]);
	if (PCNo == 0) then
		print("Select Engine window number first");
		return true;
		end
	SetCounter(COUNTER03, Dest);
	FormA[Dest] = true;
	res = SetEvent(PCNo, RUNTOEVENT, Dest, Dir);
	BumpCounter(COUNTER01);
	if (res == nil) then
		print("Engine window not running");
		return false;
		end;	
	return true;
end;
--[[---------------------------------------------------------------------------------------]]
-- Engines
--[[---------------------------------------------------------------------------------------]]
function Script3(Eng, TIU)
	print("Engine ", ({GetName(1)})[1]);
	TargetPCNO = PCNum[1];
	SetCounter(COUNTER02, PCNum[1]);	
	return true;
end
Function11Name, Function11Label = Script3, GetName(EngNum[1]);
--[[---------------------------------------------------------------------------------------]]
function Script4(Eng, TIU)
	print("Engine ", ({GetName(2)})[1]);
	TargetPCNO = PCNum[2];
	SetCounter(COUNTER02, PCNum[2]);	
	return true;
end
Function12Name, Function12Label = Script4, GetName(EngNum[2]);
--[[---------------------------------------------------------------------------------------]]
function Script5(Eng, TIU)
	print("Engine ", ({GetName(3)})[1]);
	TargetPCNO = PCNum[3];
	SetCounter(COUNTER02, PCNum[3]);	
	return true;
end
Function13Name, Function13Label = Script5, GetName(EngNum[3]);
--[[---------------------------------------------------------------------------------------]]
function event(FromPC, Station, EngineNo, Time)
	-- receive an event from engine script when it stops
	-- odd construction on GetName() is to discard the 2nd return value
	print("event() On Sheet from: ", FromPC, " At ", StationName[Station], " ", ({GetName(EngineNo)})[1], " Time = ", Time - StartTime);
	BumpCounter(COUNTER04);	-- bump On Sheet counter
	return true;
end
--[[---------------------------------------------------------------------------------------]]
function startup(Eng, TIU)
	print("Startup Button()");
	-- startup engines
	for iEng = 1, EngCount do
		print("Starting Up Engine #" .. EngNum[iEng]);
		res = SetEvent(PCNum[iEng], STARTUPENGINE, EngNum[iEng]);
		if (res == nil) then
			print("Engine window ", PCNum[iEng], " not running");
			return false;
			end;
		Sleep(6);
		end		
	return true;
end
Function01Name, Function01Label = startup, "Startup";
--[[---------------------------------------------------------------------------------------]]
function shutdown(Eng, TIU)
	print("Shutdown Button()");
	-- shutdown engines
	for iEng = 1, EngCount do
		print("Shutting Down Engine #" .. EngNum[iEng]);
		res = SetEvent(PCNum[iEng], SHUTDOWNENGINE, EngNum[iEng]);
		if (res == nil) then
			print("Engine window ", PCNum[iEng], " not running");
			return false;
			end;
		Sleep(3);
		end;
	return true;
end
Function02Name, Function02Label = shutdown, "Shutdown";
--[[---------------------------------------------------------------------------------------]]
