/*
 * Galatea Dialog Manager:
 * (c)2003 Takuya NISHIMOTO (nishi@hil.t.u-tokyo.ac.jp)
 *
 * $Id: GrammarUtil.java,v 1.5 2006/12/18 00:55:17 nishi Exp $
 */
package galatea.grammar;

import galatea.relaxer.vxml20.VxmlGrammar;
import galatea.relaxer.vxml20.VxmlRule;
import galatea.relaxer.vxml20.VxmlToken;
import galatea.util.HashArray;
import galatea.util.Util;


public class GrammarUtil 
{
	private GrammarUtil() {
	}
	
	private static HashArray kana2ph_ = null;
	
	private static HashArray _getKana2ph() 
	{
		HashArray kana2ph = new HashArray();
		kana2ph.put("きゃ","ky a ");
		kana2ph.put("きゅ","ky u ");
		kana2ph.put("きょ","ky o ");
		kana2ph.put("しゃ","sh a ");
		kana2ph.put("しゅ","sh u ");
		kana2ph.put("しぇ","sh e ");
		kana2ph.put("しょ","sh o ");
		kana2ph.put("ちゃ","ch a ");
		kana2ph.put("ちゅ","ch u ");
		kana2ph.put("ちぇ","ch e ");
		kana2ph.put("ちょ","ch o ");
		kana2ph.put("つぇ","ts e ");
		kana2ph.put("つぁ","ts a ");
		kana2ph.put("つぃ","ts i ");
		
		kana2ph.put("にゃ","ny a ");
		kana2ph.put("にゅ","ny u ");
		kana2ph.put("にょ","ny o ");
		kana2ph.put("ひゃ","hy a ");
		kana2ph.put("ひゅ","hy u ");
		kana2ph.put("ひょ","hy o ");
		kana2ph.put("みゃ","my a ");
		kana2ph.put("みゅ","my u ");
		kana2ph.put("みょ","my o ");
		kana2ph.put("りゃ","ry a ");
		kana2ph.put("りゅ","ry u ");
		kana2ph.put("りょ","ry o ");
		kana2ph.put("ぎゃ","gy a ");
		kana2ph.put("ぎゅ","gy u ");
		kana2ph.put("ぎょ","gy o ");
		kana2ph.put("びゃ","by a ");
		kana2ph.put("びゅ","by u ");
		kana2ph.put("びょ","by o ");
		kana2ph.put("ぴゃ","py a ");
		kana2ph.put("ぴゅ","py u ");
		kana2ph.put("ぴょ","py o ");
		
		kana2ph.put("ふぁ","f a ");
		kana2ph.put("ふぃ","f i ");
		kana2ph.put("ふぇ","f e ");
		kana2ph.put("ふぉ","f o ");
		
		kana2ph.put("じぁ","j a ");
		kana2ph.put("じゃ","j a ");
		kana2ph.put("じゅ","j u ");
		kana2ph.put("じぇ","j e ");
		kana2ph.put("じょ","j o ");
		
		kana2ph.put("ぢぁ","j a ");
		kana2ph.put("ぢゃ","j a ");
		kana2ph.put("ぢゅ","j u ");
		kana2ph.put("ぢぇ","j e ");
		kana2ph.put("ぢょ","j o ");
		
		kana2ph.put("でぃ","d i ");
		kana2ph.put("でゅ","dy u ");
		
		kana2ph.put("うぇ","w e ");
		kana2ph.put("うぃ","w i ");
		
		kana2ph.put("とぅ","t u ");
		kana2ph.put("てぃ","t i ");
		kana2ph.put("てゅ","t u ");
		
		
		kana2ph.put("うぉ","w o ");
		kana2ph.put("ずぃ","z i ");
		kana2ph.put("どぅ","d u ");
		kana2ph.put("ふょ","hy o ");
		kana2ph.put("ふゅ","hy u ");
		
		kana2ph.put("くぇ","k u e ");
		kana2ph.put("すぃ","s i ");
		kana2ph.put("ほぃ","h o i ");
		kana2ph.put("くぃ","k u i ");
		kana2ph.put("しぃ","sh i ");
		kana2ph.put("くぉ","k u o ");
		kana2ph.put("ねぇ","n e: ");
		
		kana2ph.put("あ","a ");
		kana2ph.put("い","i ");
		kana2ph.put("う","u ");
		kana2ph.put("え","e ");
		kana2ph.put("お","o ");
		kana2ph.put("を","o ");
		
		kana2ph.put("か","k a ");
		kana2ph.put("き","k i ");
		kana2ph.put("く","k u ");
		kana2ph.put("け","k e ");
		kana2ph.put("こ","k o ");
		kana2ph.put("さ","s a ");
		kana2ph.put("し","sh i ");
		kana2ph.put("す","s u ");
		kana2ph.put("せ","s e ");
		kana2ph.put("そ","s o ");
		kana2ph.put("た","t a ");
		kana2ph.put("ち","ch i ");
		kana2ph.put("つ","ts u ");
		kana2ph.put("て","t e ");
		kana2ph.put("と","t o ");
		kana2ph.put("な","n a ");
		kana2ph.put("に","n i ");
		kana2ph.put("ぬ","n u ");
		kana2ph.put("ね","n e ");
		kana2ph.put("の","n o ");
		kana2ph.put("は","h a ");
		kana2ph.put("ひ","h i ");
		kana2ph.put("ふ","f u ");
		kana2ph.put("へ","h e ");
		kana2ph.put("ほ","h o ");
		kana2ph.put("ま","m a ");
		kana2ph.put("み","m i ");
		kana2ph.put("む","m u ");
		kana2ph.put("め","m e ");
		kana2ph.put("も","m o ");
		kana2ph.put("や","y a ");
		kana2ph.put("ゆ","y u ");
		kana2ph.put("よ","y o ");
		kana2ph.put("ら","r a ");
		kana2ph.put("り","r i ");
		kana2ph.put("る","r u ");
		kana2ph.put("れ","r e ");
		kana2ph.put("ろ","r o ");
		kana2ph.put("わ","w a ");
		kana2ph.put("ん","N ");
		
		kana2ph.put("が","g a ");
		kana2ph.put("ぎ","g i ");
		kana2ph.put("ぐ","g u ");
		kana2ph.put("げ","g e ");
		kana2ph.put("ご","g o ");
		kana2ph.put("ざ","z a ");
		kana2ph.put("じ","j i ");
		kana2ph.put("ず","z u ");
		kana2ph.put("ぜ","z e ");
		kana2ph.put("ぞ","z o ");
		kana2ph.put("だ","d a ");
		kana2ph.put("ぢ","j i ");
		kana2ph.put("づ","z u ");
		kana2ph.put("で","d e ");
		kana2ph.put("ど","d o ");
		kana2ph.put("ば","b a ");
		kana2ph.put("び","b i ");
		kana2ph.put("ぶ","b u ");
		kana2ph.put("べ","b e ");
		kana2ph.put("ぼ","b o ");
		kana2ph.put("ぱ","p a ");
		kana2ph.put("ぴ","p i ");
		kana2ph.put("ぷ","p u ");
		kana2ph.put("ぺ","p e ");
		kana2ph.put("ぽ","p o ");
		
		kana2ph.put("っ","q ");
		kana2ph.put("ー",": ");
		kana2ph.put("ぁ","a ");
		kana2ph.put("ぃ","i ");
		kana2ph.put("ぅ","u ");
		kana2ph.put("ぇ","e ");
		kana2ph.put("ぉ","o ");
		kana2ph.put("ゃ","y a ");
		kana2ph.put("ゅ","y u ");
		kana2ph.put("ょ","y o ");
		kana2ph.put("ゐ","i ");
		kana2ph.put("ゑ","e ");
		
		kana2ph.put("a a ", "a: ");
		kana2ph.put("i i ", "i: ");
		kana2ph.put("u u ", "u: ");
		kana2ph.put("e e ", "e: ");
		kana2ph.put("o o ", "o: ");
		
		kana2ph.put("e i ", "e: ");
		kana2ph.put("o u ", "o: ");
		
		kana2ph.put(" :", ":");
		kana2ph.put("・", "");
		kana2ph.put(" ", ";");
		return kana2ph;
	}
	
