/*
 * Galatea Dialog Manager:
 * (c)2003-2004 Takuya NISHIMOTO (nishi@hil.t.u-tokyo.ac.jp)
 * Based on Phoenix By Takuya NISHIMOTO and Mitsuhiro KIZU
 *
 * $Id: AMThread.java,v 1.39 2008/02/14 02:00:07 nishi Exp $
 */
package galatea.io;

import galatea.dialog.ISystemEventLogger;
import galatea.logger.Logger;
import galatea.submodule.IReceiverFromSubModule;
import galatea.submodule.ISubModule;
import galatea.util.AMBuffer;
import galatea.util.Util;

import java.util.ArrayList;

public class AMThread extends Thread implements ISenderToDevice
{
	private int runLevel_ = 0;
	
	private Logger dbg = new Logger("AMThread", 0);
	private AMBuffer ambuf_;
	private ArrayList<ISubModule> subModules_ = new ArrayList<ISubModule>(); 

	public AMThread() {
		setName("AMThread");
		ambuf_ = new AMBuffer(Util.getSystemDefaultCharset());
		outputNative("rep Run = POWEROFF");
		dbg.print("rep Run = POWEROFF");
	}
	
	public void addSubModule(ISubModule s, 
			IReceiverFromSubModule r, ISystemEventLogger l) {
		subModules_.add(s);
		s.setSender(this);
		s.setReceiver(r);
		s.setLogger(l);
	}
	
	public void outputNative(String str) {
		// 仮想サブモジュールを実装する
		// 例えば to @SIM set DialogName & SlotAlias を監視する
		for (int i = 0, n = subModules_.size(); i < n; i++) {
			ISubModule s = subModules_.get(i);
			if ( s != null && s.filterOutputNative(str) == true) 
				return;
		}
		ambuf_.send(str);
	}
	
	/**
	 *  returns
	 *  true  : repeat
	 *  false : quit 
	 */
	private synchronized boolean _iteration() {
		String str = ambuf_.receive();
		dbg.ASSERT(str != null, "AMT str != null");
		if ( str.length() == 0 ) {
			// dbg.print("AMT received nothing");
			return true;
		}
		dbg.print(str);
		for (int i = 0; i < subModules_.size(); i++) {
			ISubModule s = subModules_.get(i);
			if ( s != null && s.receiveFromDevice(str) == true) 
				return true;
		}
		return true;
	}

	// implements ISenderToDevice
	public void send(String msg) {
		ambuf_.send(msg);
	}
	
	// implements Runnable
	public void run()
	{
//		String s = System.getProperty("AMThread.StartupWait", "0");
//		dbg.print("AMThread.StartupWait:" + s);
//		int waitms = (int)(Double.parseDouble(s) * 1000.0);
//		try { 
//			Thread.sleep(waitms);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		while(_iteration()) {
			try { 
				Thread.sleep(1, 0);
			} catch (Exception e) {e.printStackTrace();}
		}
	}

}
