/*******************************************************************************
 *  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.baselibs;



import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomValue;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDictionaryReader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITransferSyntax;
import cdac.medinfo.sdk.dcm30_04.enums.EnumContrastBolusIngredientOpaque;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.exceptions.MandatoryMissingException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;




/**
* This item class contains the methods to set,get and validate the attribute present in Contrast Bolus Agent Sequence Item
 */
public class ContrastBolusAgentSequenceItem extends CodeSequenceMacroDependentItem  
{
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * This constructor creates the item and internal code sequence macro with default TransferSyntax 
	 */
	ContrastBolusAgentSequenceItem()
	{
		super();
	}

	/**
	 * This constructor creates the item ContrastBolusAgentSequenceItem with default TransferSyntax 
	 * and default DictionaryReader
	 * @param objITransferSyntax  specifies the DICOM Standard defined TransfeSyntax
	 */
	ContrastBolusAgentSequenceItem(ITransferSyntax objITransferSyntax)
	{
		super(objITransferSyntax);
	}

	/**
	 * This constructor creates ContrastBolusAgentSequenceItem with specified TransferSyntax and
	 * specified DictionaryReader
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	ContrastBolusAgentSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}

	/**
	 * Sets Identifying number, unique within this SOP Instance, of the agent administered.
	 * @param shContrastOrBolusAgentNumber short value of number
	 */
	public void setContrastOrBolusAgentNumber(short shContrastOrBolusAgentNumber)
	{
		/*Accept the ContrastOrBolusAgentNumber in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x9337, shContrastOrBolusAgentNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x9337,DicomConstants.DCM_DT_US, shContrastOrBolusAgentNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Identifying number, unique within this SOP Instance, of the agent administered.
	 * @return short - short value of number.
	 */
	public short getContrastOrBolusAgentNumber()
	{
		Object objValue = getValue(0x0018,0x9337);
		if(objValue != null)
			return Short.parseShort(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Volume administered during this phase in milliliters of diluted contrast agent.
	 * @param strContrastOrBolusVolume String value of ContrastOrBolusVolume
	 */
	public void setContrastOrBolusVolume(String strContrastOrBolusVolume)
	{
		/*Accept the ContrastOrBolusVolume in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x1041, strContrastOrBolusVolume,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1041,DicomConstants.DCM_DT_DS, strContrastOrBolusVolume);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Volume administered during this phase in milliliters of diluted contrast agent.
	 * @return String - String value of ContrastOrBolusVolume.
	 */
	public String getContrastOrBolusVolume()
	{
		Object objValue = getValue(0x0018,0x1041);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets Milligrams of active ingredient per milliliter of agent.
	 * @param strContrastOrBolusIngredientConcentration String value of of active ingredient
	 */
	public void setContrastOrBolusIngredientConcentration(String strContrastOrBolusIngredientConcentration)
	{
		/*Accept the ContrastOrBolusIngredientConcentration in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x1049, strContrastOrBolusIngredientConcentration,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1049,DicomConstants.DCM_DT_DS, strContrastOrBolusIngredientConcentration);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Milligrams of active ingredient per milliliter of agent.
	 * @return String - String value of active ingredient.
	 */
	public String getContrastOrBolusIngredientConcentration()
	{
		Object objValue = getValue(0x0018,0x1049);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	
	/**
	 * Sets the percentage by volume of active ingredient in the total volume.
	 * @param fContrastBolusIngredientPercentbyVolume Float value of the Ratio of displayed pixels to source pixels
	 */
	public void setContrastBolusIngredientPercentbyVolume( float fContrastBolusIngredientPercentbyVolume)
	{
		/*
		 * Accept the ContrastBolusIngredientPercentbyVolume in String format of type FL.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0052,0x0001, fContrastBolusIngredientPercentbyVolume,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0052,0x0001,DicomConstants.DCM_DT_FL, fContrastBolusIngredientPercentbyVolume);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the Ratio of displayed pixels to source pixels,specified in one dimension.
	 * @return float - Float value of the Ratio of displayed pixels to source pixels
	 */
	public float getContrastBolusIngredientPercentbyVolume()
	{ 
		Object objValue = getValue(0x0052,0x0001);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets the absorption of the ingredient greater than the absorption of water (tissue).
	 * @param enumContrastBolusIngredientOpaque Specifies type of the value encoded in this Item
	 */
	public void setContrastBolusIngredientOpaque(EnumContrastBolusIngredientOpaque enumContrastBolusIngredientOpaque)
	{
		/* Accept the Value Type in String format of type CS.
		 * Absorption of the ingredient greater than the absorption of water (tissue).
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018, 0x9425, enumContrastBolusIngredientOpaque,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018, 0x9425,DicomConstants.DCM_DT_CS, enumContrastBolusIngredientOpaque);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getContrastBolusIngredientOpaque()
	{
		Object objValue = getValue(0x0018, 0x9425);
		if(objValue != null)
			return objValue.toString();
		return null;
	}


	/**
	 * Sets the T1 Relaxivity of the MR Contrast/Bolus used specified in s-1*mmol-1 specified at body temperature in human blood plasma.
	 * @param fContrastBolusT1Relaxivity Float value of the Ratio of displayed pixels to source pixels
	 */
	public void setContrastBolusT1Relaxivity( float fContrastBolusT1Relaxivity)
	{
		/*
		 * Accept the ContrastBolusT1Relaxivity in String format of type FL.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0018,0x0013, fContrastBolusT1Relaxivity,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x0013,DicomConstants.DCM_DT_FL, fContrastBolusT1Relaxivity);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the Ratio of displayed pixels to source pixels,specified in one dimension.
	 * @return float - Float value of the Ratio of displayed pixels to source pixels
	 */
	public float getContrastBolusT1Relaxivity()
	{ 
		Object objValue = getValue(0x0018,0x0013);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Retrieves pre-initialized object of Contrast Bolus Administration Route Sequence.If the module contains the sequence object
	 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
	 * and then returns the object of sequence
	 * @return ContrastBolusAdministrationRouteSequence - instance of ContrastBolusAdministrationRouteSequence. 
	 */
	public ContrastBolusAdministrationRouteSequence getContrastBolusAdministrationRouteSequence()
	{
		ContrastBolusAdministrationRouteSequence objContrastBolusAdministrationRouteSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0018,0x0014);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objContrastBolusAdministrationRouteSequence = (ContrastBolusAdministrationRouteSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objContrastBolusAdministrationRouteSequence = (ContrastBolusAdministrationRouteSequence)objDicomV3Factory.createSequence(0x0018,0x0014, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0018,0x0014, objContrastBolusAdministrationRouteSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0018,0x0014, DicomConstants.DCM_DT_SQ, objContrastBolusAdministrationRouteSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objContrastBolusAdministrationRouteSequence;
	}

	/**
	 * Retrieves pre-initialized object of Contrast Bolus Ingredient Code Sequence.If the module contains the sequence object
	 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
	 * and then returns the object of sequence
	 * @return ContrastBolusIngredientCodeSequence - instance of ContrastBolusIngredientCodeSequence. 
	 */
	public ContrastBolusIngredientCodeSequence getContrastBolusIngredientCodeSequence()
	{
		ContrastBolusIngredientCodeSequence objContrastBolusIngredientCodeSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0018,0x9338);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objContrastBolusIngredientCodeSequence = (ContrastBolusIngredientCodeSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objContrastBolusIngredientCodeSequence = (ContrastBolusIngredientCodeSequence)objDicomV3Factory.createSequence(0x0018,0x9338, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0018,0x9338, objContrastBolusIngredientCodeSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0018,0x9338, DicomConstants.DCM_DT_SQ, objContrastBolusIngredientCodeSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objContrastBolusIngredientCodeSequence;
	}

	/**
	 * Retrieves pre-initialized object of Contrast Administration Profile Sequence.If the module contains the sequence object
	 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
	 * and then returns the object of sequence
	 * @return ContrastAdministrationProfileSequence - instance of ContrastAdministrationProfileSequence. 
	 */
	public ContrastAdministrationProfileSequence getContrastAdministrationProfileSequence()
	{
		ContrastAdministrationProfileSequence objContrastAdministrationProfileSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0018,0x9340);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objContrastAdministrationProfileSequence = (ContrastAdministrationProfileSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objContrastAdministrationProfileSequence = (ContrastAdministrationProfileSequence)objDicomV3Factory.createSequence(0x0018,0x9340, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0018,0x9340, objContrastAdministrationProfileSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0018,0x9340, DicomConstants.DCM_DT_SQ, objContrastAdministrationProfileSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objContrastAdministrationProfileSequence;
	}

	/**
	 * Validates all the attributes in ContrastBolusAgentSequenceItem that are present in the DataSet
	 * @return boolean - Success -true, Failure - false
	 * @throws InvalidItemException throws InvalidItemException If Mandatory or Conditional element fails.
	 */
	public boolean validateForModule()  throws InvalidItemException
	{
		try
		{
			super.validateForModule();
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),me);
		}
		return true;
	}
}
