/*******************************************************************************
 *  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.EnumAnodeTargetMaterial;
import cdac.medinfo.sdk.dcm30_04.enums.EnumExposureControlMode;
import cdac.medinfo.sdk.dcm30_04.enums.EnumFieldOfViewShape;
import cdac.medinfo.sdk.dcm30_04.enums.EnumXRayReceptorType;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.exceptions.MandatoryMissingException;
import cdac.medinfo.sdk.dcm30_04.exceptions.ValidationException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;
import cdac.medinfo.sdk.dcm30_04.utils.EnumFeatureList;

/**
 * This class provides a sequence of items containing the attributes of X Ray 3D Acquisition Sequence {@link XRay3DAcquisitionSequence}
 *
 */

public class XRay3DAcquisitionSequenceItem extends Item 
{
	


	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	XRay3DGeneralSharedAcquisitionMacro objXRay3DGeneralSharedAcquisitionMacro= null;
	XRay3DGeneralPositionerMovementMacro objXRay3DGeneralPositionerMovementMacro = null;
	DigitalXRayDetectorMacro objDigitalXRayDetectorMacro=null;

	/**
	 * This constructor creates the item with default TransferSyntax 
	 */
	XRay3DAcquisitionSequenceItem()
	{
		super();
	}

	/*
	 * This constructor calls the respective superclass constructor
	 * This constructor should throw exception if null TS is tried to be set
	 */
	/**
	 * This constructor creates the item with specified TransferSyntax 
	 * and default DictionaryReader
	 * @param objITransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 */
	XRay3DAcquisitionSequenceItem(ITransferSyntax objITransferSyntax)
	{
		super(objITransferSyntax);
	}

