/* ***************************************************************************+
 * ITX package (cnrg.itx) for telephony application programming.              *
 * Copyright (c) 1999  Cornell University, Ithaca NY.                         *
 * A copy of the license is distributed with this package.  Look in the docs  *
 * directory, filename GPL.  Contact information: bergmark@cs.cornell.edu     *
 ******************************************************************************/


package cnrg.itx.datax.devices;

import java.util.Enumeration;

import cnrg.itx.datax.DataException;
import cnrg.itx.datax.Property;
import cnrg.itx.datax.PropertiesCollection;

/**
 * Class that models the properties of an audio device. This class has information
 * about the audio sampling rate and the sample size.
 */
public class AudioProperty implements Property
{
	/**
	 * Some of the supported audio formats.
	 */
	public static final int PCM		= 0;
	public static final int MU_LAW	= 1;
	public static final int A_LAW	= 2;
	
	/**
	 * The sampling rate.
	 */
	private int sampleRate;
	
	/**
	 * The number of bits per sample.
	 */
	private int bitsPerSample;
	
	/**
	 * The audio format used for sampling.
	 */
	private int sampleFormat;
	
	/**
	 * Creates an audioProperty.
	 * @param sampleRate the rate of audio samples, in terms of bytes per second
	 * @param bitsPerSample the number of bits that a sample contains. Typical values include 8 or 16
	 * @param sampleFormat the format of the sample (PCM, MU_LAW, A_LAW)
	 */
	public AudioProperty (int sampleRate, int bitsPerSample, int sampleFormat)
	{
		this.sampleRate		= sampleRate;
		this.bitsPerSample	= bitsPerSample;
		this.sampleFormat	= sampleFormat;
	}
	
	/**
	 * Returns the sample rate in terms of bits per second.
	 * @return int the sampling rate
	 */
	public int getSampleRate()
	{
		return sampleRate;
	}

	/**
	 * Returns the number of bits that each sample contains.
	 * @return int the number of bits per sample
	 */
	public int getBitsPerSample()
	{
		return bitsPerSample;
	}
	
	/**
	 * Get the format of the sample (PCM< MU_LAW, A_LAW).
	 * @return int the sample format
	 */
	public int getSampleFormat()
	{
		return sampleFormat;
	}

	/**
	 * Merges the audio property in the property collection.
	 * @param pc the properties collection to merge the audio property with
	 * @return PropertiesCollection the merged collection of properties
	 * @exception DataException thrown if there are incompatible AudioFormat objects
	 */
	public PropertiesCollection merge(PropertiesCollection pc) throws DataException
	{
		// Go through the collection of properties and find an audio property
		for (Enumeration e = pc.getProperties (); e.hasMoreElements (); ) {
			Property p = (Property) e.nextElement ();
			
			if (p instanceof AudioProperty) {
				AudioProperty ap = (AudioProperty)p;
				if (ap.getBitsPerSample () != bitsPerSample ||
					ap.getSampleFormat ()  != sampleFormat  ||
					ap.getSampleRate ()  != sampleRate) {
						throw new DataException("Incompatible AudioDevices." + 
						" Check that the formats of devices along the channel are compatible");
					}
			}
		}
		
		return pc;
	}

	/**
	 * Finds the optimal set of properties when merging this property with a properties collection.
	 * @param pc the properties collection to find the optimal properties from
	 * @return PropertiesCollection the optimal properties collection
	 * @exception DataException thrown if there are incompatible AudioFormat objects
	 */
	public PropertiesCollection findOptimal(PropertiesCollection pc ) throws DataException
	{
		// TODO: Implement the findOptimal () method
		return pc;
	}
	
	/**
	 * Tranforms this class into <code>String</code> format.
	 * 
	 * @return the <code>String</code> depiction of <code>AudioProperty</code>
	 */
	public String toString()
	{
		String s = new String("AudioProperty\r\n");
		s = s + "Format: " + (new Integer(sampleFormat)).toString() + "\r\n";
		s = s + "Rate: " + (new Integer(sampleRate)).toString() + "\r\n";
		s = s + "Bits: " + (new Integer(bitsPerSample)).toString() + "\r\n" + "\r\n";
		
		return s;
	}
}
