/*******************************************************************************
 * Copyright (c) 2003, 2007 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.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);
	}
}
