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

import galatea.dialog.window.DialogManagerWindow;
import galatea.io.ISenderToDevice;
import galatea.logger.Logger;
import galatea.outitem.AudioOutItem;
import galatea.outitem.OutItem;
import galatea.outitem.VoiceOutItem;
import galatea.submodule.AbstractSubModule;
import galatea.util.Property;
import galatea.util.Util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SSMSubModule 
extends AbstractSubModule
{
	private Logger dbg = new Logger("SSM", 0);
	
	private boolean dummyMode_ = Property.getAsBoolean("DM.UseWrapper.SSM.Dummy", false); 
	private long lastOutputWhen_;
	private boolean waitingForReady_;
	
	private String speakLen_ = "";
	private String speakUtt_ = "";

	public void doTimerTask() {
		if (dummyMode_ && waitingForReady_) {
			long curr = Util.getCurrentTimeInMillis();
			if (curr - lastOutputWhen_ > 2000) {
				dbg.print("checkFromSSM IDLE (dummy)");
				receiver_.receiveOutputReady("voice", "(dummy output done)");
				waitingForReady_ = false;
			}
		}
	}
	
	public boolean receiveFromDevice(String str) {
		//
		// From @SSM rep Speak.stat = SPEAKING
		// From @SSM rep Speak.len = 2210
		// From @SSM rep Speak.utt = sil[290] i[75] ch[100] i[60] i[85] ...
		// From @SSM rep Speak.stat = IDLE
		//
		// perl.match("/From @SSM\\s+(.*)$/", str)
		// str = perl.group(1);
		// perl.match("/rep Speak.stat = (.*)$/", str)
		//
		Pattern pSSMSpeakLen = Pattern.compile("From @SSM rep Speak.len = (.*)$");
		Matcher mSSMSpeakLen = pSSMSpeakLen.matcher(str);
		if (mSSMSpeakLen.matches()) {
			speakLen_ = mSSMSpeakLen.group(1);
			return true;
		}
		
		Pattern pSSMSpeakUtt = Pattern.compile("From @SSM rep Speak.utt = (.*)$");
		Matcher mSSMSpeakUtt = pSSMSpeakUtt.matcher(str);
		if (mSSMSpeakUtt.matches()) {
			speakUtt_ = mSSMSpeakUtt.group(1);
			return true;
		}
		
		Pattern pSSMSpeakStat = Pattern.compile("From @SSM rep Speak.stat = (.*)$");
		Matcher mSSMSpeakStat = pSSMSpeakStat.matcher(str);
		if (mSSMSpeakStat.matches()) {
			String g1 = mSSMSpeakStat.group(1);
			if ( g1.equals("IDLE") ) {
				dbg.print("checkFromSSM IDLE");
				receiver_.receiveOutputReady("voice", speakLen_ + " " +speakUtt_);
				return true;
			} else if ( g1.equals("ERROR") ) {
				dbg.print("checkFromSSM ERROR");
				receiver_.receiveOutputReady("voice", "ERROR");
				return true;
			} else if ( g1.equals("SPEAKING") ) {
				dbg.print("checkFromSSM SPEAKING");
				receiver_.receiveOutputBusy("voice", "");
				return true;
			} else if ( g1.equals("PROCESSING") ) { // 
				dbg.print("checkFromSSM PROCESSING");
				return true;
			}
		}
		return false;
	}

	public boolean startOutput(OutItem item) {
		if (!(item instanceof VoiceOutItem)) return false;
		String str = ((VoiceOutItem)item).getArg();
		if (str.length() == 0) {
			dbg.print("doOutput() speak empty *** ignored ***");
			return false;
		}
		sender_.send("to @AM-MCL set Speak = " + str);
		logger_.outputVoiceStarted("set Speak = " + str);
		dbg.print("doOutput() speak (" + str +")");
		if (dummyMode_) {
			receiver_.receiveOutputBusy("voice", "");
			lastOutputWhen_ = Util.getCurrentTimeInMillis();
			waitingForReady_ = true;
		}
		return true;
	}

	public boolean stopOutput(OutItem item) {
		if (item instanceof VoiceOutItem) {
			sender_.send("to @AM-MCL set Speak = STOP");
			return true;
		}
		return false;
	}

}
