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

/**
 * The Class UserInfoItem.
 */
public class UserInfoItem extends AssociationItem 
{

	/** The object of max length item. */
	MaxLengthItem objMaxLengthItem = null;

	/** The object of implementation class uid item. */
	ImplClassUIDItem objImplClassUIDItem = null;

	/** The object of implementation version name item. */
	ImplVersionNameItem objImplVersionNameItem = null;

	/** The object of async ops window item. */
	AsyncOpsWindowItem objAsyncOpsWindowItem = null;

	/** The object of scuscp role selection item. */
	SCUSCPRoleSelectionItem objSCUSCPRoleSelectionItem = null;

	/** The object of SOP Class Ext Negotiation Item. */
	ISingleCollection<SOPClassExtNegotiationItem>  objCollSingleCollection = null;

	/**
	 * Instantiates a new user info item.
	 */
	public UserInfoItem()
	{
		super(EnumItemType.USER_INFORMATION_ITEM.getValue());
	}

	/**
	 * Instantiates a new user info item.
	 * @param maxlength the maxlength
	 * @param ImplVersionName  the implementation version name
	 */
	public UserInfoItem(int maxlength ,String ImplVersionName)
	{
		super(EnumItemType.USER_INFORMATION_ITEM.getValue());
		objMaxLengthItem = new MaxLengthItem(maxlength);
		objImplVersionNameItem = new ImplVersionNameItem(ImplVersionName);
	}


	/**
	 * @param objSOPClassExtNegotiationItem
	 */
	public void addSOPClassExtNegotiationItem(SOPClassExtNegotiationItem objSOPClassExtNegotiationItem) 
	{
		if(objCollSingleCollection == null)
			objCollSingleCollection = new SingleCollection<SOPClassExtNegotiationItem>();
		objCollSingleCollection.add(objSOPClassExtNegotiationItem);
	}	

	/**
	 * @param objSOPClassExtNegotiationItem
	 */
	public void setSOPClassExtNegotiationItems(ISingleCollection<SOPClassExtNegotiationItem> objSOPClassExtNegotiationItem) 
	{
		this.objCollSingleCollection = objSOPClassExtNegotiationItem;		
	}

	/**
	 * @return
	 */
	public ISingleCollection<SOPClassExtNegotiationItem> getSOPClassExtNegotiationItems() 
	{
		return	objCollSingleCollection;
	}	
	/**
	 * Gets ASYNCHRONOUS OPERATIONS WINDOW item.
	 * @return AsyncOpsWindowItem - the ASYNCHRONOUS OPERATIONS WINDOW item.
	 */
	public AsyncOpsWindowItem getAsyncOpsWindowItem() 
	{
		return objAsyncOpsWindowItem;
	}

	/**
	 * Sets the ASYNCHRONOUS OPERATIONS WINDOW item.
	 * @param objAsyncOpsWindowItem object of ASYNCHRONOUS OPERATIONS WINDOW
	 */
	public void setAsyncOpsWindowItem(AsyncOpsWindowItem objAsyncOpsWindowItem) 
	{
		this.objAsyncOpsWindowItem = objAsyncOpsWindowItem;
	}

	/**
	 * Gets the implementation class uid item.
	 * @return ImplClassUIDItem - the implementation class uid item.
	 */
	public ImplClassUIDItem getImplClassUIDItem() 
	{
		return objImplClassUIDItem;
	}

	/**
	 * Sets the implementation class uid item.
	 * @param objImplClassUIDItem - object of implementation class uid item.
	 */
	public void setImplClassUIDItem(ImplClassUIDItem objImplClassUIDItem) 
	{
		this.objImplClassUIDItem = objImplClassUIDItem;
	}

	/**
	 * Gets the implementation version name item.
	 * @return ImplVersionNameItem - the implementation version name item
	 */
	public ImplVersionNameItem getImplVersionNameItem()
	{
		return objImplVersionNameItem;
	}

	/**
	 * Sets the implementation version name item.
	 * @param objImplVersionNameItem Implementation Version Name Item.
	 */
	public void setImplVersionNameItem(ImplVersionNameItem objImplVersionNameItem)
	{
		this.objImplVersionNameItem = objImplVersionNameItem;
	}

	/**
	 * Gets the max length item.
	 * @return MaxLengthItem - the max length item.
	 */
	public MaxLengthItem getMaxLengthItem() 
	{
		return objMaxLengthItem;
	}

	/**
	 * Sets the max length item.
	 * @param objMaxLengthItem object of Max Length Item.
	 */
	public void setMaxLengthItem(MaxLengthItem objMaxLengthItem) 
	{
		this.objMaxLengthItem = objMaxLengthItem;
	}

	/**
	 * Gets the SCUSCP role selection item.
	 * @return SCUSCPRoleSelectionItem - SCUSCP role selection item
	 */
	public SCUSCPRoleSelectionItem getSCUSCPRoleSelectionItem() 
	{
		return objSCUSCPRoleSelectionItem;
	}

	/**
	 * Sets the SCU/SCP role selection item.
	 * @param objSCUSCPRoleSelectionItem object of SCU/SCP role selection item.
	 */
	public void setSCUSCPRoleSelectionItem(SCUSCPRoleSelectionItem objSCUSCPRoleSelectionItem) 
	{
		this.objSCUSCPRoleSelectionItem = objSCUSCPRoleSelectionItem;
	}

