/**
 * $Id: GrammarSubModule.java,v 1.5 2008/02/14 02:00:07 nishi Exp $
 */
package galatea.io.plugins;

import galatea.dialog.DialogManager;
import galatea.dialog.RuntimeError;
import galatea.dialog.window.DialogManagerWindow;
import galatea.grammar.GrammarTransformer;
import galatea.io.AMThread;
import galatea.io.DeviceEvent;
import galatea.io.ISenderToDevice;
import galatea.logger.Logger;
import galatea.outitem.GrammarOutItem;
import galatea.outitem.OutItem;
import galatea.submodule.AbstractSubModule;
import galatea.util.Util;

import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GrammarSubModule extends AbstractSubModule {
	//private final boolean ignoreError_ = true;
	private final String XML_ENCODING = "UTF-8";
	private Logger dbg = new Logger("GRM");
	private Charset charset_ = Util.getSystemDefaultCharset();
	private Charset xmlCharset_ = Charset.forName(XML_ENCODING);
	
	private String document_ = "";
	private String location_ = "";
	private String transformErrors_ = "";

	private final int STOPPED  = 0;
	private final int BUSY     = 1;
	private final int STOPPING = 2;
	private final int ERROR    = 3;
	private int state_ = STOPPED;

	private synchronized void _setState(int newstate) {
		state_ = newstate;
	}
	
	private synchronized int _getState() {
		return state_;
	}
	
	public void doTimerTask() throws RuntimeError {
		switch (_getState()) {
		case ERROR:
			receiver_.receiveOutputReady("GrammarSubModule", "error");
//			waitingForReady_ = false;
//			transformDone_ = false;
			String err = transformErrors_;
			transformErrors_ = "";
			_setState(STOPPED);
			logger_.fatalError(err);
//			if (ignoreError_) {
//				return;
//			}
			throw new RuntimeError(err);
//			break;
		case STOPPING:
			receiver_.receiveOutputReady("GrammarSubModule", "done");
//			waitingForReady_ = false;
//			transformDone_ = false;
			_setState(STOPPED);
			break;
		}
	}
	
	public boolean startOutput(OutItem item) {
		if (!(item instanceof GrammarOutItem)) return false;
		GrammarOutItem g = (GrammarOutItem)item;
		document_ = "<?xml version=\"1.0\" encoding=\"" 
			+ XML_ENCODING + "\"?>" + g.getDocument();
		location_ = g.getLocation();
//		if (Util.isWindows()) {
//			location_ = "c:" + location_;
//		}
		receiver_.receiveOutputBusy("GrammarSubModule", "started");
//		waitingForReady_ = true;
//		transformDone_ = false;
		while (_getState() != STOPPED) {
			try {
				dbg.print("wait until STOPPED");
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
//		try {
//			Thread.sleep(2000);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		dbg.print("startOutput("+location_+") "+document_);
		Thread th = new Thread(new Runnable() {
			public void run() {
				GrammarTransformer gt = new GrammarTransformer();
				if (gt.doTransform(document_, location_) == false) {
//					transformDoneWithError_ = true;
					transformErrors_ =
						"doTransform " + location_ + "\n" 
						+ "[stderr]\n" + gt.getErrors() 
						+ "[stdout]\n" + gt.getOutputs();
					// dbg.print(transformErrors_);
					_setState(ERROR);
				} else {
					transformErrors_ = "";
//					transformDoneWithError_ = false;
					_setState(STOPPING);
				}
//				transformDone_ = true;
			}
		});
		th.start();
		return true;
	}

	public boolean stopOutput(OutItem item) {
		if (!(item instanceof GrammarOutItem)) return false;
		_setState(STOPPING);
		return true;
	}

//	private boolean waitingForReady_;
//	private boolean transformDone_;
//	private boolean transformDoneWithError_ = false;
//
//	public void doTimerTask() throws RuntimeError {
//		if (waitingForReady_ && transformDone_) {
//			if (transformDoneWithError_) {
//				receiver_.receiveOutputReady("GrammarSubModule", "error");
//				waitingForReady_ = false;
//				transformDone_ = false;
//				logger_.fatalError(transformErrors_);
//				throw new RuntimeError(transformErrors_);
//			}
//			receiver_.receiveOutputReady("GrammarSubModule", "done");
//			waitingForReady_ = false;
//			transformDone_ = false;
//		}
//	}
//	
//	public boolean startOutput(OutItem item) {
//		if (!(item instanceof GrammarOutItem)) return false;
//		GrammarOutItem g = (GrammarOutItem)item;
//		document_ = "<?xml version=\"1.0\" encoding=\"" 
//			+ XML_ENCODING + "\"?>" + g.getDocument();
//		location_ = g.getLocation();
//		receiver_.receiveOutputBusy("GrammarSubModule", "started");
//		waitingForReady_ = true;
//		transformDone_ = false;
//		dbg.print("startOutput("+location_+") "+document_);
//		Thread th = new Thread(new Runnable() {
//			public void run() {
//				GrammarTransformer gt = new GrammarTransformer();
//				if (gt.doTransform(document_, location_) == false) {
//					dbg.print(gt.getErrors());
//					dbg.print(gt.getException());
//					transformDoneWithError_ = true;
//					transformErrors_ = gt.getErrors();
//				} else {
//					transformErrors_ = "";
//					transformDoneWithError_ = false;
//				}
//				transformDone_ = true;
//			}
//		});
//		th.start();
//		return true;
//	}
//
//	public boolean stopOutput(OutItem item) {
//		return item instanceof GrammarOutItem;
//	}
}
