/*******************************************************************************
 *  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.EnumBeamLimitingDeviceRotationDirection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumGantryRotationDirection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPatientSupportRotationDirection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumTableTopEccentricRotationDirection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumTableTopPitchRotationDirection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumTableTopRollRotationDirection;
import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
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 Control Point Sequence.
 */
public class ControlPointSequenceItem extends Item  
{
	

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

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

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

	/**
	 * This constructor creates ControlPointSequenceItem with specified TransferSyntax and
	 * specified DictionaryReader
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	ControlPointSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}
	
	/**
	 * Sets Index of current Control Point, starting at 0 for first Control Point.
	 * @param strControlPointIndex String value of Control Point Index.
	 */
	public void setControlPointIndex(String strControlPointIndex)
	{
		/*Accept the ControlPointIndex in String format of type IS.
		 * 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(0x300A,0x0112, strControlPointIndex,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0112,DicomConstants.DCM_DT_IS, strControlPointIndex);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Index of current Control Point, starting at 0 for first Control Point.
	 * @return String - value of Control Point Index.
	 */
	public String getControlPointIndex()
	{
		Object objValue = getValue(0x300A,0x0112);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Cumulative weight to current control point. It is always zero for first item in Control Point Sequence and 
	 * Cumulative Meterset Weight for the final item in Control Point Sequence shall always be equal to Final Cumulative Meterset Weight.
	 * @param strCumulativeMetersetWeight String value of Cumulative Meterset Weight.
	 */
	public void setCumulativeMetersetWeight(String strCumulativeMetersetWeight)
	{
		/*Accept the CumulativeMetersetWeight 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(0x300A,0x0134, strCumulativeMetersetWeight,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0134,DicomConstants.DCM_DT_DS, strCumulativeMetersetWeight);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves  Cumulative weight to current control point.
	 * @return String - value of Cumulative Meterset Weight.
	 */
	public String getCumulativeMetersetWeight()
	{
		Object objValue = getValue(0x300A,0x0134);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Retrieves pre-initialized object of Referenced Dose Reference 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 ReferencedDoseReferenceSequence - instance of Referenced Dose Reference Sequence. 
	 */
	public ReferencedDoseReferenceSequence getReferencedDoseReferenceSequence()
	{
		ReferencedDoseReferenceSequence objReferencedDoseReferenceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300C,0x0050);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedDoseReferenceSequence = (ReferencedDoseReferenceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedDoseReferenceSequence = (ReferencedDoseReferenceSequence)objDicomV3Factory.createSequence(0x300C,0x0050, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300C,0x0050, objReferencedDoseReferenceSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300C,0x0050, DicomConstants.DCM_DT_SQ, objReferencedDoseReferenceSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objReferencedDoseReferenceSequence;
	}
	/**
	 * Sets Nominal Beam Energy at control point (MV/MeV).
	 * @param strNominalBeamEnergy String value of Nominal Beam Energy.
	 */
	public void setNominalBeamEnergy(String strNominalBeamEnergy)
	{
		/*Accept the NominalBeamEnergy 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(0x300A,0x0114, strNominalBeamEnergy,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0114,DicomConstants.DCM_DT_DS, strNominalBeamEnergy);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves  Nominal Beam Energy at control point (MV/MeV).
	 * @return String - value of Nominal Beam Energy.
	 */
	public String getNominalBeamEnergy()
	{
		Object objValue = getValue(0x300A,0x0114);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Dose Rate to be set on treatment machine for segment beginning at current control point (e.g. MU/min).
	 * @param strDoseRateSet String value of Dose Rate Set.
	 */
	public void setDoseRateSet(String strDoseRateSet)
	{
		/*Accept the DoseRateSet 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(0x300A,0x0115, strDoseRateSet,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0115,DicomConstants.DCM_DT_DS, strDoseRateSet);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Dose Rate to be set on treatment machine for segment beginning at current control point (e.g. MU/min).
	 * @return String - value of  Dose Rate Set.
	 */
	public String getDoseRateSet()
	{
		Object objValue = getValue(0x300A,0x0115);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	
	/**
	 * Retrieves pre-initialized object of Wedge Position 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 WedgePositionSequence - instance of Wedge Position Sequence. 
	 */
	public WedgePositionSequence getWedgePositionSequence()
	{
		WedgePositionSequence objWedgePositionSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x0116);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objWedgePositionSequence = (WedgePositionSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objWedgePositionSequence = (WedgePositionSequence)objDicomV3Factory.createSequence(0x300A,0x0116, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x0116, objWedgePositionSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x0116, DicomConstants.DCM_DT_SQ, objWedgePositionSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objWedgePositionSequence;
	}
	
	
	/**
	 * Retrieves pre-initialized object of Beam Limiting Device Position 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 BeamLimitingDevicePositionSequence - instance of Beam Limiting Device Position Sequence. 
	 */
	public BeamLimitingDevicePositionSequence getBeamLimitingDevicePositionSequence()
	{
		BeamLimitingDevicePositionSequence objBeamLimitingDevicePositionSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x011A);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objBeamLimitingDevicePositionSequence = (BeamLimitingDevicePositionSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objBeamLimitingDevicePositionSequence = (BeamLimitingDevicePositionSequence)objDicomV3Factory.createSequence(0x300A,0x011A, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x011A, objBeamLimitingDevicePositionSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x011A, DicomConstants.DCM_DT_SQ, objBeamLimitingDevicePositionSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objBeamLimitingDevicePositionSequence;
	}
	
	
	/**
	 * Sets Gantry angle of radiation source, i.e. orientation of IEC GANTRY coordinate system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * @param strGantryAngle String value of Gantry Angle.
	 */
	public void setGantryAngle(String strGantryAngle)
	{
		/*Accept the GantryAngle 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(0x300A,0x011E, strGantryAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x011E,DicomConstants.DCM_DT_DS, strGantryAngle);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Gantry angle of radiation source.
	 * @return String - value of Gantry Angle.
	 */
	public String getGantryAngle()
	{
		Object objValue = getValue(0x300A,0x011E);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Gantry Rotation Direction. Direction of Gantry Rotation when viewing gantry from isocenter, for segment beginning at current Control Point.
	 * Enumerated Values:
	 * CW = clockwise
	 * CC = counter-clockwise
	 * NONE = no rotation
	 * @param enumGantryRotationDirection Enum value of Gantry Rotation Direction.
	 */
	public void setGantryRotationDirection(EnumGantryRotationDirection enumGantryRotationDirection)
	{
		/*Accept the GantryRotationDirection in String format of type CS.
		 * 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(0x300A,0x011F, enumGantryRotationDirection.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x011F,DicomConstants.DCM_DT_CS, enumGantryRotationDirection.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Gantry Rotation Direction.
	 * @return String - value of Gantry Rotation Direction.
	 */
	public String getGantryRotationDirection()
	{
		Object objValue = getValue(0x300A,0x011F);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Beam Limiting Device Angle. i.e. orientation of IEC BEAM LIMITING DEVICE coordinate system with respect to IEC GANTRY coordinate system (degrees).
	 * @param strBeamLimitingDeviceAngle String value of Beam Limiting Device Angle.
	 */
	public void setBeamLimitingDeviceAngle(String strBeamLimitingDeviceAngle)
	{
		/*Accept the BeamLimitingDeviceAngle 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(0x300A,0x0120, strBeamLimitingDeviceAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0120,DicomConstants.DCM_DT_DS, strBeamLimitingDeviceAngle);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Beam Limiting Device Angle.
	 * @return String - value of Beam Limiting Device Angle.
	 */
	public String getBeamLimitingDeviceAngle()
	{
		Object objValue = getValue(0x300A,0x0120);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Beam Limiting Device Rotation Direction. Direction of Beam Limiting Device Rotation when viewing beam limiting device (collimator) from radiation source, for segment beginning at current Control Point.
	 * Enumerated Values:
	 * CW = clockwise,
	 * CC = counter-clockwise,
	 * NONE = no rotation.
	 * @param enumBeamLimitingDeviceRotationDirection Enum value of Beam Limiting Device Rotation Direction.
	 */
	public void setBeamLimitingDeviceRotationDirection(EnumBeamLimitingDeviceRotationDirection enumBeamLimitingDeviceRotationDirection)
	{
		/*Accept the BeamLimitingDeviceRotationDirection in String format of type CS.
		 * 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(0x300A,0x0121, enumBeamLimitingDeviceRotationDirection.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0121,DicomConstants.DCM_DT_CS, enumBeamLimitingDeviceRotationDirection.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Beam Limiting Device Rotation Direction.
	 * @return String - value of Beam Limiting Device Rotation Direction.
	 */
	public String getBeamLimitingDeviceRotationDirection()
	{
		Object objValue = getValue(0x300A,0x0121);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Patient Support Angle. i.e. orientation of IEC PATIENT SUPPORT (turntable) coordinate system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * @param strPatientSupportAngle String value of Patient Support Angle.
	 */
	public void setPatientSupportAngle(String strPatientSupportAngle)
	{
		/*Accept the PatientSupportAngle 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(0x300A,0x0122, strPatientSupportAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0122,DicomConstants.DCM_DT_DS, strPatientSupportAngle);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Patient Support Angle.
	 * @return String - value of Patient Support Angle.
	 */
	public String getPatientSupportAngle()
	{
		Object objValue = getValue(0x300A,0x0122);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	
	/**
	 * Sets Patient Support Rotation Direction. Direction of Patient Support Rotation when viewing table from above, for segment beginning at current Control Point.
	 * Enumerated Values:
	 * CW = clockwise,
	 * CC = counter-clockwise,
	 * NONE = no rotation.
	 * @param enumPatientSupportRotationDirection Enum value of Patient Support Rotation Direction.
	 */
	public void setPatientSupportRotationDirection(EnumPatientSupportRotationDirection enumPatientSupportRotationDirection)
	{
		/*Accept the PatientSupportRotationDirection in String format of type CS.
		 * 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(0x300A,0x0123, enumPatientSupportRotationDirection.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0123,DicomConstants.DCM_DT_CS, enumPatientSupportRotationDirection.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Patient Support Rotation Direction.
	 * @return String - value of Patient Support Rotation Direction.
	 */
	public String getPatientSupportRotationDirection()
	{
		Object objValue = getValue(0x300A,0x0123);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Table Top Eccentric Axis Distance. Distance (positive) from the IEC PATIENT SUPPORT vertical axis to the IEC TABLE TOP ECCENTRIC vertical axis (mm).
	 * @param strTableTopEccentricAxisDistance String value of Table Top Eccentric Axis Distance.
	 */
	public void setTableTopEccentricAxisDistance(String strTableTopEccentricAxisDistance)
	{
		/*Accept the TableTopEccentricAxisDistance 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(0x300A,0x0124, strTableTopEccentricAxisDistance,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0124,DicomConstants.DCM_DT_DS, strTableTopEccentricAxisDistance);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Table Top Eccentric Axis Distance.
	 * @return String - value of Table Top Eccentric Axis Distance.
	 */
	public String getTableTopEccentricAxisDistance()
	{
		Object objValue = getValue(0x300A,0x0124);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Table Top Eccentric Angle. Table Top (non-isocentric) angle, i.e. orientation of IEC TABLE TOP ECCENTRIC coordinate system with respect to IEC PATIENT SUPPORT coordinate system (degrees).
	 * @param strTableTopEccentricAngle String value of Table Top Eccentric Angle.
	 */
	public void setTableTopEccentricAngle(String strTableTopEccentricAngle)
	{
		/*Accept the TableTopEccentricAngle 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(0x300A,0x0125, strTableTopEccentricAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0125,DicomConstants.DCM_DT_DS, strTableTopEccentricAngle);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Table Top Eccentric Angle.
	 * @return String - value of Table Top Eccentric Angle.
	 */
	public String getTableTopEccentricAngle()
	{
		Object objValue = getValue(0x300A,0x0125);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Table Top Eccentric Rotation Direction. Direction of Table Top Eccentric Rotation when viewing table from above, for segment beginning at current Control Point.
	 * Enumerated Values:
	 * CW = clockwise,
	 * CC = counter-clockwise,
	 * NONE = no rotation.
	 * @param enumTableTopEccentricRotationDirection Enum value of Table Top Eccentric Rotation Direction.
	 */
	public void setTableTopEccentricRotationDirection(EnumTableTopEccentricRotationDirection enumTableTopEccentricRotationDirection)
	{
		/*Accept the TableTopEccentricRotationDirection in String format of type CS.
		 * 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(0x300A,0x0126, enumTableTopEccentricRotationDirection.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0126,DicomConstants.DCM_DT_CS, enumTableTopEccentricRotationDirection.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Table Top Eccentric Rotation Direction.
	 * @return String - value of Table Top Eccentric Rotation Direction.
	 */
	public String getTableTopEccentricRotationDirection()
	{
		Object objValue = getValue(0x300A,0x0126);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	
	/**
	 * Sets the Ratio of displayed pixels to source pixels,specified in one dimension.
	 * @param fTableTopPitchAngle Float value of the Ratio of displayed pixels to source pixels
	 */
	public void setTableTopPitchAngle( float fTableTopPitchAngle)
	{
		/*
		 * Accept the TableTopPitchAngle 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(0x300A,0x0140, fTableTopPitchAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0140,DicomConstants.DCM_DT_FL, fTableTopPitchAngle);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves fTableTopPitchAngle
	 * @return float - Float value of the Ratio of displayed pixels to source pixels
	 */
	public float getTableTopPitchAngle()
	{
		Object objValue = getValue(0x300A,0x0140);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	
	/**
	 * Sets Direction of Table Top Pitch Rotation when viewing the table along the positive 
	 * X-axis of the IEC TABLE TOP coordinate system, for segmentfollowing Control Point.
	 * @param strValueType Specifies type of the value encoded in this Item
	 */
	public void setTableTopPitchRotationDirection(EnumTableTopPitchRotationDirection enumTableTopPitchRotationDirection)
	{
		/* Accept the Value Type in String format of type CS.
		 * Read Table Top Pitch Rotation Direction
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x0142, enumTableTopPitchRotationDirection,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A, 0x0142,DicomConstants.DCM_DT_CS, enumTableTopPitchRotationDirection);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getTableTopPitchRotationDirection()
	{
		Object objValue = getValue(0x300A, 0x0142);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Table Top Roll Angle, i.e., the rotation of the IEC TABLE TOP coordinatesystem 
	 * about the IEC Y-axis of the IEC TABLE TOP coordinate system(degrees).
	 * @param fPresentationPixelMagnificationRatio Float value of the Ratio of displayed pixels to source pixels
	 */
	public void setTableTopRollAngle( float fTableTopRollAngle)
	{
		/* Accept the Table Top Roll Angle in String format of type FL.
		 * Sets Table Top Roll Angle, i.e., the rotation of the IEC TABLE TOP coordinatesystem 
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x300A,0x0144, fTableTopRollAngle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0144,DicomConstants.DCM_DT_FL, fTableTopRollAngle);

		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 getTableTopRollAngle()
	{
		Object objValue = getValue(0x300A,0x0144);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	
	/**
	 * Sets Direction of Table Top Pitch Rotation when viewing the table along the positive 
	 * X-axis of the IEC TABLE TOP coordinate system, for segmentfollowing Control Point.
	 * @param strValueType Specifies type of the value encoded in this Item
	 */
	public void setTableTopRollRotationDirection(EnumTableTopRollRotationDirection enumTableTopRollRotationDirection)
	{
		/* Accept the Value Type in String format of type CS.
		 * Read Table Top Pitch Rotation Direction
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x0146, enumTableTopRollRotationDirection,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A, 0x0146,DicomConstants.DCM_DT_CS, enumTableTopRollRotationDirection);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getTableTopRollRotationDirection()
	{
		Object objValue = getValue(0x300A, 0x0146);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	
	
	/**
	 * Sets Table Top Vertical Position. Table Top Vertical position in IEC TABLE TOP coordinate system (mm).
	 * @param strTableTopVerticalPosition String value of Table Top Vertical Position.
	 */
	public void setTableTopVerticalPosition(String strTableTopVerticalPosition)
	{
		/*Accept the TableTopVerticalPosition 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(0x300A,0x0128, strTableTopVerticalPosition,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0128,DicomConstants.DCM_DT_DS, strTableTopVerticalPosition);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Table Top Vertical Position.
	 * @return String - value of Table Top Vertical Position.
	 */
	public String getTableTopVerticalPosition()
	{
		Object objValue = getValue(0x300A,0x0128);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Table Top Longitudinal Position. Table Top Longitudinal position in IEC TABLE TOP coordinate system (mm).
	 * @param strTableTopLongitudinalPosition String value of Table Top Longitudinal Position.
	 */
	public void setTableTopLongitudinalPosition(String strTableTopLongitudinalPosition)
	{
		/*Accept the TableTopLongitudinalPosition 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(0x300A,0x0129, strTableTopLongitudinalPosition,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0129,DicomConstants.DCM_DT_DS, strTableTopLongitudinalPosition);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Table Top Longitudinal Position.
	 * @return String - value of Table Top Longitudinal Position.
	 */
	public String getTableTopLongitudinalPosition()
	{
		Object objValue = getValue(0x300A,0x0129);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Table Top Lateral Position. Table Top Lateral position in IEC TABLE TOP coordinate system (mm).
	 * @param strTableTopLateralPosition String value of Table Top Lateral Position.
	 */
	public void setTableTopLateralPosition(String strTableTopLateralPosition)
	{
		/*Accept the TableTopLateralPosition 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(0x300A,0x012A, strTableTopLateralPosition,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x012A,DicomConstants.DCM_DT_DS, strTableTopLateralPosition);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Table Top Lateral Position.
	 * @return String - value of Table Top Lateral Position.
	 */
	public String getTableTopLateralPosition()
	{
		Object objValue = getValue(0x300A,0x012A);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Isocenter coordinates (x,y,z) in the patient based coordinate system.
	 * @param arrIsocenterPosition String array of Isocenter Position.
	 */
	public void setIsocenterPosition(String[] arrIsocenterPosition)
	{
		/*Accept the Isocenter Position 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(0x300A,0x012C, arrIsocenterPosition,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x012C,DicomConstants.DCM_DT_DS, arrIsocenterPosition);

		addDataElement(objIDataElement);
	}
	
	/**
	 * Retrieves Isocenter coordinates (x,y,z) in the patient based coordinate system.
	 * @return String - array of Isocenter Position.
	 */
	public String[] getIsocenterPosition()
	{
		Object objValue = getValue(0x300A,0x012C);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	
	/**
	 * Sets Patient surface entry point coordinates (x,y,z) in the patient based coordinate system .
	 * @param arrSurfaceEntryPoint String array of Surface Entry Point.
	 */
	public void setSurfaceEntryPoint(String[] arrSurfaceEntryPoint)
	{
		/*Accept the Surface Entry Point 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(0x300A,0x012E, arrSurfaceEntryPoint,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x012E,DicomConstants.DCM_DT_DS, arrSurfaceEntryPoint);

		addDataElement(objIDataElement);
	}
	
	/**
	 * Retrieves Patient surface entry point coordinates (x,y,z) in the patient based coordinate system .
	 * @return String - array of Surface Entry Point.
	 */
	public String[] getSurfaceEntryPoint()
	{
		Object objValue = getValue(0x300A,0x012E);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	

	/**
	 * Sets Source to Patient Surface distance (mm).
	 * @param strSourcetoSurfaceDistance String value of Source to Surface Distance.
	 */
	public void setSourcetoSurfaceDistance(String strSourcetoSurfaceDistance)
	{
		/*Accept the SourcetoSurfaceDistance 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(0x300A,0x0130, strSourcetoSurfaceDistance,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0130,DicomConstants.DCM_DT_DS, strSourcetoSurfaceDistance);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Source to Patient Surface distance (mm).
	 * @return String - value of Source to Surface Distance
	 */
	public String getSourcetoSurfaceDistance()
	{
		Object objValue = getValue(0x300A,0x0130);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Validates all the attributes in ControlPointSequenceItem  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
	{
		String strControlPointIndex = "0";
		try
		{
			
			if(!contains(0x300A,0x0112))
				throw new MandatoryMissingException("300A,0112");			
			if(!contains(0x300A,0x00B8))
				throw new MandatoryMissingException("300A,00B8");
			if(!contains(0x300A,0x011C))
				throw new MandatoryMissingException("300A,011C");
			
			/*
			 * Tag 300A,011A
			 * Introduces sequence of beam limiting device (collimator) jaw or leaf (element) positions.
			 * Required for first item of Control Point Sequence, or if Beam Limiting Device changes during Beam.
			 * How to know whether beam limiting device changes during beam.
			 */
			String strValueControlPointIndex= getControlPointIndex();
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x011A)))
				throw new ConditionFailedException("300A,011A is required if value of Control Point Index is 0");
			
			/*
			 * Tag 300A,011E
			 * Gantry angle of radiation source, i.e. orientation of IEC GANTRY coordinate system with respect to IEC FIXED REFERENCE coordinate system (degrees).
			 * Required for first item of Control Point Sequence, or if Gantry Angle changes during Beam.
			 * How to know whether Gantry Angle changes during Beam.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x011E)))
				throw new ConditionFailedException("300A,011E is required if value of Control Point Index is 0");
			
			/*
			 * Tag 300A,011F
			 * Direction of Gantry Rotation when viewing gantry from isocenter, for segment following Control Point. Required for first item of Control Point Sequence,
			 * or if Gantry Rotation Direction changes during Beam.
			 * How to know whether Gantry Rotation Direction changes during Beam.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x011F)))
				throw new ConditionFailedException("300A,011F is required if value of Control Point Index is 0");
			
			/*
			 * Tag 300A,0120
			 * Beam Limiting Device (collimator) angle, i.e. orientation of IEC BEAM LIMITING DEVICE coordinate system with respect to IEC GANTRY coordinate system.
			 * Required for first item of Control Point Sequence,
			 * or if beam limiting device (collimator) angle changes during beam delivery.
			 * How to know whether beam limiting device (collimator) angle changes during beam delivery
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0120)))
				throw new ConditionFailedException("300A,0120 is required if value of Control Point Index is 0");
			/*
			 * Tag 300A,0121
			 * Direction of Beam Limiting Device Rotation when viewing beam limiting device (collimator) from radiation source, for
			 * segment beginning at current Control Point.
			 * Required for first item of Control Point Sequence, or if Beam Limiting Device
			 * Rotation Direction changes during beam administration.
			 * How to know whether Rotation Direction changes during beam administration.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0121)))
				throw new ConditionFailedException("300A,0121 is required if value of Control Point Index is 0");
			/*
			 * Tag 300A,0122
			 * Patient Support angle, i.e. orientation of IEC PATIENT SUPPORT (turntable) coordinate system with respect to IEC FIXED REFERENCE coordinate system.
			 * Required for first item of Control Point Sequence, or if Patient Support Angle changes during beam administration.
			 * How to know whether Patient Support Angle changes during beam administration.
			 */
			
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0122)))
				throw new ConditionFailedException("300A,0122 is required if value of Control Point Index is 0");
			
			/*
			 * Tag 300A,0123
			 * Direction of Patient Support Rotation when viewing table from above, for segment beginning at current Control Point.
			 * Required for first item of Control Point Sequence,
			 * or if Patient Support Rotation Direction changes during beam administration.
			 * How to know whether Patient Support Rotation Direction changes during beam administration.
			 */
			
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0123)))
				throw new ConditionFailedException("300A,0123 is required if value of Control Point Index is 0");
			
			/*
			 * Tag 300A,0125
			 * Table Top (non-isocentric) angle, i.e. orientation of IEC TABLE TOP ECCENTRIC coordinate system with with respect to IEC PATIENT SUPPORT coordinate system.
			 * Required for first item of Control Point Sequence,or if Table Top Eccentric Angle changes during beam administration.
			 * How to know whether Table Top Eccentric Angle changes during beam administration.
			 */
			
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0125)))
				throw new ConditionFailedException("300A,0125 is required if value of Control Point Index is 0");
			
			/*
			 * 300A,0126
			 * Direction of Table Top Eccentric Rotation when viewing table from above,
			 * for segment beginning at current Control Point.
			 * Required for first item of Control Point Sequence, or if Table Top Eccentric Rotation Direction changes during beam administration.
			 * How to know whether Table Top Eccentric Rotation Direction changes during beam administration.
			 */
			
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0126)))
				throw new ConditionFailedException("300A,0126 is required if value of Control Point Index is 0");
			
			/*
			 * 300A,0128
			 * Table Top Vertical position in IEC TABLE TOP coordinate system (mm).
			 * This value is interpreted as an absolute, rather than relative, Table setting.
			 * Required for first item of Control Point Sequence, or if Table Top Vertical Position changes during beam administration.
			 * How to know whether Table Top Vertical Position changes during beam administration.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0128)))
				throw new ConditionFailedException("300A,0128 is required if value of Control Point Index is 0");
			
			/*
			 * 300A,0129
			 * Table Top Longitudinal position in IEC TABLE TOP coordinate system (mm).
			 * This value is interpreted as an absolute, rather than relative, Table setting.
			 * Required for first item of Control Point Sequence,or if Table Top Longitudinal Position changes during beam administration.
			 * How to know whether Table Top Longitudinal Position changes during beam administration.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x0129)))
				throw new ConditionFailedException("300A,0129 is required if value of Control Point Index is 0");
			
			/*
			 * 300A,012A
			 * Table Top Lateral position in IEC TABLE TOP coordinate system (mm).
			 * This value is interpreted as an absolute, rather than relative, Table setting.
			 * Required for first item of Control Point Sequence, or if Table Top Lateral Position changes during beam administration.
			 * How to know whether Table Top Lateral Position changes during beam administration.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x012A)))
				throw new ConditionFailedException("300A,012A is required if value of Control Point Index is 0");
			
			/*
			 * 300A,012C
			 * Isocenter coordinates (x,y,z) in the patient based coordinate system
			 * Required for first item of Control Point Sequence, or if Segment Isocenter Position changes during Beam.
			 * How to know whether Segment Isocenter Position changes during Beam.
			 */
			if(strValueControlPointIndex.equals(strControlPointIndex) && (!contains(0x300A,0x012C)))
				throw new ConditionFailedException("300A,012C is required if value of Control Point Index is 0");
			
		}
		catch( ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),ce); 
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),me);
		}
		return true;
	}

	/**
	 * Sets source to External Contour distance (mm) including devices associatedwith the patient anatomy model.
	 * @param fSourcetoExternalContourDistance Float value of the Ratio of displayed pixels to source pixels
	 */
	public void setSourcetoExternalContourDistance( float fSourcetoExternalContourDistance)
	{
		/*
		 * Accept the SourcetoExternalContourDistance in String format of type FL.
		 * Source to External Contour distance (mm) including devices associatedwith the patient anatomy model.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x300A,0x0132, fSourcetoExternalContourDistance,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0132,DicomConstants.DCM_DT_FL, fSourcetoExternalContourDistance);

		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 getSourcetoExternalContourDistance()
	{
		Object objValue = getValue(0x300A,0x0132);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
}
