--[[
---------------------------------------------------------------------------
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 = "Sleep Interpreter Test"

require("defines");
require("functions");

LastRunTime = 0.0;
LastDTO = 0.0;
Accuracy = 0.01;	-- 1.00%

SaveAcc = 0;
SaveDec = 0;

MyEngineNo = 0;

--[[---------------------------------------------------------------------------------------]]
function setup(Engine, TIU)
	-- this function is called once when the [Run Script] button is pushed
	print("setup()");
	SetLED(1, clGreen, "Speed");	-- set status LED to green
	SetLED(2, clGreen, "%");	-- set status LED to green	
	-- Engine number selected on the Main window is used
	if (Debug() > 0) then print(string.format("Debug level %d", Debug())); end
	MyEngineNo = Engine;
	Resp = InputQuery("Numeric Input Required", "Enter Engine Number", MyEngineNo);
	if (Resp == false or Resp == nil) then	-- user pressed [Cancel]
		return false;	-- false=setup failed, true=setup succeeded
		end;
	Enum = tonumber(Resp);
	if (Enum ~= nil) then	-- if the result is a number, then use it, otherwise, ignore it
		MyEngineNo = Enum;
		end
	print("Engine Number = " .. MyEngineNo);
	
	-- initialize the layout
	print(string.format("Startup Engine : %d", MyEngineNo));
	EngineStartUp(MyEngineNo, TIU);
	Sleep(25);			
	if (IsEngineRunning(MyEngineNo)) then	-- IsEngineRunning() REQUIRES use of StartUpActiveEngines() or EngineStartUp()
		print(string.format("Initalizing Engine %d", MyEngineNo));
		-- Set smoke off
		Smoke(OFF, 0, MyEngineNo, TIU);
		-- Cab Chatter Off
		CabChat(OFF, 0, MyEngineNo, TIU);
		-- get DTO at start
		CurrentDTO = DTO(MyEngineNo, TIU);
		print(string.format("Trip odometer at start = %.3f Smiles", CurrentDTO));
		-- read up and save the Acc/Dec rates
		SaveAcc, SaveDec = GetRate(MyEngineNo, TIU);
		if (SaveAcc == nil or SaveDec == nil) then
			print(string.format("Get Acc/Dec Rates Failed for Engine : %d", MyEngineNo));
			return false;	-- false=setup failed, true=setup succeeded
			else
			print(string.format("Saved Acc/Dec Rates for Engine : %d : %d - %d", MyEngineNo, SaveAcc, SaveDec));
			end
		-- Set Acc/Dec rate to 25 Smph/sec
		Rate(25, 25, 0, MyEngineNo, TIU);
		print("Acc/Dec rates set to 25 Smph/sec");
		else
		print(string.format("Startup Failed for Engine : %d", MyEngineNo));
		return false;	-- false=setup failed, true=setup succeeded
		end
	print(string.format("Required Speed Accuracy : %.2f%%", Accuracy * 100.0));

	Speeds = {5,11,15,22,26,33,38,44,50,55}
	--Speeds = {35,40}
	for i,iSpeed in ipairs(Speeds) do
		print(string.format("SetSpeed %d Smph for Engine : %d", iSpeed, MyEngineNo));
		SetSpeed(iSpeed, 0, MyEngineNo, TIU);
		Sleep(10);			
		-- read up speed and check it against iSpeed
		CurrentSpeed = GetSetSpeed(MyEngineNo, TIU);
		if (CurrentSpeed ~= iSpeed) then
			print(string.format("Requested Speed Wrong : %d Smph", CurrentSpeed));
			SetLED(1, clRed);	-- set status LED to red
			--return false;
			else
			print(string.format("Requested Speed Correct : %d Smph", CurrentSpeed));
			end
		-- read up speed and check it against iSpeed
		InstantSpeed = GetSpeed(MyEngineNo, TIU);
		if (InstantSpeed ~= iSpeed) then
			print(string.format("Instantaneous Speed Wrong : %d Smph", InstantSpeed));
			SetLED(1, clRed);	-- set status LED to red
			--return false;
			else
			print(string.format("Instantaneous Speed Correct : %d Smph", InstantSpeed));
			end
		-- run for one test period
		print("Test " .. i .. " Started");
		LastDTO = DTO(MyEngineNo, TIU);
		LastRunTime = RunTime();
		Sleep(30);			
		-- read up time and distance and compare with iSpeed
		CurrentDTO = DTO(MyEngineNo, TIU);
		CurrentRunTime = RunTime();
		print(string.format("Run Time = %.2f seconds (%.2f-%.2f)", CurrentRunTime - LastRunTime, CurrentRunTime, LastRunTime)); 
		print(string.format("Distance = %.6f Smiles (%.6f-%.6f)", CurrentDTO - LastDTO, CurrentDTO, LastDTO)); 
		CalculatedSpeed = 3600 * (CurrentDTO - LastDTO)/(CurrentRunTime - LastRunTime);
		print(string.format("Calculated Speed = %.2f Smph (%.6f/%.2f)", CalculatedSpeed, CurrentDTO - LastDTO, CurrentRunTime - LastRunTime));
		print(string.format("Speed accurate to %.2f%%", 100.0 * (CurrentSpeed - CalculatedSpeed) / CurrentSpeed ));
		if ((CalculatedSpeed > (CurrentSpeed * (1 + Accuracy))) or (CalculatedSpeed < (CurrentSpeed * (1 - Accuracy)))) then
			print(string.format("*** Speed not within %.2f%% of expected", Accuracy * 100.0));
			Beep();
			SetLED(2, clRed);	-- set status LED to red
			end
		end
	Sleep(15);			
	print("Test Complete");
	return true;	-- false=setup failed, true=setup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function cleanup(Engine, TIU)
	-- this function is called once when the user presses the [STOP] button
	print("cleanup()");
	-- Restore Acc/Dec rates if saved
	if (SaveAcc > 0 and SaveDec > 0) then
		Rate(SaveAcc, SaveDec, 0, MyEngineNo, TIU);
		Sleep(1);
		SetSpeed(0, 0, MyEngineNo, TIU);
		Sleep(10);
		print("Shutdown Engine " .. MyEngineNo .. " - Please Wait");
		EngineShutdown(MyEngineNo, TIU);
		end;
	print("Script Finished");
	return true;		-- false=cleanup failed, true=cleanup succeeded
	end
--[[---------------------------------------------------------------------------------------]]
function StopEngine(Eng, TIU)		
	print("Stopping Engine " .. MyEngineNo);
	SetSpeed(0, 0, MyEngineNo, TIU);
	return true;
end
Function01Name, Function01Label = StopEngine, "Stop";
--[[---------------------------------------------------------------------------------------]]
function StartEngine(Eng, TIU)		
	print("Starting Engine " .. MyEngineNo);
	SetSpeed(20, 0, MyEngineNo, TIU);	
	return true;
end
Function02Name, Function02Label = StartEngine, "Start 20 Smph";
--[[---------------------------------------------------------------------------------------]]
function Forward(Eng, TIU)		
	print("Forward Engine " .. MyEngineNo);
	SetDirection(FORWARD, 0, MyEngineNo, TIU);
	return true;
end
Function03Name, Function03Label = Forward, "Forward";
--[[---------------------------------------------------------------------------------------]]
function Reverse(Eng, TIU)	
	print("Reverse Engine " .. MyEngineNo);
	SetDirection(REVERSE, 0, MyEngineNo, TIU);
	return true;
end
Function04Name, Function04Label = Reverse, "Reverse";
--[[---------------------------------------------------------------------------------------]]

