/*******************************************************************************
 * Copyright (c) 2007, 2012 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Takashi ITOH - initial API and implementation
 *    Kentarou FUKUDA - initial API and implementation
 *******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.engine;

import java.io.File;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

import org.eclipse.actf.ai.tts.ISAPIEngine;
import org.eclipse.actf.ai.tts.sapi.SAPIPlugin;
import org.eclipse.actf.ai.voice.IVoiceEventListener;
import org.eclipse.actf.util.win32.COMUtil;
import org.eclipse.actf.util.win32.MemoryUtil;
import org.eclipse.actf.util.win32.NativeIntAccess;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.internal.ole.win32.GUID;
import org.eclipse.swt.internal.ole.win32.IDispatch;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.Variant;

/**
 * The implementation of ITTSEngine to use Microsoft Speech API.
 */
public class SapiVoice implements ISAPIEngine, IPropertyChangeListener {

	public static final String ID = "org.eclipse.actf.ai.tts.sapi.engine.SapiVoice"; //$NON-NLS-1$
	public static final String AUDIO_OUTPUT = "org.eclipse.actf.ai.tts.SapiVoice.audioOutput"; //$NON-NLS-1$

	public static final GUID IID_SpFileStream = COMUtil
			.IIDFromString("{947812B3-2AE1-4644-BA86-9E90DED7EC91}"); //$NON-NLS-1$

	public ISpVoice dispSpVoice;
	private Variant varSapiVoice;
	private OleAutomation automation;
	private int idGetVoices;
	private int idGetAudioOutputs;
	private ISpNotifySource spNotifySource = null;
	private static IPreferenceStore preferenceStore = SAPIPlugin.getDefault()
			.getPreferenceStore();
	private boolean isDisposed = false;

	private SpObjectToken curVoiceToken = null;

	private class EngineInfo {
		String name;
		String langId;
		String gender;

		public EngineInfo(String name, String langId, String gender) {
			this.name = name;
			this.langId = langId;
			this.gender = gender;
		}
	}

	private Map<String, TreeSet<EngineInfo>> langId2EngineMap = new HashMap<String, TreeSet<EngineInfo>>();

