/* ***************************************************************************+
 * ITX package (cnrg.itx) for telephony application programming.              *
 * Copyright (c) 1999  Cornell University, Ithaca NY                          *
 *                                                                            *
 * This program is free software; you can redistribute it and/or modify       *
 * it under the terms of the GNU General Public Liense as published by        *
 * the Free Software Foundation, either version 2 of the License, or (at      * 
 * your option) any later version.                                            *
 *                                                                            *
 * The ITX package 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.                                                          * 
 *                                                                            *
 * A copy of the license is distributed with this package.  Look in the docs  *
 * directory, filename GPL.                                                   *
 *                                                                            * 
 * Contact information:                                                       *
 * Donna Bergmark                                                             *
 * 484 Rhodes Hall                                                            *
 * Cornell University                                                         *
 * Ithaca, NY 14853-3801                                                      *
 * bergmark@cs.cornell.edu                                                    *
 ******************************************************************************/


package cnrg.itx.datax.devices;

import cnrg.itx.datax.*;
import java.net.*;
import java.util.*;

/**
 * Class to implement the properties of a network device.
 */
public class NetworkProperty implements Property
{
	/**
	 * The port number for the network device.
	 */
	private int iPort;
	
	/**
	 * The IP address of the network device.
	 */
	private InetAddress iaAddress;

	/**
	 * The packet size for the network device.
	 */
	private int iPacketSize;
	
	/**
	 * The sequence number for the first packet that is generated by the network device.
	 */
	int iInitialSequenceNumber;
	
	/**
	 * The version number of the network device.
	 */
	double dVersion;
	
	/**
	 * Creates a network property object from the parameters.
	 * @param iPort the port the device is listening on
	 * @param iaAddress the IP Address of the device
	 * @param iPacketSize the dataTransmission packet size
	 * @param dVersion the data-encoding version.
	 */
	public NetworkProperty(int iPort, InetAddress iaAddress, int iPacketSize, double dVersion)
	{
		// Initial sequence number is not specified so initialize it to something
		// that is not possible this also means that the network device will not
		// use the buffer queue.
		this (iPort, iaAddress, iPacketSize, dVersion, -1);
	}
	
	/**
	 * Creates a network property object from the parameters.
	 * @param iPort the port the device is listening on
	 * @param iaAddress the IP Address of the device
	 * @param iPacketSize the dataTransmission packet size
	 * @param dVersion the data-encoding version.
	 * @param iInitialSequenceNumber the initial sequence number of the RTP packets
	 */
	public NetworkProperty(int iPort, InetAddress iaAddress, int iPacketSize, double dVersion, int iInitialSequenceNumber)
	{
		this.iPort					= iPort;
		this.iaAddress				= iaAddress;
		this.iPacketSize			= iPacketSize;
		this.dVersion				= dVersion;
		this.iInitialSequenceNumber	= iInitialSequenceNumber;
	}

	/**
	 * Creates a network proeprty object (for transmission destination -> source)
	 * @param iInitialSequenceNumber the first sequence number that the receiver should expect
	 */
	public NetworkProperty (int iInitialSequenceNumber)
	{
		this (-1, null, -1, 0.00, iInitialSequenceNumber);
	}
	
	/**
	 * Gets the port the device is bound on.
	 * @return int the port number which the device is bound to
	 */
	public int getPort()
	{
		return iPort;
	}

	/**
	 * Gets the IP Address of the network device.
	 * @return InetAddress the IP address of the network device
	 */
	public InetAddress getAddress()
	{
		return iaAddress;
	}

	/**
	 * Gets the data transmission packet size in bytes.
	 * @return int the data packet size in bytes
	 */
	public int getPacketSize()
	{
		return iPacketSize;
	}

	/**
	 * Gets the data encoding version.
	 * @return double the data encoding version
	 */
	public double getVersion()
	{
		return dVersion;
	}

	/**
	 * Gets the initial sequence number.
	 * @return int the initial sequence number
	 */
	public int getInitialSequenceNumber()
	{
		return iInitialSequenceNumber;
	}
	
	/**
	 * Finds intersection of compatible properies properties. Otherwise the union.
	 * @param pc the collection of properties to merge
	 * @return PropertiesCollection the merged properties
	 * @exception DataException thrown if there are multiple network devices
	 */
	public PropertiesCollection merge (PropertiesCollection pc) throws DataException 
	{
		// If the passed properties collection is null then just add the 
		if (pc == null) return pc;
		
		for (Enumeration e = pc.getProperties(); e.hasMoreElements() ; )
		{
			Property prop = (Property)e.nextElement();
			
			if (prop instanceof NetworkProperty)
			{
				if (iaAddress == null)
				{
					((NetworkProperty)prop).iInitialSequenceNumber = iInitialSequenceNumber;
				}
				else if ( ((NetworkProperty)prop).iaAddress == null)
				{
					((NetworkProperty)prop).iaAddress	= iaAddress;
					((NetworkProperty)prop).iPacketSize	= iPacketSize;
					((NetworkProperty)prop).iPort		= iPort;
					((NetworkProperty)prop).dVersion	= dVersion;
				}
				else 
				{
					throw new DataException("Multiple Sources or destinations on channel!");
				}
			}
		}

		return pc;
	}

	/**
	 * Returns the optimal set of properties when merging the passed property with a
	 * properties collection object.
	 * @param pc the PropertiesCollection object to find the optimal properties with
	 * @return PropertiesCollection the optimal properties collection
	 */
	public PropertiesCollection findOptimal(PropertiesCollection pc)
	{
		// TODO: Implement the findOptimal() method
		return pc;
	}
}