	/**
	 * This constructor creates XRay3DAcquisitionSequenceItem with specified TransferSyntax and
	 * specified DictionaryReader.
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax.
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used.
	 */
	XRay3DAcquisitionSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}
	/**
	 * This method returns the XRay3DGeneralSharedAcquisitionMacro with proper initialization.
	 * @return - instance of {@link XRay3DGeneralSharedAcquisitionMacro} 
	 */
	public XRay3DGeneralSharedAcquisitionMacro getXRay3DGeneralSharedAcquisitionMacro()
	{
		if(objXRay3DGeneralSharedAcquisitionMacro == null)
		{
			objXRay3DGeneralSharedAcquisitionMacro = new XRay3DGeneralSharedAcquisitionMacro(this);
			return objXRay3DGeneralSharedAcquisitionMacro;
		}
		return objXRay3DGeneralSharedAcquisitionMacro;
	}
	/**
	 * This method returns the XRay3DGeneralPositionerMovementMacro with proper initialization.
	 * @return - instance of {@link XRay3DGeneralPositionerMovementMacro} 
	 */
	public XRay3DGeneralPositionerMovementMacro getXRay3DGeneralPositionerMovementMacro()
	{
		if(objXRay3DGeneralPositionerMovementMacro == null)
		{
			objXRay3DGeneralPositionerMovementMacro = new XRay3DGeneralPositionerMovementMacro(this);		
			return objXRay3DGeneralPositionerMovementMacro;
		}
		return objXRay3DGeneralPositionerMovementMacro;
	}
	/**
	 * This method returns the DigitalXRayDetectorMacro with proper initialization.
	 * @return - instance of {@link DigitalXRayDetectorMacro} 
	 */
	public DigitalXRayDetectorMacro getDigitalXRayDetectorMacro()
	{
		if(objDigitalXRayDetectorMacro == null)
		{
			objDigitalXRayDetectorMacro = new DigitalXRayDetectorMacro(this);		
			return objDigitalXRayDetectorMacro;
		}
		return objDigitalXRayDetectorMacro;
	}
	/**
	 * Sets Shape of the Field of View in the source projection images.
	 * @param enumFieldOfViewShape enum value of Field of View Shape
	 */
	public void setFieldOfViewShape(EnumFieldOfViewShape enumFieldOfViewShape)
	{
		/* Accept the Field of View Shape 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(0x0018,0x1147, enumFieldOfViewShape.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1147,DicomConstants.DCM_DT_CS, enumFieldOfViewShape.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Shape of the Field of View in the source projection images.
	 * @return String - value of Field of View Shape
	 */
	public String getFieldOfViewShape()
	{
		Object objValue = getValue(0x0018,0x1147);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets X-Ray Receptor Type
	 * @param enumXRayReceptorType enum value of X-Ray Receptor Type
	 */
	public void setXRayReceptorType(EnumXRayReceptorType enumXRayReceptorType)
	{
		/* Accept the X-Ray Receptor Type 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(0x0018,0x9420, enumXRayReceptorType.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x9420,DicomConstants.DCM_DT_CS, enumXRayReceptorType.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return X-Ray Receptor Type
	 * @return String - value of X-Ray Receptor Type
	 */
	public String getXRayReceptorType()
	{
		Object objValue = getValue(0x0018,0x9420);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Distance in mm from transmission source to the detector face. Required if Image
	 * Type (0008,0008) Value 4 is TRANSMISSION, Value 3 is not TOMO,
	 * and a sequence Item is present.
	 * @param strDistanceSourceToDetector String value of Distance Source to Detector.
	 */
	public void setDistanceSourceToDetector(String strDistanceSourceToDetector)
	{
		/*Accept the Distance Source to Detector 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,0x1110, strDistanceSourceToDetector,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1110,DicomConstants.DCM_DT_DS, strDistanceSourceToDetector);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Distance in mm from transmission source to the detector face
	 * @return String - value of Distance Source to Detector.
	 */
	public String getDistanceSourceToDetector()
	{
		Object objValue = getValue(0x0018,0x1110);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/*
	 * Sets Distance Source to Patient
	 * @param strDistanceSourceToPatient String value of Distance Source to Patient
	 */
	public void setDistanceSourceToPatient(String strDistanceSourceToPatient)
	{
		/*Accept the DistanceSourceToPatient 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,0x1111, strDistanceSourceToPatient,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1111,DicomConstants.DCM_DT_DS, strDistanceSourceToPatient);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Distance Source to Patient
	 * @return String - value of Distance Source to Patient
	 */
	public String getDistanceSourceToPatient()
	{
		Object objValue = getValue(0x0018,0x1111);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/*
	 * Sets Estimated RadiographicMagnification Factor
	 * @param strEstimatedRadiographicMagnificationFactor String value of Estimated RadiographicMagnification Factor
	 */
	public void setEstimatedRadiographicMagnificationFactor(String strEstimatedRadiographicMagnificationFactor)
	{
		/*Accept the EstimatedRadiographicMagnificationFactor 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,0x1114, strEstimatedRadiographicMagnificationFactor,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1114,DicomConstants.DCM_DT_DS, strEstimatedRadiographicMagnificationFactor);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Estimated RadiographicMagnification Factor
	 * @return String - value of Estimated RadiographicMagnification Factor
	 */
	public String getEstimatedRadiographicMagnificationFactor()
	{
		Object objValue = getValue(0x0018,0x1114);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Anode Target Material
	 * @param enumAnodeTargetMaterial enum value of Anode Target Material
	 */
	public void setAnodeTargetMaterial(EnumAnodeTargetMaterial enumAnodeTargetMaterial)
	{
		/* Accept the Anode Target Material 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(0x0018,0x1191, enumAnodeTargetMaterial.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1191,DicomConstants.DCM_DT_CS, enumAnodeTargetMaterial.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Anode Target Material
	 * @return String - value of Anode Target Material
	 */
	public String getAnodeTargetMaterial()
	{
		Object objValue = getValue(0x0018,0x1191);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/*
	 * Sets Body Part Thickness
	 * @param strBodyPartThickness String value of Body Part Thickness
	 */
	public void setBodyPartThickness(String strBodyPartThickness)
	{
		/*Accept the BodyPartThickness 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,0x11A0, strBodyPartThickness,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x11A0,DicomConstants.DCM_DT_DS, strBodyPartThickness);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Body Part Thickness
	 * @return String - value of Body Part Thickness
	 */
	public String getBodyPartThickness()
	{
		Object objValue = getValue(0x0018,0x11A0);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Exposure Control Mode
	 * @param enumExposureControlMode enum value of Exposure Control Mode
	 */
	public void setExposureControlMode(EnumExposureControlMode enumExposureControlMode)
	{
		/* Accept the Exposure Control Mode 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(0x0018,0x7060, enumExposureControlMode.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7060,DicomConstants.DCM_DT_CS, enumExposureControlMode.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Exposure Control Mode
	 * @return String - value of Exposure Control Mode
	 */
	public String getExposureControlMode()
	{
		Object objValue = getValue(0x0018,0x7060);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Exposure Control Mode Description
	 * @param strExposureControlModeDescription String value of Exposure Control Mode Description
	 */
	public void setExposureControlModeDescription(String strExposureControlModeDescription)
	{
		/* Accept Exposure Control Mode Description of type LT.
		 * 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,0x7062, strExposureControlModeDescription,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7062,DicomConstants.DCM_DT_LT, strExposureControlModeDescription);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Exposure Control Mode Description
	 * @return String - value of  Exposure Control Mode Description
	 */
	public String getExposureControlModeDescription()
	{
		Object objValue = getValue(0x0018,0x7062);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Half Value Layer.Uniquely identifies Half Value Layer
	 * The thickness of Aluminum in mm required to reduce the X-Ray Output(0040,0312) by a factor of two.
	 * @param strHalfValueLayer String value of Half Value Layer.
	 */
	public void setHalfValueLayer(String strHalfValueLayer)
	{
		/* Accept the HalfValueLayer in String format of type DS.
		 * The thickness of Aluminum in mm required to reduce the X-Ray Output(0040,0312) by a factor of two.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0040,0x0314, strHalfValueLayer,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0040,0x0314,DicomConstants.DCM_DT_DS, strHalfValueLayer);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Half Value Layer
	 * The thickness of Aluminum in mm required to reduce the X-Ray Output(0040,0312) by a factor of two.
	 * @return String - value of Half Value Layer.
	 */
	public String getHalfValueLayer()
	{
		Object objValue = getValue(0x0040,0x0314);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Half Value Layer.Uniquely identifies Half Value Layer
	 * Average organ dose value measured in dGy during the acquisition of thisimage.
	 * @param strHalfValueLayer String value of Half Value Layer.
	 */
	public void setOrganDose(String strOrganDose)
	{
		/* Accept the HalfValueLayer in String format of type DS.
		 * Average organ dose value measured in dGy during the acquisition of thisimage.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0040,0x0316, strOrganDose,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0040,0x0316,DicomConstants.DCM_DT_DS, strOrganDose);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Organ Dose
	 * Average organ dose value measured in dGy during the acquisition of thisimage.
	 * @return String - value of OrganDose.
	 */
	public String getOrganDose()
	{
		Object objValue = getValue(0x0040,0x0316);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Entrance Dose in mGy.
	 * Average entrance dose value measured in mGy at the surface of the patientduring the acquisition of this image.
	 * @param strEntranceDoseinmGy String value of EntranceDoseinmGy.
	 */
	public void setEntranceDoseinmGy(String strEntranceDoseinmGy)
	{
		/* Accept the EntranceDoseinmGy in String format of type DS.
		 * Average entrance dose value measured in mGy at the surface of the patientduring the acquisition of this image.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0040,0x8302, strEntranceDoseinmGy,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0040,0x8302,DicomConstants.DCM_DT_DS, strEntranceDoseinmGy);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves EntranceDoseinmGy.
	 * Average entrance dose value measured in mGy at the surface of the patientduring the acquisition of this image.
	 * @return String - value of Entrance Dose inmGy.
	 */
	public String getEntranceDoseinmGy()
	{
		Object objValue = getValue(0x0040,0x8302);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets the used nominal size of the focal spot in mm.
	 *  @param strFocalSpots String value of Focal Spot(s).
	 */
	public void setFocalSpots(String[] strFocalSpots)
	{
		/*Accept the FocalSpots 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,0x1190, strFocalSpots,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1190,DicomConstants.DCM_DT_DS, strFocalSpots);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Focal Spot(s).
	 * @return String - value of Focal Spot(s).
	 */
	public String[] getFocalSpots()
	{
		Object objValue = getValue(0x0018,0x1190);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	/**
	 * Sets Detector Binning
	 * @param strDetectorBinning String value of Detector Binning.
	 */
	public void setDetectorBinning(String[] strDetectorBinning)
	{
		/*Accept the Detector Binning 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,0x701A, strDetectorBinning,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x701A,DicomConstants.DCM_DT_DS, strDetectorBinning);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Detector Binning
	 * @return String - value of Detector Binning
	 */
	public String[] getDetectorBinning()
	{
		Object objValue = getValue(0x0018,0x701A);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	/**
	 * Sets Detector Temperature
	 * @param strDetectorTemperature String value of Detector Temperature
	 */
	public void setDetectorTemperature(String strDetectorTemperature)
	{
		/*Accept the Detector Temperature 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,0x7001, strDetectorTemperature,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7001,DicomConstants.DCM_DT_DS, strDetectorTemperature);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Detector Temperature
	 * @return String - value of Detector Temperature
	 */
	public String getDetectorTemperature()
	{
		Object objValue = getValue(0x0018,0x7001);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets the type of filter(s) inserted into the X-Ray beam..
	 * @param FilterType
	 */
	public void setFilterType(String strFilterType)
	{
		/*Accept the FilterType in String format of type SH.
		 * 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, 0x1160, strFilterType,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018, 0x1160,DicomConstants.DCM_DT_SH, strFilterType);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves type of filter(s) inserted into the X-Ray beam..
	 * @return String - value of type of filter(s) inserted into the X-Ray beam..
	 */
	public String getFilterType()
	{
		Object objValue = getValue(0x0018, 0x1160);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets the X-Ray absorbing material used in the filter.
	 * @param strFilterMaterial String Value component of a Name/Value pair when the Concept implied by Concept Name
	 */
	public void setFilterMaterial(String strFilterMaterial)
	{
		/*Accept the Filter Material 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(0x0018, 0x7050, strFilterMaterial,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018, 0x7050,DicomConstants.DCM_DT_CS, strFilterMaterial);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves  the X-Ray absorbing material used in the filter.
	 * @return String Array -  Value component of the X-Ray absorbing material used in the filter.
	 */
	public String[] getFilterMaterial()
	{
		if(getDataForTag(0x0040, 0xA30A)!=null)
		{
			if(getDataForTag(0x0040, 0xA30A).getValue()!=null)
			{
				Object objValue = getDataForTag(0x0018, 0x7050).getValue();
				if(objValue!=null)
				{
					if(objValue instanceof String)
					{
						String strTemp = (String)objValue;
						String[] strArr = new String[1];
						strArr[0] = strTemp;
						return strArr;
					}
					else
						return (String[])objValue;
				}
			}
		}
		return null;
	}
	/**
	 * Sets Filter Thickness Minimum
	 * @param strFilterThicknessMinimum String value of Filter Thickness Minimum
	 */
	public void setFilterThicknessMinimum(String[] strFilterThicknessMinimum)
	{
		/*Accept the Filter Thickness Minimum 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,0x7052, strFilterThicknessMinimum,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7052,DicomConstants.DCM_DT_DS, strFilterThicknessMinimum);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Filter Thickness Minimum
	 * @return String - value of Filter Thickness Minimum
	 */
	public String[] getFilterThicknessMinimum()
	{
		Object objValue = getValue(0x0018,0x7052);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	
	/**
	 * Sets Filter Thickness Maximum
	 * @param strFilterThicknessMaximum String value of Filter Thickness Maximum
	 */
	public void setFilterThicknessMaximum(String[] strFilterThicknessMaximum)
	{
		/*Accept the Filter Thickness Maximum 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,0x7054, strFilterThicknessMaximum,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7054,DicomConstants.DCM_DT_DS, strFilterThicknessMaximum);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Filter Thickness Maximum
	 * @return String - value of Filter Thickness Maximum
	 */
	public String[] getFilterThicknessMaximum()
	{
		Object objValue = getValue(0x0018,0x7054);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	/**
	 * Sets Filter Beam Path Length Minimum
	 * @param arrFFilterBeamPathLengthMinimum pair of Filter Beam Path Length Minimum
	 */
	public void setFilterBeamPathLengthMinimum(float[] arrFFilterBeamPathLengthMinimum)
	{
		/* Accept the Filter Beam Path Length Minimum in short format of type FL.
		 * 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,0x7056, arrFFilterBeamPathLengthMinimum,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7056,DicomConstants.DCM_DT_FL, arrFFilterBeamPathLengthMinimum);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Filter Beam Path Length Minimum
	 * @return float[] - Float array of Filter Beam Path Length Minimum
	 */
	public float[] getFilterBeamPathLengthMinimum()
	{
		Object objValue = getValue(0x0018,0x7056);
		if(objValue != null)
			return (float[])objValue;
		return null;
	}
	/**
	 * Sets Filter Beam Path Length Maximum
	 * @param arrFFilterBeamPathLengthMaximum pair of Filter Beam Path Length Maximum
	 */
	public void setFilterBeamPathLengthMaximum(float[] arrFFilterBeamPathLengthMaximum)
	{
		/* Accept the Filter Beam Path Length Maximum in short format of type FL.
		 * 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,0x7058, arrFFilterBeamPathLengthMaximum,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x7058,DicomConstants.DCM_DT_FL, arrFFilterBeamPathLengthMaximum);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Filter Beam Path Length Maximum
	 * @return float[] - Float array of Filter Beam Path Length Maximum
	 */
	public float[] getFilterBeamPathLengthMaximum()
	{
		Object objValue = getValue(0x0018,0x7058);
		if(objValue != null)
			return (float[])objValue;
		return null;
	}
	/**
	 * Sets Compression Force
	 * @param strCompressionForce String value of Compression Force
	 */
	public void setCompressionForce(String strCompressionForce)
	{
		/*Accept the Compression Force 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,0x11A2, strCompressionForce,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x11A2,DicomConstants.DCM_DT_DS, strCompressionForce);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Compression Force
	 * @return String - value of Compression Force
	 */
	public String getCompressionForce()
	{
		Object objValue = getValue(0x0018,0x11A2);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Paddle Description.
	 * @param strPaddleDescription String value of Paddle Description.
	 */
	public void setPaddleDescription(String strPaddleDescription)
	{
		/* Accept the Paddle Description in String format of type LO.
		 * 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,0x11A4, strPaddleDescription,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x11A4,DicomConstants.DCM_DT_LO, strPaddleDescription);

		addDataElement(objIDataElement);
	}
	/**
	 * Return Paddle Description
	 * @return String - value of Paddle Description
	 */
	public String getPaddleDescription()
	{
		Object objValue = getValue(0x0018,0x11A4);
		if(objValue != null)
			return objValue.toString();
		return null;
	}	
	/**
	 * Retrieves pre-initialized object of Per Projection AcquisitionSequence.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 PerProjectionAcquisitionSequence - instance of Per Projection AcquisitionSequence. 
	 */
	public PerProjectionAcquisitionSequence getPerProjectionAcquisitionSequence()
	{
		PerProjectionAcquisitionSequence objPerProjectionAcquisitionSequence= null;
		IDataElement objIDataElement =  getDataForTag(0x0018, 0x9538); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objPerProjectionAcquisitionSequence = (PerProjectionAcquisitionSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objPerProjectionAcquisitionSequence = (PerProjectionAcquisitionSequence)objDicomV3Factory.createSequence(0x0018, 0x9538, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0018, 0x9538, objPerProjectionAcquisitionSequence.getValue(), objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0018, 0x9538, DicomConstants.DCM_DT_SQ, objPerProjectionAcquisitionSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objPerProjectionAcquisitionSequence;
	}
	/*
	 * (non-Javadoc) This method validates the contents of the Item
	 * @see cdac.medinfo.sdk.dcm30_04.commoninterface.IItem#validate()
	 */
	/**
	 * Validates all the attributes in WideFieldOphthalmicPhotographyQualityRatingSequenceItem 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
		{
			if(!contains(0x0018,0x9507))
				throw new MandatoryMissingException("0018,9507");
			if(!contains(0x0018,0x1147))
				throw new MandatoryMissingException("0018,1147");			
			if(!contains(0x0018,0x9420))
				throw new MandatoryMissingException("0018,9420");			
			if(!contains(0x0018,0x1110))
				throw new MandatoryMissingException("0018,1110");			
			if(!contains(0x0018,0x1111))
				throw new MandatoryMissingException("0018,1111");		
			if(!contains(0x0018,0x1114))
				throw new MandatoryMissingException("0018,1114");			
			if(!contains(0x0018,0x1191))
				throw new MandatoryMissingException("0018,1191");
			if(!contains(0x0018,0x11A0))
				throw new MandatoryMissingException("0018,11A0");
			if(!contains(0x0018,0x7060))
				throw new MandatoryMissingException("0018,7060");
			if(!contains(0x0018,0x7062))
				throw new MandatoryMissingException("0018,7062");
			if(!contains(0x0018,0x0314))
				throw new MandatoryMissingException("0040,0314");
			if(!contains(0x0018,0x1190))
				throw new MandatoryMissingException("0018,1190");			
			if(!contains(0x0018,0x7001))
				throw new MandatoryMissingException("0018,7001");
			if(!contains(0x0018,0x1160))
				throw new MandatoryMissingException("0018,1160");
			if(!contains(0x0018,0x7050))
				throw new MandatoryMissingException("0018,7050");
			if(!contains(0x0018,0x11A2))
				throw new MandatoryMissingException("0018,11A2");
			if(!contains(0x0018,0x11A4))
				throw new MandatoryMissingException("0018,11A4");
			if(!contains(0x0018,0x9538))
				throw new MandatoryMissingException("0018,9538");
		}
		catch(MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new ValidationException(this.getClass().getSimpleName(),me);
		}
		return true;
	}
}