	/**
	 * This method Retrieves the item length of User Info.
	 * @return short - short value of User Info Item.
	 */
	public short getItemLength() 
	{
		short shItemLength = 0;
		if(objMaxLengthItem != null)
			shItemLength = (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + objMaxLengthItem.getItemLength());
		if(objImplClassUIDItem != null)
			shItemLength += (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + objImplClassUIDItem.getItemLength());
		if(objImplVersionNameItem != null)
			shItemLength += (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + objImplVersionNameItem.getItemLength());
		if(objAsyncOpsWindowItem != null)
			shItemLength += (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + objAsyncOpsWindowItem.getItemLength());
		if(objSCUSCPRoleSelectionItem != null)
			shItemLength += (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + objSCUSCPRoleSelectionItem.getItemLength());		
		if(objCollSingleCollection != null)
		{
			for (SOPClassExtNegotiationItem element : objCollSingleCollection) 
			{
				shItemLength += (short)(EnumLength.ITEM_HEADER_LENGTH.getShortValue() + element.getItemLength());				
			}
		}

		return shItemLength;
	}

	/**
	 * This method parse the User Info Item from the given Dicom Stream.
	 * @param objIDicomStream Dicom Stream containing the dicom data .
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void parse(IDicomStream objIDicomStream)throws IOException
	{
		super.parse(objIDicomStream);
		byte iTempItemValue;

		objIDicomStream.readShort();
		objIDicomStream.mark(1);
		iTempItemValue = objIDicomStream.readByte();

		EnumItemType enumItemType = StandardMethods.getUserInfoItemType(iTempItemValue);

		while(enumItemType == EnumItemType.USER_INFO_MAX_LENGTH_ITEM || enumItemType == EnumItemType.USER_INFO_IMPL_CLASS_UID_ITEM  
				|| enumItemType == EnumItemType.USER_INFO_IMPL_VERSION_NAME_ITEM  || enumItemType == EnumItemType.USER_INFO_ASYNC_OPS_WINDOW_ITEM 
				|| enumItemType == EnumItemType.USER_INFO_SCU_SCP_ROLE_SELECTION_ITEM
				|| enumItemType == EnumItemType.SOP_CLASS_EXTENDED_NEGOTIATION_ITEM)
		{
			switch(enumItemType)
			{
			case USER_INFO_MAX_LENGTH_ITEM:
				objMaxLengthItem = new MaxLengthItem();
				objIDicomStream.reset();
				objMaxLengthItem.parse(objIDicomStream);
				break;
			case USER_INFO_IMPL_CLASS_UID_ITEM :
				objImplClassUIDItem = new ImplClassUIDItem();
				objIDicomStream.reset();
				objImplClassUIDItem.parse(objIDicomStream);
				break;
			case USER_INFO_IMPL_VERSION_NAME_ITEM :
				objImplVersionNameItem = new ImplVersionNameItem();
				objIDicomStream.reset();
				objImplVersionNameItem.parse(objIDicomStream);
				break;
			case USER_INFO_ASYNC_OPS_WINDOW_ITEM :
				objAsyncOpsWindowItem = new AsyncOpsWindowItem();
				objIDicomStream.reset();
				objAsyncOpsWindowItem.parse(objIDicomStream);
				break;
			case USER_INFO_SCU_SCP_ROLE_SELECTION_ITEM :
				objSCUSCPRoleSelectionItem = new SCUSCPRoleSelectionItem();
				objIDicomStream.reset();
				objSCUSCPRoleSelectionItem.parse(objIDicomStream);
				break;
			case SOP_CLASS_EXTENDED_NEGOTIATION_ITEM :
				if(objCollSingleCollection == null)
					objCollSingleCollection = new SingleCollection<SOPClassExtNegotiationItem>();
				SOPClassExtNegotiationItem objSOPClassExtNegotiationItem = new SOPClassExtNegotiationItem();				
				objIDicomStream.reset();
				objSOPClassExtNegotiationItem.parse(objIDicomStream);
				objCollSingleCollection.add(objSOPClassExtNegotiationItem);
				break;
			}
			objIDicomStream.mark(1);
			iTempItemValue = objIDicomStream.readByte();
			enumItemType = StandardMethods.getUserInfoItemType(iTempItemValue);
		}
		if(objIDicomStream.available() != 0)
			objIDicomStream.reset();
	}

	/**
	 * This method writes the Data Value to the given Stream.
	 * @param objIDicomStream object of the stream to which User Info Item is to be written.
	 * @throws IOException Signals IO Exception if IO Operation fails.
	 */
	public void serialize(IDicomStream objIDicomStream) throws IOException
	{
		super.serialize(objIDicomStream);
		objIDicomStream.writeShort(getItemLength());
		if(objMaxLengthItem != null)
			objMaxLengthItem.serialize(objIDicomStream);
		if(objImplClassUIDItem != null)
			objImplClassUIDItem.serialize(objIDicomStream);
		if(objAsyncOpsWindowItem != null)
			objAsyncOpsWindowItem.serialize(objIDicomStream);
		if(objSCUSCPRoleSelectionItem != null)
			objSCUSCPRoleSelectionItem.serialize(objIDicomStream);
		if(objImplVersionNameItem != null)
			objImplVersionNameItem.serialize(objIDicomStream);
		if(objCollSingleCollection != null)
			for (SOPClassExtNegotiationItem element : objCollSingleCollection) 
			{
				element.serialize(objIDicomStream);
			}
	}


}
