/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.common.option; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.freecolandroid.repackaged.javax.sound.sampled.AudioSystem; import org.freecolandroid.repackaged.javax.sound.sampled.Mixer; import org.freecolandroid.xml.stream.XMLStreamException; import org.freecolandroid.xml.stream.XMLStreamReader; import org.freecolandroid.xml.stream.XMLStreamWriter; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.common.model.Specification; /** * Option for selecting an audio mixer. * * <p>Element <tt>MixerWrapper</tt> may return a <b>null</b> value in * <tt>getMixerInfo()</tt>. <br>Element <tt>MixerWrapper</tt> may be * <b>null</b> in <tt>getValue()</tt> (unusual). */ public class AudioMixerOption extends AbstractOption<AudioMixerOption.MixerWrapper> { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(AudioMixerOption.class.getName()); private static final Map<String, MixerWrapper> audioMixers = new HashMap<String, MixerWrapper>(); public static final String AUTO = Messages.message("clientOptions.audio.audioMixer.automatic"); private static final Mixer AUTODETECT_MIXER = tryGetDefaultMixer(); private static final MixerWrapper DEFAULT = new MixerWrapper(AUTO, (AUTODETECT_MIXER != null) ? AUTODETECT_MIXER.getMixerInfo() : null); private static Mixer tryGetDefaultMixer() { Mixer mixer = null; try { mixer = AudioSystem.getMixer(null); } catch (IllegalArgumentException e) { ; // Thrown on Ubuntu } return mixer; } private static Comparator<MixerWrapper> audioMixerComparator = new Comparator<MixerWrapper>() { public int compare(MixerWrapper m1, MixerWrapper m2) { if (m1.equals(DEFAULT)) { if (m2.equals(DEFAULT)) { return 0; } else { return -1; } } else if (m2.equals(DEFAULT)) { return 1; } else { return m1.getMixerInfo().getName().compareTo(m2.getMixerInfo().getName()); } } }; private MixerWrapper value; /** * Creates a new <code>AudioMixerOption</code>. * * @param specification The specification this option belongs * to. May be null. */ public AudioMixerOption(Specification specification) { super(specification); } public AudioMixerOption clone() { AudioMixerOption result = new AudioMixerOption(getSpecification()); result.setValues(this); return result; } /** * Get the <code>Value</code> value. * * @return a <code>String</code> value */ public final MixerWrapper getValue() { return value; } /** * Set the <code>Value</code> value. * * @param newValue The new Value value. */ public final void setValue(MixerWrapper newValue) { final MixerWrapper oldValue = this.value; if (newValue == null) { newValue = DEFAULT; // audioMixers.get(AUTO); ** does it make a difference? } this.value = newValue; if (!newValue.equals(oldValue)) { firePropertyChange(VALUE_TAG, oldValue, value); } } /** * Sets the value of this Option from the given string * representation. Both parameters must not be null at the same * time. * * @param valueString the string representation of the value of * this Option * @param defaultValueString the string representation of the * default value of this Option */ protected void setValue(String valueString, String defaultValueString) { if (valueString != null) { setValue(audioMixers.get(valueString)); } else if (defaultValueString != null) { setValue(audioMixers.get(defaultValueString)); } else { // setValue(DEFAULT); // audioMixers.get(AUTO)); ** does it make a difference? } } /** * Returns a list of the available audioMixers. * @return The available audioMixers in a human readable format. */ public MixerWrapper[] getOptions() { findAudioMixers(); List<MixerWrapper> mixers = new ArrayList<MixerWrapper>(audioMixers.values()); Collections.sort(mixers, audioMixerComparator); return mixers.toArray(new MixerWrapper[0]); } /** * Finds the audioMixers available. */ private void findAudioMixers() { audioMixers.clear(); audioMixers.put(AUTO, DEFAULT); for (Mixer.Info mi : AudioSystem.getMixerInfo()) { audioMixers.put(mi.getName(), new MixerWrapper(mi.getName(), mi)); } } public static class MixerWrapper { private String name; private Mixer.Info mixerInfo; MixerWrapper(String name, Mixer.Info mixerInfo) { this.name = name; this.mixerInfo = mixerInfo; } public String getKey() { return name; } public Mixer.Info getMixerInfo() { return mixerInfo; } @Override public String toString() { return name; } @Override public boolean equals(Object o) { if (o instanceof MixerWrapper) { return ((MixerWrapper) o).getKey().equals(getKey()); } else { return false; } } @Override public int hashCode() { return getKey().hashCode(); } } /** * This method writes an XML-representation of this object to * the given stream. * * @param out The target stream. * @throws XMLStreamException if there are any problems writing * to the stream. */ protected void toXMLImpl(XMLStreamWriter out) throws XMLStreamException { super.toXML(out, getXMLElementTagName()); } /** * Write the attributes of this object to a stream. * * @param out The target stream. * @throws XMLStreamException if there are any problems writing to * the stream. */ @Override protected void writeAttributes(XMLStreamWriter out) throws XMLStreamException { super.writeAttributes(out); out.writeAttribute(VALUE_TAG, getValue().getKey()); } /** * {@inheritDoc} */ protected void readAttributes(XMLStreamReader in) throws XMLStreamException { findAudioMixers(); super.readAttributes(in); logger.warning("AudioMixer options disabled"); } /** * Gets the tag name of the root element representing this object. * * @return "audioMixerOption". */ public static String getXMLElementTagName() { return "audioMixerOption"; } }