	public static String getPhonemeFromSym(String sym)
	{
		if (kana2ph_ == null) {
			kana2ph_ = _getKana2ph();
		}
		
		String phoneme = Util.removeSpaces(sym);
		for ( int i = 0, n = kana2ph_.size(); i < n; i++ ) {
			String key = kana2ph_.getKey(i);
			String str = (String)(kana2ph_.get(i));
			phoneme = phoneme.replaceAll(key, str);
		}
		return phoneme;
	}
	
	
	//
	// <token sym="はい" slot="yesno" value="y">はい</token>
	// <token phoneme="h;a;i;" sym="はい" slot="yesno" value="y">はい@yesno=y</token>
	//
	// <token sym="は い" slot="yesno" value="y es"> は い </token> 
	// <token phoneme="h;a;i;" sym="は い" slot="yesno" value="y es">はい@yesno=y_es</token>
	//
	public static void convertToken(VxmlGrammar gram)
	{
		for (int i = 0, n = gram.sizeContent(); i < n; i++) {
			if ( gram.getContent(i) instanceof VxmlRule ) {
				VxmlRule rule = (VxmlRule)(gram.getContent(i));
				for (int j = 0, m = rule.sizeContent(); j < m; j++) {
					if ( rule.getContent(j) instanceof VxmlToken ) {
						VxmlToken token = (VxmlToken)(rule.getContent(j));
						if ( token.getPhoneme() == null ) {
							token.setPhoneme(getPhonemeFromSym(token.getSym()));
						}
						if ( token.getSlot() != null && token.getValue() != null ) {
							// wd@slot=val
							String text = token.getContent();
							String value = token.getValue().replaceAll(" ", "_");
							text = text + "@" + token.getSlot() + "=" + value;
							token.setContent(text);
						} else if ( token.getSlot() != null && token.getValue() == null ) {
							// wd@slot (assume wd=val)
							String text = token.getContent();
							String value = text.replaceAll(" ", "_");
							text = text + "@" + token.getSlot() + "=" + value;
							token.setContent(text);
						}
						token.setContent(Util.removeSpaces(token.getContent()));
					}
				}
			}
		}
	}
	
	/**
	 * for document.VXMLDoc 
	 */
	public static String getJulianXmlGrammar(VxmlGrammar gram, String gramAdrs) {
		GrammarRuleSet gs = new GrammarRuleSet();
		gs.setupTemplateGrammar();
		gs.addRulesFromGrammar(gram, gramAdrs);
		String gramStr = gs.getRulesAsString();
		gramStr = Util.removeNewLines(gramStr);
		gramStr = gramStr.replaceAll(" xmlns=\"[^\"]*\"","");
		gramStr = gramStr.replaceAll("> <","><");
		gramStr = gramStr.replaceAll("></ruleref>","/>");
		return gramStr; 
	}
	
}
