/*******************************************************************************
 * Copyright (c) 2003, 2006 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:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.ui.internal.audio;

import java.util.*;
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IMemento;
import org.eclipse.wst.server.ui.internal.ServerUIPlugin;
import org.eclipse.wst.server.ui.internal.Trace;
/**
 * Main audio plugin class.
 */
public class AudioCore {
	protected static AudioCore instance;

	public static final String PREF_SOUND_ENABLED = "soundEnabled";
	public static final String PREF_VOLUME = "volume";

	public static final String SOUNDS_FILE = "sounds.xml";
	public static final String DISABLED_FILE = "disabled-sounds.xml";

	// Categories - map of String id to String names
	private Map<String, String> categories;

	// Sounds - map of String id to Sound
	private Map<String, Sound> sounds;

	// specific sounds or categories that have been disabled, by id
	private List<String> disabledSounds;
	private List<String> disabledCategories;

	// SoundMap - map of String id to an IPath
	private Map<String, IPath> userSoundMap;

	/**
	 * AudioCore constructor comment.
	 */
	private AudioCore() {
		super();
	
		loadExtensionPoints();
	
		loadSoundMap();
		loadDisabledLists();
		
		
	}

	/**
	 * Return the categories
	 *
	 * @return java.util.Map
	 */
	protected Map<String, String> getCategories() {
		return categories;
	}

	/**
	 * Returns the audio clip.
	 *
	 * @param url java.net.URL
	 * @return javax.sound.sampled.Clip
	 */
	protected static Clip getClip(URL url) {
		try {
			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
	
			AudioFormat format = audioInputStream.getFormat();
	
			/**
			 * we can't yet open the device for ALAW/ULAW playback,
			 * convert ALAW/ULAW to PCM
			 */
			if ((format.getEncoding() == AudioFormat.Encoding.ULAW) ||
				(format.getEncoding() == AudioFormat.Encoding.ALAW)) {
				AudioFormat tmp = new AudioFormat(
					AudioFormat.Encoding.PCM_SIGNED, 
					format.getSampleRate(),
					format.getSampleSizeInBits() * 2,
					format.getChannels(),
					format.getFrameSize() * 2,
					format.getFrameRate(), true);
				audioInputStream = AudioSystem.getAudioInputStream(tmp, audioInputStream);
				format = tmp;
			}
			DataLine.Info info = new DataLine.Info(
				Clip.class, audioInputStream.getFormat(), 
				((int) audioInputStream.getFrameLength() *
				format.getFrameSize()));
		
			Clip clip = (Clip) AudioSystem.getLine(info);
			clip.open(audioInputStream);
			return clip;
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not get clip: " + url, e);
		}
		return null;
	}
	
	/**
	 * Returns true if audio is currently available on this system.
	 *
	 * @return boolean
	 */
	protected static boolean isAudioSupported() {
		try {
			boolean sound = false;
			Mixer.Info[] info2 = AudioSystem.getMixerInfo();
			if (info2 != null) {
				int size = info2.length;
				for (int i = 0; i < size; i++) {
					//Trace.trace(" " + info2[i]);
					Mixer mixer = AudioSystem.getMixer(info2[i]);
					if (mixer != null) {
						//Trace.trace("   Mixer:" + mixer);
						//Trace.trace("   " + mixer.getLineInfo());
						try {
							Line.Info info = mixer.getLineInfo();
							Line line = mixer.getLine(info);
							//Trace.trace("   Line:" + line);
							if (line != null && line.toString().indexOf("Output") >= 0)
								sound = true;
						} catch (Exception e) {
							// ignore
						}
					}
				}
			}
			return sound;
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not verify audio status", e);
		}
		return true;
	}
	
	/**
	 * Returns true if sound is enabled.
	 *
	 * @return boolean
	 */
	public boolean getDefaultSoundsEnabled() {
		return getPreferenceStore().getDefaultBoolean(PREF_SOUND_ENABLED);
	}

	/**
	 * Returns the default volume.
	 *
	 * @return int
	 */
	public int getDefaultVolume() {
		return getPreferenceStore().getDefaultInt(PREF_VOLUME);
	}

