/* ***************************************************************************+
 * 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 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, Channel.SAMPLE_SIZE, 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;
	}
	
	/**
	 * Tranforms this class into <code>String</code> format.
	 * 
	 * @return the <code>String</code> depiction of <code>NetworkProperty</code>
	 */
	public String toString()
	{
		String s = new String("NetworkProperty\r\n");
		s = s + "IP: " + iaAddress.toString() + "\r\n";
		s = s + "Port: " + (new Integer(iPort)).toString() + "\r\n";
		s = s + "Version: " + (new Double(dVersion)).toString() + "\r\n";
		s = s + "Packet Size: " + (new Integer(iPacketSize)).toString() + "\r\n";
		s = s + "ISeq: " + (new Integer(iInitialSequenceNumber)).toString() + "\r\n" + "\r\n";
		
		return s;
	}
}
