/*
 * 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 java.util.ArrayList;

import com.jaamsim.events.ProcessTarget;
import com.jaamsim.input.InputAgent;
import com.jaamsim.input.ValueInput;
import com.jaamsim.units.TimeUnit;
import com.sandwell.JavaSimulation.Entity;
import com.sandwell.JavaSimulation.FileEntity;
import com.sandwell.JavaSimulation.InputErrorException;
import com.sandwell.JavaSimulation.Keyword;
import com.sandwell.JavaSimulation.Process;
import com.sandwell.JavaSimulation.StringInput;
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 StringInput 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 ValueInput scriptTime; // the time that has been read in the script

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

		scriptTime = new ValueInput("Time", "Key Inputs", 0.0d);
		scriptTime.setUnitType(TimeUnit.class);
		scriptTime.setValidRange(0.0d, Double.POSITIVE_INFINITY);
		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
		ArrayList<String> rec = new ArrayList<String>();
		while( record.size() > 0 ) {
			// Process the record
			rec.clear();
			for (int i = 0; i < record.size(); i++)
				rec.add((String)record.get(i));

			InputAgent.processKeywordRecord(rec, null);

			// If a "Time" record was read, then wait until the time
			long delayTicks = Process.secondsToTicks(scriptTime.getValue()) - getSimTicks();
			if (delayTicks > 0)
				simWaitTicks(delayTicks);

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

@@ -747,16 +747,49 @@
 tAgent;%0A
+import com.jaamsim.input.Parser;%0A
 import c
@@ -1178,51 +1178,8 @@
 til;
-%0Aimport com.sandwell.JavaSimulation.Vector;
 %0A%0Apu
@@ -3044,504 +3044,257 @@
 %0A%0A%09%09
-// Read the next record%0A%09%09Vector record = scriptFile.readAndParseRecord();%0A%09%09if( record.size() %3E 0 ) %7B%0A%09
+ArrayList%3CString%3E tokens = new ArrayList%3CString%3E();%0A
 %09%09while
-(
  (
-(String)record.get( 0 )).startsWith( %22%5C%22%22 ) ) %7B%0A%09%09%09%09record = scriptFile.readAndParseRecord();%0A%09%09%09%7D%0A%09%09%09Util.discardComment( record );%0A%09%09%7D%0A%0A%09%09// While end of file has not been reached%0A%09%09ArrayList%3CString%3E rec = new ArrayList%3CString%3E();%0A%09%09while( record.size() %3E 0 ) %7B%0A%09%09%09// Process the record%0A%09%09%09rec.clear();%0A%09%09%09for (int i = 0; i %3C record
+true) %7B%0A%09%09%09String line = scriptFile.readLine();%0A%09%09%09if (line == null)%0A%09%09%09%09break;%0A%0A%09%09%09Parser.tokenize(tokens, line);%0A%09%09%09Parser.removeComments(tokens);%0A%09%09%09if (tokens
 .size()
-; i++
+ == 0
 )%0A%09%09%09%09
-rec.add((String)record.get(i))
+continue
 ;%0A%0A%09
@@ -3331,17 +3331,39 @@
 ord(
-rec, null
+tokens, null);%0A%09%09%09tokens.clear(
 );%0A%0A
@@ -3562,246 +3562,8 @@
 ks);
-%0A%0A%09%09%09// Read the next record%0A%09%09%09record = scriptFile.readAndParseRecord();%0A%09%09%09while( record.size() %3E 0 && ((String)record.get( 0 )).startsWith( %22%5C%22%22 ) ) %7B%0A%09%09%09%09record = scriptFile.readAndParseRecord();%0A%09%09%09%7D%0A%09%09%09Util.discardComment( record );
 %0A%09%09%7D

use the new Parser tokenize method in ScriptEntity