	/**
	 * Returns the singleton instance.
	 *
	 * @return org.eclipse.audio.internal.AudioCore
	 */
	public static AudioCore getInstance() {
		if (instance == null)
			instance = new AudioCore();
		return instance;
	}

	/**
	 * 
	 * @return org.eclipse.jface.preference.IPreferenceStore
	 */
	protected IPreferenceStore getPreferenceStore() {
		return ServerUIPlugin.getInstance().getPreferenceStore();
	}

	/**
	 * Returns the sound with the given id.
	 *
	 * @param id java.lang.String
	 * @return org.eclipse.audio.Sound
	 */
	protected Sound getSound(String id) {
		try {
			return sounds.get(id);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * Return the sounds.
	 *
	 * @return java.util.Map
	 */
	protected Map<String, Sound> getSounds() {
		return sounds;
	}

	/**
	 * Returns the full user sound map.
	 *
	 * @return java.util.Map
	 */
	protected Map<String, IPath> getUserSoundMap() {
		if (userSoundMap == null)
			loadSoundMap();
		return userSoundMap;
	}

	/**
	 * Return the current URL for this sound.
	 *
	 * @param id java.lang.String
	 * @return java.net.URL
	 */
	protected IPath getUserSoundPath(String id) {
		try {
			if (userSoundMap == null)
				loadSoundMap();
	
			IPath path = userSoundMap.get(id);
			if (path != null)
				return path;
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not get sound URL: " + id, e);
		}
		return null;
	}

	/**
	 * Returns the preferred volume.
	 *
	 * @return int
	 */
	public int getVolume() {
		return getPreferenceStore().getInt(PREF_VOLUME);
	}

	/**
	 * Initialize the default preferences.
	 *
	 * @param store org.eclipse.jface.preference.IPreferenceStore
	 */
	public static void initializeDefaultPreferences(IPreferenceStore store) {
		store.setDefault(PREF_VOLUME, 18);
	}

	/**
	 * Returns true if the given category is enabled.
	 *
	 * @param id java.lang.String
	 * @return boolean
	 */
	public boolean isCategoryEnabled(String id) {
		if (id == null)
			return false;
	
		if (disabledCategories == null)
			loadDisabledLists();
	
		return (!disabledCategories.contains(id));
	}

	/**
	 * Returns true if sound is enabled.
	 *
	 * @return boolean
	 */
	public boolean isSoundEnabled() {
		return getPreferenceStore().getBoolean(PREF_SOUND_ENABLED);
	}

	/**
	 * Returns true if the given sound is enabled.
	 *
	 * @param id java.lang.String
	 * @return boolean
	 */
	public boolean isSoundEnabled(String id) {
		if (id == null)
			return false;
	
		if (disabledSounds == null)
			loadDisabledLists();
	
		return (!disabledSounds.contains(id));
	}

	/**
	 * Saves the disabled sound list.
	 */
	private void loadDisabledLists() {
		String filename = ServerUIPlugin.getInstance().getStateLocation().append(DISABLED_FILE).toOSString();
	
		FileInputStream in = null;
		disabledCategories = new ArrayList<String>();
		disabledSounds = new ArrayList<String>();
		try {
			in = new FileInputStream(filename);
			IMemento memento = XMLMemento.loadMemento(in);
	
			IMemento cat = memento.getChild("categories");
			IMemento[] children = cat.getChildren("category");
	
			int size = children.length;
			for (int i = 0; i < size; i++) {
				try {
					IMemento child = children[i];
					String id = child.getString("id");
	
					disabledCategories.add(id);
				} catch (Exception ex) {
					Trace.trace(Trace.SEVERE, "Error reading URL map ", ex);
				}
			}
	
			IMemento sound = memento.getChild("sounds");
			children = sound.getChildren("sound");
	
			size = children.length;
			for (int i = 0; i < size; i++) {
				try {
					IMemento child = children[i];
					String id = child.getString("id");
	
					disabledSounds.add(id);
				} catch (Exception ex) {
					Trace.trace(Trace.SEVERE, "Error reading URL map ", ex);
				}
			}
		} catch (Exception e) {
			//AudioPlugin.log(new Status(IStatus.WARNING, AudioPlugin.PLUGIN_ID, 0, "Could not load disabled sound information", e));
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {
					// ignore
				}
			}
		}
	}

	/**
	 * Load extension point.
	 */
	private void loadExtensionPoints() {
		// load extension points
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IConfigurationElement[] cf = registry.getConfigurationElementsFor(ServerUIPlugin.PLUGIN_ID, "audio");
	
		int size = cf.length;
		categories = new HashMap<String, String>();
		sounds = new HashMap<String, Sound>();
	
		for (int i = 0; i < size; i++) {
			try {
				String elementName = cf[i].getName();
				String id = cf[i].getAttribute("id");
				String name = cf[i].getAttribute("name");
				if ("category".equals(elementName)) {
					categories.put(id, name);
				} else if ("sound".equals(elementName)) {
					String category = cf[i].getAttribute("category");
					String location = cf[i].getAttribute("location");
	
					URL realURL = null;
					if (location != null && location.length() > 0) {
						String pluginId = cf[i].getDeclaringExtension().getContributor().getName();
						URL url = FileLocator.find(Platform.getBundle(pluginId), new Path(location), null);
						realURL = FileLocator.resolve(url);
					}
	
					Sound sound = new Sound(id, category, name, realURL);
					sounds.put(id, sound);
				}
			} catch (Throwable t) {
				Trace.trace(Trace.SEVERE, "Could not load audio: " + cf[i].getAttribute("id"), t);
			}
		}
	}

	/**
	 * Saves the disabled sound list.
	 */
	private void loadSoundMap() {
		String filename = ServerUIPlugin.getInstance().getStateLocation().append(SOUNDS_FILE).toOSString();
	
		InputStream in = null;
		userSoundMap = new HashMap<String, IPath>();
		try {
			in = new FileInputStream(filename);
			IMemento memento = XMLMemento.loadMemento(in);
	
			IMemento[] children = memento.getChildren("map");
	
			int size = children.length;
			for (int i = 0; i < size; i++) {
				try {
					IMemento child = children[i];
					String id = child.getString("id");
					String pathStr = child.getString("path");
					IPath path = new Path(pathStr);
	
					userSoundMap.put(id, path);
				} catch (Exception ex) {
					Trace.trace(Trace.SEVERE, "Error reading URL map ", ex);
				}
			}
		} catch (Exception e) {
			// ignore
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (Exception e) {
					// ignore
				}
			}
		}
	}

