/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2002-2011 Ausenco Engineering Canada Inc.
 *
 * This program 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.
 *
 * This program 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.
 */
package com.sandwell.JavaSimulation3D;

import com.jaamsim.events.ProcessTarget;
import com.jaamsim.input.InputAgent;
import com.sandwell.JavaSimulation.DoubleInput;
import com.sandwell.JavaSimulation.Entity;
import com.sandwell.JavaSimulation.FileEntity;
import com.sandwell.JavaSimulation.FileInput;
import com.sandwell.JavaSimulation.InputErrorException;
import com.sandwell.JavaSimulation.Keyword;
import com.sandwell.JavaSimulation.Process;
import com.sandwell.JavaSimulation.Tester;
import com.sandwell.JavaSimulation.Util;
import com.sandwell.JavaSimulation.Vector;

public class ScriptEntity extends Entity {


	@Keyword(description = "The name of the script file for the script entity.",
	         example = "ScriptEntity Script { test.scr }")
	private final FileInput scriptFileName;

	@Keyword(description = "The Time keyword appears inside the script file. The value represents the simulation " +
	                "time at which the next set of commands in the script are implemented.",
	         example = "ScriptEntity Time { 24.0 h }")
	private final DoubleInput scriptTime; // the time that has been read in the script

	{
		scriptFileName = new FileInput( "Script", "Key Inputs", null );
		this.addInput( scriptFileName, true );

		scriptTime = new DoubleInput( "Time", "Key Inputs", 0.0d );
		scriptTime.setValidRange( 0.0d, Double.POSITIVE_INFINITY );
		scriptTime.setUnits( "h" );
		this.addInput( scriptTime, false );
	}

	public ScriptEntity() {
	}


	private static class ScriptTarget extends ProcessTarget {
		final ScriptEntity script;

		ScriptTarget(ScriptEntity script) {
			this.script = script;
		}

		@Override
		public String getDescription() {
			return script.getInputName() + ".doScript";
		}

		@Override
		public void process() {
			script.doScript();
		}
	}

	@Override
	public void startUp() {
		Process.start(new ScriptTarget(this));
	}

	/**
	 * Read the script
	 */
	public void doScript() {

		// If there is no script file, do nothing
		if( scriptFileName.getValue() == null ) {
			return;
		}

		// If the script file exists, open it
		FileEntity scriptFile;
		if( FileEntity.fileExists( Util.getAbsoluteFilePath( scriptFileName.getValue() ) ) ) {
			scriptFile = new FileEntity( Util.getAbsoluteFilePath( scriptFileName.getValue() ), FileEntity.FILE_READ, true );
		}
		else {
			throw new InputErrorException( "The script file " + scriptFileName.getValue() + " was not found" );
		}

		// Read the next record
		Vector record = scriptFile.readAndParseRecord();
		if( record.size() > 0 ) {
			while( ((String)record.get( 0 )).startsWith( "\"" ) ) {
				record = scriptFile.readAndParseRecord();
			}
			Util.discardComment( record );
		}

		// While end of file has not been reached
		while( record.size() > 0 ) {

			// Process the record
			InputAgent.processData( record );

			// If a "Time" record was read, then wait until the time
			if( Tester.greaterCheckTimeStep( scriptTime.getValue(), getCurrentTime() ) ) {
				scheduleWait( scriptTime.getValue() - getCurrentTime() );
			}

			// Read the next record
			record = scriptFile.readAndParseRecord();
			while( record.size() > 0 && ((String)record.get( 0 )).startsWith( "\"" ) ) {
				record = scriptFile.readAndParseRecord();
			}
			Util.discardComment( record );
		}
	}
}

@@ -733,42 +733,66 @@
 com.
-sandwell.JavaSimulation.DoubleInpu
+jaamsim.input.ValueInput;%0Aimport com.jaamsim.units.TimeUni
 t;%0Ai
@@ -1690,21 +1690,20 @@
 e final 
-Doubl
+Valu
 eInput s
@@ -1893,21 +1893,19 @@
 new 
-Doubl
+Valu
 eInput(
- 
 %22Tim
@@ -1926,17 +1926,58 @@
 s%22, 0.0d
- 
+);%0A%09%09scriptTime.setUnitType(TimeUnit.class
 );%0A%09%09scr
@@ -1998,17 +1998,16 @@
 idRange(
- 
 0.0d, Do
@@ -2032,39 +2032,8 @@
 NITY
- );%0A%09%09scriptTime.setUnits( %22h%22 
 );%0A%09
@@ -2043,25 +2043,24 @@
 is.addInput(
- 
 scriptTime, 
@@ -2064,17 +2064,16 @@
 e, false
- 
 );%0A%09%7D%0A%0A%09
@@ -2095,20 +2095,17 @@
 tity() %7B
-%0A%09%7D%0A
+%7D
 %0A%0A%09priva
@@ -3514,18 +3514,18 @@
 me%0A%09%09%09if
-(
  
+(
 Tester.g
@@ -3544,17 +3544,16 @@
 imeStep(
- 
 scriptTi
@@ -3574,24 +3574,18 @@
  get
-Current
+Sim
 Time()
- ) 
+)
 ) %7B%0A
@@ -3593,21 +3593,15 @@
 %09%09%09s
-chedule
+im
 Wait(
- 
 scri
@@ -3627,22 +3627,17 @@
  get
-Current
+Sim
 Time()
- 
 );%0A%09

convert ScriptEntity to use ValueInput