/*******************************************************************************
 *  Copyright 2017-2018 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package cdac.medinfo.sdk.dcm30_04.services.pdu;

import java.io.IOException;

import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomStream;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

/**
 * This Class represents SOP Class Common Extended Negotiation Item.
 */
public class SOPClassCommonExtNegotItem //extends AssociationItem 
{

	/** The item type. */
	byte bItemType;

	/** The  sub item version. */
	byte bSubItemVersion;

	/** The sop class uid. */
	String strSOPClassUID;

	/** The service class uid. */
	String strServiceClassUID;

	/** The Related general sop class id collection. */
	ISingleCollection<RelGenSOPClassID> objRelGenSOPClassIDCollection = null;

	/**
	 * Instantiates a new SOP Class Common Extended Negotiation Item.
	 */
	public SOPClassCommonExtNegotItem() 
	{
		objRelGenSOPClassIDCollection = new SingleCollection<RelGenSOPClassID>();
	}

	/**
	 * Gets the sub item version.
	 * @return byte - byte value of Sub-Item Version.
	 */
	public byte getSubItemVersion() 
	{
		return bSubItemVersion;
	}

	/**
	 * Sets the version of the Sub-item.
	 * @param bSubItemVersion byte value of Sub-Item Version.
	 */
	public void setSubItemVersion(byte bSubItemVersion) 
	{
		this.bSubItemVersion = bSubItemVersion;
	}

	/**
	 * Gets the service class uid.
	 * @return String - String value of service class uid
	 */
	public String getServiceClassUID() 
	{
		return strServiceClassUID;
	}

	/**
	 * Sets the service class uid.
	 * @param serviceClassUID String value of Service Class identifier encoded as a UID
	 */
	public void setServiceClassUID(String serviceClassUID) 
	{
		strServiceClassUID = serviceClassUID;
	}

	/**
	 * Gets The SOP Class identifier encoded as a UID
	 * @return String -value of The SOP Class identifier encoded as a UID.
	 */
	public String getSOPClassUID() 
	{
		return strSOPClassUID;
	}

	/**
	 * Sets The SOP Class identifier encoded as a UID.
	 * @param classUID String value of The SOP Class identifier encoded as a UID
	 */
	public void setSOPClassUID(String classUID) 
	{
		strSOPClassUID = classUID;
	}

	/**
	 * Gets the item type.
	 * @return byte - value of item type.
	 */
	public byte getItemType() 
	{
		return bItemType;
	}

	/**
	 * Sets the item type.
	 * @param bItemType byte value of Item type.
	 */
	public void setItemType(byte bItemType) 
	{
		this.bItemType = bItemType;
	}

	/**


	 */


	/**
	 * Gets The Related-general-sop-class-identification Collection. It is a sequence of
	 * pairs of length and UID sub-fields.
	 * @return ISingleCollection<RelGenSOPClassID> - The Related-general-sop-class-identification Collection.
	 */
	public ISingleCollection<RelGenSOPClassID> getRelGenSOPClassIDCollection() 
	{
		return objRelGenSOPClassIDCollection;
	}

	/**
	 * Sets The Related-general-sop-class-identification Collection. It is a sequence of
	 *  pairs of length and UID sub-fields.
	 * @param objRelGenSOPClassIDCollection The Related-general-sop-class-identification Collection.
	 */
	public void setRelGenSOPClassIDCollection(ISingleCollection<RelGenSOPClassID> objRelGenSOPClassIDCollection) 
	{
		this.objRelGenSOPClassIDCollection = objRelGenSOPClassIDCollection;
	}

	/**
	 * Parses SOP Class Common Extended Negotiation Item.
	 * @param objIDicomStream Dicom Stream containing dicom data.
	 * @throws IOException  Signals that an I/O exception has occurred.
	 */
	public void parse(IDicomStream objIDicomStream)throws IOException
	{
		bItemType = objIDicomStream.readByte();
		bSubItemVersion = objIDicomStream.readByte();
		objIDicomStream.readShort();

		short shSOPClassUIDLentgh = objIDicomStream.readShort();		
		strSOPClassUID = objIDicomStream.readString(shSOPClassUIDLentgh);

		short shServiceClassUIDLength = objIDicomStream.readShort();
		strServiceClassUID =  objIDicomStream.readString(shServiceClassUIDLength);
		short templength = objIDicomStream.readShort();

		if(templength > 0 && objIDicomStream.available() != 0)
		{
			if(objRelGenSOPClassIDCollection == null)
				objRelGenSOPClassIDCollection = new SingleCollection<RelGenSOPClassID>();

			RelGenSOPClassID tempRelGenSOPClassID;

			while(templength > 0)
			{
				tempRelGenSOPClassID = new RelGenSOPClassID();
				tempRelGenSOPClassID.parse(objIDicomStream);
				objRelGenSOPClassIDCollection.add(tempRelGenSOPClassID);
				templength -= tempRelGenSOPClassID.getLength();
			}

		}	
	}

	/**
	 * This method writes the Data Value to the given Stream.
	 * @param objIDicomStream object of the stream onto which the SOP Class Common Extended Negotiation Item is to be written.
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void serialize(IDicomStream objIDicomStream) throws IOException
	{
		objIDicomStream.writeByte(bItemType);
		objIDicomStream.writeByte(bSubItemVersion);
		objIDicomStream.writeShort(getItemLength());		
		objIDicomStream.writeShort((short)strSOPClassUID.length());
		objIDicomStream.writeString(strSOPClassUID);
		objIDicomStream.writeShort((short)strServiceClassUID.length());
		objIDicomStream.writeString(strServiceClassUID);

		short templength = 0;
		if(objRelGenSOPClassIDCollection != null)
		{
			for (RelGenSOPClassID  objRelGenSOPClassID : objRelGenSOPClassIDCollection)
			{
				templength += objRelGenSOPClassID.getLength();
			}

			// write length of Related-general-sop-class-identification is a sequence of pairs.
			objIDicomStream.writeShort(templength);

			
			// write Related-general-sop-class-identification is a sequence of pairs
			for (RelGenSOPClassID  objRelGenSOPClassID : objRelGenSOPClassIDCollection)
			{
				objRelGenSOPClassID.serialize(objIDicomStream);
			}
		}		
	}

	/**
	 * Gets the item length. This Item-length shall be the number of bytes from the first
	 * byte of the following field to the last byte of the Reserved field. 
	 * It shall be encoded as an unsigned binary number.
	 * @return short - Short value of 
	 */
	public short getItemLength() 
	{		
		short tempItemLength = 0;

		tempItemLength =(short) (2+ strSOPClassUID.length() + 2 + strServiceClassUID.length() + 2);

		if(objRelGenSOPClassIDCollection != null)
		{
			for (RelGenSOPClassID  objRelGenSOPClassID : objRelGenSOPClassIDCollection)
			{
				tempItemLength  += objRelGenSOPClassID.getLength();
			}
		}
		//tempItemLength += 1; //reserved bytes
		return tempItemLength;
	}
}