	public SapiVoice() {
		int pv = COMUtil.createDispatch(ISpVoice.IID);
		dispSpVoice = new ISpVoice(pv);
		varSapiVoice = new Variant(dispSpVoice);
		automation = varSapiVoice.getAutomation();
		spNotifySource = ISpNotifySource.getNotifySource(dispSpVoice);
		SAPIPlugin.getDefault().addPropertyChangeListener(this);

		idGetVoices = getIDsOfNames("GetVoices"); //$NON-NLS-1$
		idGetAudioOutputs = getIDsOfNames("GetAudioOutputs"); //$NON-NLS-1$

		// init by using default engine to avoid init error of some TTS engines
		String orgID = preferenceStore.getString(ID);
		preferenceStore.setValue(ID, preferenceStore.getDefaultString(ID));
		setAudioOutputName();
		// switch to actual engine
		preferenceStore.setValue(ID, orgID);
		setVoiceName(); // for init curVoiceToken

		Variant varVoices = getVoices(null, null);
		if (null != varVoices) {
			SpeechObjectTokens voiceTokens = SpeechObjectTokens
					.getTokens(varVoices);
			if (null != voiceTokens) {
				String exclude = Platform.getResourceString(SAPIPlugin
						.getDefault().getBundle(), "%voice.exclude"); //$NON-NLS-1$
				int count = voiceTokens.getCount();
				for (int i = 0; i < count; i++) {
					Variant varVoice = voiceTokens.getItem(i);
					if (null != varVoice) {
						SpObjectToken token = SpObjectToken.getToken(varVoice);
						if (null != token) {
							String voiceName = token.getDescription(0);
							String langId = token.getAttribute("language"); //$NON-NLS-1$
							int index = langId.indexOf(";");
							//use primary lang ID
							if (index > 0){
								langId = langId.substring(0, index);
							}
							String gender = token.getAttribute("gender"); //$NON-NLS-1$
							if (null == exclude || !exclude.equals(voiceName)) {
								TreeSet<EngineInfo> set = langId2EngineMap
										.get(langId);
								if (set == null) {
									set = new TreeSet<SapiVoice.EngineInfo>(
											new Comparator<EngineInfo>() {
												public int compare(
														EngineInfo o1,
														EngineInfo o2) {
													// TODO priority
													return -o1.name
															.compareTo(o2.name);
												}
											});
									langId2EngineMap.put(langId, set);
								}
								set.add(new EngineInfo(voiceName, langId,
										gender));
							}
						}
					}
				}
			}
			varVoices.dispose();
		}

		// to avoid access violation error at application shutdown
		stop();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse
	 * .jface.util.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		if (ID.equals(event.getProperty())) {
			stop();
			setVoiceName();
		} else if (AUDIO_OUTPUT.equals(event.getProperty())) {
			stop();
			setAudioOutputName();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.actf.ai.tts.ITTSEngine#setEventListener(org.eclipse.actf.
	 * ai.voice.IVoiceEventListener)
	 */
	public void setEventListener(IVoiceEventListener eventListener) {
		spNotifySource.setEventListener(eventListener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#speak(java.lang.String, int, int)
	 */
	public void speak(String text, int flags, int index) {
		int firstFlag = SVSFlagsAsync;
		if (0 != (TTSFLAG_FLUSH & flags)) {
			firstFlag |= SVSFPurgeBeforeSpeak;
		}
		if (index >= 0) {
			speak("<BOOKMARK mark=\"" + index + "\"/>", firstFlag | SVSFPersistXML); //$NON-NLS-1$ //$NON-NLS-2$
			speak(text, SVSFlagsAsync);
			speak("<BOOKMARK mark=\"-1\"/>", SVSFlagsAsync | SVSFPersistXML); //$NON-NLS-1$
		} else {
			speak(text, firstFlag);
		}
	}

	public void speak(String text, int sapiFlags) {
		char[] data = (text + "\0").toCharArray(); //$NON-NLS-1$
		int bstrText = MemoryUtil.SysAllocString(data);
		try {
			dispSpVoice.Speak(bstrText, sapiFlags);
		} finally {
			MemoryUtil.SysFreeString(bstrText);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#stop()
	 */
	public void stop() {
		speak("", TTSFLAG_FLUSH, -1); //$NON-NLS-1$
	}

	/**
	 * @param rate
	 *            The rate property to be set.
	 * @return The invocation is succeeded then it returns true.
	 */
	public boolean setRate(int rate) {
		return OLE.S_OK == dispSpVoice.put_Rate(rate);
	}

	/**
	 * @return The rate property of the voice engine.
	 */
	public int getRate() {
		NativeIntAccess nia = new NativeIntAccess();
		try {
			if (OLE.S_OK == dispSpVoice.get_Rate(nia.getAddress())) {
				return nia.getInt();
			}
		} finally {
			nia.dispose();
		}
		return -1;
	}

	/**
	 * @param varVoice
	 *            The voice object to be set.
	 * @return The invocation is succeeded then it returns true.
	 */
	public boolean setVoice(Variant varVoice) {
		boolean result = OLE.S_OK == dispSpVoice.put_Voice(varVoice
				.getDispatch().getAddress());
		if (result) {
			curVoiceToken = SpObjectToken.getToken(varVoice);
		}
		return result;
	}

	/**
	 * @param varAudioOutput
	 *            The audio output object to be set.
	 * @return The invocation is succeeded then it returns true.
	 */
	public boolean setAudioOutput(Variant varAudioOutput) {
		return OLE.S_OK == dispSpVoice
				.put_AudioOutput(null != varAudioOutput ? varAudioOutput
						.getDispatch().getAddress() : 0);
	}

	private void setVoiceName() {
		String voiceName = preferenceStore.getString(ID);
		if (voiceName.length() > 0) {
			setVoiceName("name=" + voiceName); //$NON-NLS-1$
		}
	}

	/**
	 * @param voiceName
	 *            The voice name to be set.
	 * @return The invocation is succeeded then it returns true.
	 */
	public boolean setVoiceName(String voiceName) {
		boolean success = false;
		Variant varVoices = getVoices(voiceName, null);
		if (null != varVoices) {
			SpeechObjectTokens tokens = SpeechObjectTokens.getTokens(varVoices);
			if (null != tokens && 0 < tokens.getCount()) {
				Variant varVoice = tokens.getItem(0);
				if (null != varVoice) {
					success = setVoice(varVoice);
				}
			}
			varVoices.dispose();
		}
		if (!success) {
			int index = voiceName.indexOf("name="); //$NON-NLS-1$
			varVoices = getVoices(null, null);
			if (null != varVoices && index > -1) {
				String name = voiceName.substring(index + 5);
				SpeechObjectTokens voiceTokens = SpeechObjectTokens
						.getTokens(varVoices);
				if (null != voiceTokens) {
					int count = voiceTokens.getCount();
					for (int i = 0; i < count; i++) {
						Variant varVoice = voiceTokens.getItem(i);
						if (null != varVoice) {
							SpObjectToken token = SpObjectToken
									.getToken(varVoice);
							if (null != token
									&& name.equals(token.getDescription(0))) {
								success = setVoice(varVoice);
							}
						}
					}
				}
			}
			varVoices.dispose();
		}
		return success;
	}

	private void setAudioOutputName() {
		String audioOutput = preferenceStore.getString(AUDIO_OUTPUT);
		if (audioOutput.length() > 0) {
			setAudioOutputName(audioOutput);
		} else {
			setAudioOutput(null);
		}
	}

	/**
	 * @param audioOutput
	 *            The audio output name to be set.
	 * @return The invocation is succeeded then it returns true.
	 */
	public boolean setAudioOutputName(String audioOutput) {
		boolean success = false;
		Variant varAudioOutputs = getAudioOutputs(null, null);
		if (null != varAudioOutputs) {
			SpeechObjectTokens tokens = SpeechObjectTokens
					.getTokens(varAudioOutputs);
			if (null != tokens) {
				for (int i = 0; i < tokens.getCount(); i++) {
					Variant varAudioOutput = tokens.getItem(i);
					if (null != varAudioOutput) {
						SpObjectToken token = SpObjectToken
								.getToken(varAudioOutput);
						if (null != token
								&& audioOutput.equals(token.getDescription(0))) {
							success = setAudioOutput(varAudioOutput);
							break;
						}
					}
				}
			}
			varAudioOutputs.dispose();
		}
		return success;
	}

	/**
	 * @param requiredAttributes
	 * @param optionalAttributes
	 * @return The tokens of voices.
	 */
	public Variant getVoices(String requiredAttributes,
			String optionalAttributes) {
		return getTokens(idGetVoices, requiredAttributes, optionalAttributes);
	}

	/**
	 * @param requiredAttributes
	 * @param optionalAttributes
	 * @return The tokens of audio outputs.
	 */
	public Variant getAudioOutputs(String requiredAttributes,
			String optionalAttributes) {
		return getTokens(idGetAudioOutputs, requiredAttributes,
				optionalAttributes);
	}

	private Variant getTokens(int id, String requiredAttributes,
			String optionalAttributes) {
		if (null == requiredAttributes) {
			return automation.invoke(id);
		} else if (null == optionalAttributes) {
			return automation.invoke(id, new Variant[] { new Variant(
					requiredAttributes) });
		}
		return automation.invoke(id, new Variant[] {
				new Variant(requiredAttributes),
				new Variant(optionalAttributes) });
	}

	private int getIDsOfNames(String name) {
		int dispid[] = automation.getIDsOfNames(new String[] { name });
		if (null != dispid) {
			return dispid[0];
		}
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#dispose()
	 */
	public void dispose() {
		if (!isDisposed) {
			isDisposed = true;

			varSapiVoice.dispose();

			if (SAPIPlugin.getDefault() != null) {
				SAPIPlugin.getDefault().removePropertyChangeListener(this);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#getSpeed()
	 */
	public int getSpeed() {
		int rate = getRate(); // -10 <= rate <= 10
		return (rate + 10) * 5; // 0 <= speed <= 100
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#setSpeed(int)
	 */
	public void setSpeed(int speed) {
		int rate = speed / 5 - 10;
		setRate(rate);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#setLanguage(java.lang.String)
	 */
	public void setLanguage(String language) {
		String gender = null;
		if (curVoiceToken != null) {
			gender = curVoiceToken.getAttribute("gender");
		}

		String langId = LANGID_MAP.get(language);
		if (langId == null) {
			// for backward compatibility
			if (LANG_JAPANESE.equals(language)) {
				langId = "411"; //$NON-NLS-1$
			} else if (LANG_ENGLISH.equals(language)) {
				langId = "409"; //old value "409;9" //$NON-NLS-1$
			}
			// TODO other lang
		}
		if (langId == null) {
			return;
		}

		// Workaround:
		// In some cases, getVoices("language=***",null) doesn't work well.
		// So, get all voices first. Then select lang and gender.

		TreeSet<EngineInfo> set = langId2EngineMap.get(langId);
		if (set != null && set.size() > 0) {
			if (gender != null) {
				for (EngineInfo i : set) {
					if (gender.equalsIgnoreCase(i.gender)) {
						setVoiceName("name=" + i.name);
						// System.out.println(i.name);
						return;
					}
				}
			}
			setVoiceName("name=" + set.first().name);
			// System.out.println(set.first().name);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#setGender(java.lang.String)
	 */
	public void setGender(String gender) {
		if (gender == null) {
			return;
		}
		String langId = null;
		if (curVoiceToken != null) {
			langId = curVoiceToken.getAttribute("language");
			if ("409;9".equals(langId)) {
				langId = "409";
			}
		}

		TreeSet<EngineInfo> set = langId2EngineMap.get(langId);
		if (set != null && set.size() > 0) {
			for (EngineInfo i : set) {
				if (gender.equalsIgnoreCase(i.gender)) {
					setVoiceName("name=" + i.name);
					// System.out.println(i.name);
					return;
				}
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.actf.ai.tts.ITTSEngine#isAvailable()
	 */
	public boolean isAvailable() {
		return automation != null;
	}

	public boolean isDisposed() {
		return isDisposed;
	}

	public boolean canSpeakToFile() {
		return true;
	}

	public boolean speakToFile(String text, File file) {
		int pv = COMUtil.createDispatch(IID_SpFileStream);
		OleAutomation autoSpFileStream = null;
		boolean speakToFileResult = false;

		if (file == null || (file.exists() && !file.canWrite())) {
			return false;
		}

		Variant varSpFileStream = new Variant(new IDispatch(pv));
		try {
			autoSpFileStream = varSpFileStream.getAutomation();

			// AllowAudioOutputFormatChangesOnNextSet
			// System.out.println(automation.getProperty(7).getBoolean());

			// format
			// System.out.println(autoSpFileStream.getProperty(1).getAutomation().setProperty(1,new
			// Variant(6)));

			// open 100 close 101
			String tmpS = file.toURI().toString();
			if (tmpS.startsWith("file:/")) {
				tmpS = tmpS.substring(6).replaceAll("%20"," ");
			}

			autoSpFileStream.invoke(100, new Variant[] { new Variant(tmpS),
					new Variant(3), new Variant(false) });

			dispSpVoice.put_AudioOutputStream(pv);

			char[] data = (text + "\0").toCharArray(); //$NON-NLS-1$
			int bstrText = MemoryUtil.SysAllocString(data);

			try {
				dispSpVoice.Speak(bstrText, 0);
			} finally {
				MemoryUtil.SysFreeString(bstrText);
			}
			autoSpFileStream.invoke(101);
			autoSpFileStream.dispose();
			autoSpFileStream = null;
			speakToFileResult = true;

		} catch (Exception e) {
			e.printStackTrace();
			if (autoSpFileStream != null) {
				autoSpFileStream.dispose();
				autoSpFileStream = null;
			}
		}
		setAudioOutputName(); // reset output
		return speakToFileResult;
	}

}