	/**
	 * Play the sound with the given id. (provided that
	 * the user has enabled the sound)
	 *
	 * @param id java.lang.String
	 */
	public void playSound(String id) {
		if (!isSoundEnabled())
			return;
	
		if (!isSoundEnabled(id))
			return;
	
		try {
			Sound sound = sounds.get(id);
			String category = sound.getCategory();
			if (category != null && categories.containsKey(category)) {
				if (!isCategoryEnabled(category))
					return;
			}
	
			URL url = sound.getLocation();
			IPath path = getUserSoundPath(id);
			if (path != null)
				url = path.toFile().toURL();
	
			playSound(url, getVolume());
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error playing audio: " + id, e);
		}
	}

	/**
	 * Plays the sound at the given url.
	 *
	 * @param url java.net.URL
	 */
	protected static void playSound(URL url, final int volume) {
		try {
			Trace.trace(Trace.FINEST, "playSound");
			if (url == null || volume <= 0)
				return;
	
			final Clip clip = getClip(url);
			if (clip == null)
				return;
				
			Trace.trace(Trace.FINEST, "playing");
	
			Thread t = new Thread("Sound Thread") {
				public void run() {
					// set gain
					FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
					double value = volume / 20.0;
					float dB = (float) (Math.log(value==0.0?0.0001:value)/Math.log(10.0)*20.0);
					gainControl.setValue(dB);
	
					Trace.trace(Trace.FINEST, "start");
					clip.start();
					try {
						sleep(99);
					} catch (Exception e) {
						// ignore
					}
	
					while (clip.isActive()) {
						try {
							sleep(99);
						} catch (Exception e) {
							break;
						}
					}
					clip.stop();
					clip.close();
					Trace.trace(Trace.FINEST, "stop");
				}
			};
			t.setDaemon(true);
			t.start();
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error playing audio: " + url, e);
		}
	}

