/*******************************************************************************
 *  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.enums.EnumItemType;
import cdac.medinfo.sdk.dcm30_04.utils.ICollectionIterator;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

/**
 * The Class RQ Presentation Context Item.
 * The Presentation Context Item shall be made of a sequence of mandatory fixed length fields followed by
 * a variable field. The variable field shall consist of one Abstract Syntax Sub-Item followed by one or more Transfer Syntax
 * Sub-Items.
 */
public class RQPresContextItem extends PresContextItem 
{
	/** The abstract syntax item. */
	AbstractSyntaxItem objAbstractSyntaxItem = null;

	/** The transfer syntax item collection. */
	ISingleCollection<TransferSyntaxItem> objTransferSyntaxItemCollection = null;


	/**
	 * Instantiates a new Presentation Context Item.
	 */
	public RQPresContextItem()
	{
		super(EnumItemType.RQ_PRESENTATION_CONTEXT_ITEM.getValue());
		objTransferSyntaxItemCollection = new SingleCollection<TransferSyntaxItem>();
	}
	
	/**
	 * Gets the abstract syntax item.
	 * @return AbstractSyntaxItem - object of abstract syntax item.
	 */
	public AbstractSyntaxItem getAbstractSyntaxItem() 
	{
		return objAbstractSyntaxItem;
	}

	/**
	 * Sets the abstract syntax item.
	 * @param objAbstractSyntaxItem object of abstract syntax item.
	 */
	public void setAbstractSyntaxItem(AbstractSyntaxItem objAbstractSyntaxItem) 
	{
		this.objAbstractSyntaxItem = objAbstractSyntaxItem;
	}

	/**
	 * Gets the transfer syntax item collection.
	 * @return ISingleCollection<TransferSyntaxItem> - transfer syntax item collection
	 */
	public ISingleCollection<TransferSyntaxItem> getTransferSyntaxItemCollection() 
	{
		return objTransferSyntaxItemCollection;
	}

	/**
	 * Sets the transfer syntax item collection.
	 * @param objTransferSyntaxItemCollection Collection of Transfer Syntax Item.
	 */
	public void setTransferSyntaxItemCollection(ISingleCollection<TransferSyntaxItem> objTransferSyntaxItemCollection) 
	{
		this.objTransferSyntaxItemCollection = objTransferSyntaxItemCollection;
	}

	/**
	 * This function gets the RQ Presentation Context item length.
	 * @return short - Short value of RQ Presentation Context item.
	 */
	public short getItemLength() 
	{
		short shItemlength = super.getItemLength();
		if(objAbstractSyntaxItem != null)
			shItemlength += (short)(objAbstractSyntaxItem.getItemLength()+ EnumLength.ITEM_HEADER_LENGTH.getShortValue());
		ICollectionIterator<TransferSyntaxItem> objTransferSyntaxIterator = objTransferSyntaxItemCollection.iterator();
		TransferSyntaxItem objTempTransferSyntaxItem = null;
		while(objTransferSyntaxIterator.hasNext())
		{
			objTempTransferSyntaxItem = objTransferSyntaxIterator.next();
			shItemlength += (short)(objTempTransferSyntaxItem.getItemLength()+ EnumLength.ITEM_HEADER_LENGTH.getShortValue());
		}
		return shItemlength;
	}

	/**
	 * Parses RQ Presentation Context item.
	 * @param objIDicomStream Dicom Stream on which Dicom Data resides.
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void parse(IDicomStream objIDicomStream)throws IOException
	{
		super.parse(objIDicomStream);

		byte iItemTypeValue;
		objIDicomStream.skip(3); //Skipping reserved bytes because while serializing these bytes 00H velue needs to be set.
		objIDicomStream.mark(1);
		byte iTempItemValue = objIDicomStream.readByte();
		if(iTempItemValue == EnumItemType.RQ_ABSTRACT_SYNTAX_ITEM.getValue())
		{
			objAbstractSyntaxItem = new AbstractSyntaxItem();
			objIDicomStream.reset();
			objAbstractSyntaxItem.parse(objIDicomStream);
		}
		//Parsing Multiple Items of TransferSyntax
		objIDicomStream.mark(1);
		iItemTypeValue = objIDicomStream.readByte();
		if(iItemTypeValue == EnumItemType.TRANSFER_SYNTAX_ITEM.getValue())
		{
			do
			{
				objIDicomStream.reset();
				TransferSyntaxItem objTempTransferSyntaxItem = new TransferSyntaxItem();
				objTempTransferSyntaxItem.parse(objIDicomStream);
				objTransferSyntaxItemCollection.add(objTempTransferSyntaxItem);
				objIDicomStream.mark(1);
				iItemTypeValue = objIDicomStream.readByte();
			}while((iItemTypeValue == EnumItemType.TRANSFER_SYNTAX_ITEM.getValue()));
			objIDicomStream.reset();
		}
	}

	/**
	 * This method writes the Data Value to the given Stream.
	 * @param objIDicomStream object of the stream onto which RQ Presentation Context Item is to be written.
	 * @throws IOException Signals that an IO Exception has occurred.
	 */
	public void serialize(IDicomStream objIDicomStream) throws IOException
	{
		super.serialize(objIDicomStream);
		objIDicomStream.writeByte((byte)0);
		objIDicomStream.writeByte((byte)0);
		objIDicomStream.writeByte((byte)0);
		if(objAbstractSyntaxItem != null)
			objAbstractSyntaxItem.serialize(objIDicomStream);

		//Serializing Multiple Items of TransferSyntax
		ICollectionIterator<TransferSyntaxItem> objTransferSyntaxIterator = objTransferSyntaxItemCollection.iterator();
		TransferSyntaxItem objTempTransferSyntaxItem = null;
		while(objTransferSyntaxIterator.hasNext())
		{
			objTempTransferSyntaxItem = objTransferSyntaxIterator.next();
			objTempTransferSyntaxItem.serialize(objIDicomStream);
		}
	}
}