	/**
	 * Saves the disabled sounds and categories list.
	 */
	private void saveDisabledLists() {
		String filename = ServerUIPlugin.getInstance().getStateLocation().append(DISABLED_FILE).toOSString();
	
		FileOutputStream fout = null;
		try {
			XMLMemento memento = XMLMemento.createWriteRoot("disabled");
	
			IMemento cat = memento.createChild("categories");
			Iterator iterator = disabledCategories.iterator();
			while (iterator.hasNext()) {
				IMemento child = cat.createChild("category");
				String id = (String) iterator.next();
				child.putString("id", id);
			}
	
			IMemento sound = memento.createChild("sounds");
			iterator = disabledSounds.iterator();
			while (iterator.hasNext()) {
				IMemento child = sound.createChild("sound");
				String id = (String) iterator.next();
				child.putString("id", id);
			}
	
			fout = new FileOutputStream(filename);
			memento.save(fout);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not save disabled information", e);
		} finally {
			if (fout != null) {
				try {
					fout.close();
				} catch (Exception e) {
					// ignore
				}
			}
		}
	}

	/**
	 * Saves the disabled sound list.
	 */
	private void saveSoundMap() {
		String filename = ServerUIPlugin.getInstance().getStateLocation().append(SOUNDS_FILE).toOSString();
	
		FileOutputStream fout = null;
		try {
			XMLMemento memento = XMLMemento.createWriteRoot("sound-map");
	
			Iterator iterator = userSoundMap.keySet().iterator();
			while (iterator.hasNext()) {
				IMemento child = memento.createChild("map");
				String id = (String) iterator.next();
				child.putString("id", id);
				IPath path = userSoundMap.get(id);
				child.putString("path", path.toString());
			}
	
			fout = new FileOutputStream(filename);
			memento.save(fout);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not save URL map information", e);
		} finally {
			if (fout != null) {
				try {
					fout.close();
				} catch (Exception e) {
					// ignore
				}
			}
		}
	}

	/**
	 * Enable or disable a specific category.
	 *
	 * @param id java.lang.String
	 * @param b boolean
	 */
	public void setCategoryEnabled(String id, boolean b) {
		if (id == null)
			return;
	
		if (disabledCategories == null)
			loadDisabledLists();
	
		if (b) {
			if (disabledCategories.contains(id)) {
				disabledCategories.remove(id);
				saveDisabledLists();
			}
		} else {
			if (!disabledCategories.contains(id)) {
				disabledCategories.add(id);
				saveDisabledLists();
			}
		}
	}

	/**
	 * Enable or disable a specific sound.
	 *
	 * @param id java.lang.String
	 * @param b boolean
	 */
	public void setSoundEnabled(String id, boolean b) {
		if (id == null)
			return;
	
		if (disabledSounds == null)
			loadDisabledLists();
	
		if (b) {
			if (disabledSounds.contains(id)) {
				disabledSounds.remove(id);
				saveDisabledLists();
			}
		} else {
			if (!disabledSounds.contains(id)) {
				disabledSounds.add(id);
				saveDisabledLists();
			}
		}
	}

	/**
	 * Sets whether sound is enabled.
	 *
	 * @param enabled
	 */
	public void setSoundsEnabled(boolean enabled) {
		getPreferenceStore().setValue(PREF_SOUND_ENABLED, enabled);
	}

	/**
	 * Sets the current URL for this sound.
	 *
	 * @param id java.lang.String
	 * @param path IPath
	 */
	protected void setSoundURL(String id, IPath path) {
		if (id == null || path == null)
			return;
	
		try {
			if (userSoundMap == null)
				loadSoundMap();
	
			userSoundMap.put(id, path);
			saveSoundMap();
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not get sound URL: " + id, e);
		}
	}

	/**
	 * Sets the full user sound map.
	 *
	 * @param map the sound map
	 */
	protected void setUserSoundMap(Map<String, IPath> map) {
		if (map != null) {
			userSoundMap = map;
			saveSoundMap();
		}
	}

	/**
	 * Sets the volume.
	 *
	 * @param volume the volume
	 */
	public void setVolume(int volume) {
		getPreferenceStore().setValue(PREF_VOLUME, volume);
	}
}