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

import cdac.medinfo.sdk.dcm30_04.baselibs.CornealTopographyMapTypeCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.KeratometricMeasurementsMacro;
import cdac.medinfo.sdk.dcm30_04.baselibs.MaximumCornealCurvatureSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.MinimumKeratometricSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.SimulatedKeratometricCylinderSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.SourceImageCornealProcessedDataSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.CornealTopographyMappingNormalsSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.SourceImageSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.Tag;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCornealTopographyMapQualityEvaluation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumOphthalmicMappingDeviceType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCornealTopographySurface;

import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidModuleException;
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;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

/**
\* This module is used for Corneal Topography Map Analysis Module.
*/
public class CornealTopographyMapAnalysisModule extends Module
{
	/**
	 * The obj single collection.
	 */
	public static ISingleCollection<ITag> objSingleCollection = null;


	/**
	 * Instantiates a new Corneal Topography Map Analysis Module
	 * 
	 * @param objIDataSet the obj i data set
	 */
	KeratometricMeasurementsMacro objKeratometricMeasurementsMacro=null;
	public CornealTopographyMapAnalysisModule(IDataSet objIDataSet)
	{
		super(objIDataSet);
	}

	static
	{
		objSingleCollection = new SingleCollection<ITag>();
		objSingleCollection.add(new Tag(0x0046,0x0244));
		objSingleCollection.add(new Tag(0x0008,0x2112));
		objSingleCollection.add(new Tag(0x0046,0x0210));
		objSingleCollection.add(new Tag(0x0046,0x0207));
		objSingleCollection.add(new Tag(0x0046,0x0242));
		
		objSingleCollection.add(new Tag(0x0046,0x0238));
		objSingleCollection.add(new Tag(0x0046,0x0236));
		objSingleCollection.add(new Tag(0x0046,0x0234));
		objSingleCollection.add(new Tag(0x0046,0x0232));
		objSingleCollection.add(new Tag(0x0046,0x0230));
		
		objSingleCollection.add(new Tag(0x0046,0x0211));
		objSingleCollection.add(new Tag(0x0046,0x0227));
		objSingleCollection.add(new Tag(0x0046,0x0224));
		objSingleCollection.add(new Tag(0x0046,0x0220));
		objSingleCollection.add(new Tag(0x0046,0x0218));
		objSingleCollection.add(new Tag(0x0046,0x0215));
		
		objSingleCollection.add(new Tag(0x0046,0x0208));
		objSingleCollection.add(new Tag(0x0046,0x0205));
		objSingleCollection.add(new Tag(0x0046,0x0204));
		objSingleCollection.add(new Tag(0x0046,0x0203));
		objSingleCollection.add(new Tag(0x0046,0x0202));
		objSingleCollection.add(new Tag(0x0046,0x0201));
		objSingleCollection.add(new Tag(0x0022,0x1415));

	}

	/* For normalized IODs, the type(Mandatory/Optional) of a Module depends upon the
	 * Requirement Type which defines if this module is required by a SCP class or an
	 * SCP class. Hence,the validation of Modules in a Normalized IOD totally depends 
	 * upon the decision that the is it an SCU/SCP that needs the module.Also, Type of the Modules
	 * describes the type of the Attributes inside the Module. Ex: Mandatory Modules contain Attributes that are
	 * included in all SOP Instances employing this IOD.
	 * Decision on implementation of this kind of validation is yet to be done. Hence,
	 * i am putting a empty validate method.
	 * @return - returns validation status as success or failure 
	 * @throws InvalidModuleException - If validation of Module fails 	 
	 */
	/* (non-Javadoc)
	 * @see cdac.medinfo.sdk.dcm30_04.dicommodel.modules.Module#validateModule()
	 */
	public boolean validateModule() throws InvalidModuleException
	{
		try
		{
			if(!isPresent(0x0022,0x1415))
				throw new MandatoryMissingException("0022,1415");
			if(!isPresent(0x0046,0x0202))
				throw new MandatoryMissingException("0046,0202");
			if(!isPresent(0x0046,0x0201))
				throw new MandatoryMissingException("0046,0201");
			
			
			String strCornealTopographySurface = getCornealTopographySurface();
			if(strCornealTopographySurface.toString().equals(EnumCornealTopographySurface.A) && (!isPresent(0x0046,0x0203)))
				throw new ConditionFailedException("0046,0203 is if Attribute Corneal Topography Surface (0046,0201) is A(Anterior).");
			
			if(strCornealTopographySurface.toString().equals(EnumCornealTopographySurface.A) && (!isPresent(0x0046,0x0204)))
				throw new ConditionFailedException("0046,0204 is if Attribute Corneal Topography Surface (0046,0201) is A(Anterior).");
			
			if(strCornealTopographySurface.toString().equals(EnumCornealTopographySurface.A) && (!isPresent(0x0046,0x0205)))
				throw new ConditionFailedException("0046,0205 is if Attribute Corneal Topography Surface (0046,0201) is A(Anterior).");
			
			if(strCornealTopographySurface.toString().equals(EnumCornealTopographySurface.A) && (!isPresent(0x0046,0x0208)))
				throw new ConditionFailedException("0046,0208 is if Attribute Corneal Topography Surface (0046,0201) is A(Anterior).");
			
			if(!isPresent(0x0046,0x0215))
				throw new MandatoryMissingException("0046,0215");
			if(!isPresent(0x0046,0x0218))
				throw new MandatoryMissingException("0046,0218");	
			if(!isPresent(0x0046,0x0220))
				throw new MandatoryMissingException("0046,0220");
			if(!isPresent(0x0046,0x0224))
				throw new MandatoryMissingException("0046,0224");
			if(!isPresent(0x0046,0x0227))
				throw new MandatoryMissingException("0046,0227");
			if(!isPresent(0x0046,0x0207))
				throw new MandatoryMissingException("0046,0207");
			if(!isPresent(0x0008,0x2112))
				throw new MandatoryMissingException("0008,2112");
			if(!isPresent(0x0046,0x0244))
				throw new MandatoryMissingException("0046,0244");
		}
		catch(MandatoryMissingException mme)
		{
			if(DicomConfig.createInstance().isLoggingOn())
				DicomLogger.getLogger().log(mme.getMessage());

			
				throw new InvalidModuleException(this.getClass().getSimpleName(),mme);

		}
		return true;
	}
	/**
	 * Sets OphthalmicMappingDeviceType
	 * @param enumOphthalmicMappingDeviceType Enum value ofOphthalmicMappingDeviceType
	 */
	public void setOphthalmicMappingDeviceType(EnumOphthalmicMappingDeviceType enumOphthalmicMappingDeviceType)
	{
		/* Accept OphthalmicMappingDeviceType 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 Hash Map
		 */
		addDataElement(0x0022,0x1415, DicomConstants.DCM_DT_CS, enumOphthalmicMappingDeviceType.getValue());
	}

	/**
	 * Retrieves OphthalmicMappingDeviceType
	 * @return String - String value of OphthalmicMappingDeviceType
	 */
	public String getOphthalmicMappingDeviceType()
	{
		Object objValue = getValue(0x0022,0x1415);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Corneal Topography Surface
	 * @param enumCornealTopographySurface Enum value of Corneal Topography Surface
	 */
	public void setCornealTopographySurface(EnumCornealTopographySurface enumCornealTopographySurface)
	{
		/* Accept Corneal Topography Surface 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 Hash Map
		 */
		addDataElement(0x0046,0x0201, DicomConstants.DCM_DT_CS, enumCornealTopographySurface.getValue());
	}

	/**
	 * Retrieves Corneal Topography Surface
	 * @return String - String value of Corneal Topography Surface
	 */
	public String getCornealTopographySurface()
	{
		Object objValue = getValue(0x0046,0x0201);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Corneal Vertex Location
	 * @param arrFCornealVertexLocation pair of Corneal Vertex Location
	 */
	public void setCornealVertexLocation(float[] arrFCornealVertexLocation)
	{
		/* Accept the Corneal Vertex Location 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
		 */
		addDataElement(0x0046,0x0202,DicomConstants.DCM_DT_FL,arrFCornealVertexLocation);
	}

	/**
	 * Retrieves Corneal Vertex Location
	 * @return float[] - Float array of Corneal Vertex Location
	 */
	public float[] getCornealVertexLocation()
	{
		Object objValue = getValue(0x0046,0x0203);
		if(objValue != null)
			return (float[])objValue;
		return null;
	}

	/**
	 * Sets Pupil CentroidX-Coordinate
	 * @param fPupilCentroidXCoordinate value of Pupil CentroidX-Coordinate
	 */
	public void setPupilCentroidXCoordinate( float fPupilCentroidXCoordinate)
	{
		/*
		 * Accept the Pupil CentroidX-Coordinate in String 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
		 */
		addDataElement(0x0046,0x0203, DicomConstants.DCM_DT_FL,fPupilCentroidXCoordinate);
	}
	/**
	 * Retrieves Pupil CentroidX-Coordinate
	 * @return float - Float value of Pupil CentroidX-Coordinate
	 */
	public float getPupilCentroidXCoordinate()
	{
		Object objValue = getValue(0x0046,0x0203);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets Pupil Centroid Y-Coordinate
	 * @param fPupilCentroidYCoordinate value of Pupil Centroid Y-Coordinate
	 */
	public void setPupilCentroidYCoordinate( float fPupilCentroidYCoordinate)
	{
		/*
		 * Accept the Pupil Centroid Y-Coordinate in String 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
		 */
		addDataElement(0x0046,0x0204, DicomConstants.DCM_DT_FL,fPupilCentroidYCoordinate);
	}
	/**
	 * Retrieves Pupil Centroid Y-Coordinate
	 * @return float - Float value of Pupil Centroid Y-Coordinate
	 */
	public float getPupilCentroidYCoordinate()
	{
		Object objValue = getValue(0x0046,0x0204);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets Equivalent Pupil Radius
	 * @param fEquivalentPupilRadius value of Equivalent Pupil Radius
	 */
	public void setEquivalentPupilRadius( float fEquivalentPupilRadius)
	{
		/*
		 * Accept the Equivalent Pupil Radius in String 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
		 */
		addDataElement(0x0046,0x0205, DicomConstants.DCM_DT_FL,fEquivalentPupilRadius);
	}
	/**
	 * Retrieves Equivalent Pupil Radius
	 * @return float - Float value of Equivalent Pupil Radius
	 */
	public float getEquivalentPupilRadius()
	{
		Object objValue = getValue(0x0046,0x0205);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/* Sets Vertices of the Outline of Pupil
	 * @param strVerticesOfTheOutlineOfPupilString Value Vertices of the Outline of Pupil
	 */
	public void setVerticesOfTheOutlineOfPupil(String strVerticesOfTheOutlineOfPupilString)
	{
		/*Accept the Vertices of the Outline of Pupil 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
		 */
		addDataElement(0x0046,0x0208, DicomConstants.DCM_DT_IS,strVerticesOfTheOutlineOfPupilString);
	}

	/**
	 * Retrieves Vertices of the Outline of Pupil
	 * @return String Array -  Value component of Vertices of the Outline of Pupil
	 */
	public String[] getVerticesOfTheOutlineOfPupil()
	{
		Object objValue = objIDataSet.getValue(0x0046,0x0208);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	
	/**
	 * Get the Instance of Keratometric MeasurementsMacro related to Content Identification  will be set in Macro
	 * using the setter methods provided in the Macro.Calling this method multiple times will return the same Marco
	 * Instance that was created at first. Hence, any attributes in this Macro,if set multiple times will contain the value that was
	 * set in the last call to its setter method.
	 * 
	 * @return - object of Keratometric MeasurementsMacro which the user programmer can populate
	 */
	public KeratometricMeasurementsMacro getKeratometricMeasurementsMacro()
	{
		if(objKeratometricMeasurementsMacro == null)
			objKeratometricMeasurementsMacro = new KeratometricMeasurementsMacro(objIDataSet);
		return objKeratometricMeasurementsMacro; 
	}
	
	/**
	 * Retrieves a sequence which provides references to Minimum Keratometric Sequence
	 * @return - instance of {@link Minimum Keratometric Sequence}
	 */
	public MinimumKeratometricSequence getMinimumKeratometricSequence()
	{
		MinimumKeratometricSequence objMinimumKeratometricSequence = (MinimumKeratometricSequence)getDicomValue(0x0046,0x0215);
		if(objMinimumKeratometricSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objMinimumKeratometricSequence = (MinimumKeratometricSequence)objDicomV3Factory.createSequence(0x0046,0x0218, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0215, DicomConstants.DCM_DT_SQ, objMinimumKeratometricSequence.getValue());
		}
		return objMinimumKeratometricSequence;
	}
	/**
	 * Retrieves a sequence which provides references to Simulated Keratometric CylinderSequence
	 * @return - instance of {@linkSimulated Keratometric CylinderSequence}
	 */
	public SimulatedKeratometricCylinderSequence getSimulatedKeratometricCylinderSequence()
	{
		SimulatedKeratometricCylinderSequence objSimulatedKeratometricCylinderSequence = (SimulatedKeratometricCylinderSequence)getDicomValue(0x0046,0x0211);
		if(objSimulatedKeratometricCylinderSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objSimulatedKeratometricCylinderSequence = (SimulatedKeratometricCylinderSequence)objDicomV3Factory.createSequence(0x0046,0x0218, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0218, DicomConstants.DCM_DT_SQ, objSimulatedKeratometricCylinderSequence.getValue());
		}
		return objSimulatedKeratometricCylinderSequence;
	}	
	/**
	 * Sets area-corrected average of the corneal power ahead of the entrance pupil, measured in diopters.
	 * @param fAverageCornealPower value of the Average Corneal Power
	 */
	public void setAverageCornealPower( float fAverageCornealPower)
	{
		/*
		 * Accept the Average Corneal Power in String 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
		 */
		addDataElement(0x0046,0x0220, DicomConstants.DCM_DT_FL,fAverageCornealPower);
	}
	/**
	 * Retrieves area-corrected average of the corneal power ahead of the entrancepupil, measured in diopters.
	 * @return float - Float value of Average Corneal Power
	 */
	public float getAverageCornealPower()
	{
		Object objValue = getValue(0x0046,0x0220);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}	
	/**
	 * Sets Corneal I-S Value
	 * @param fCornealISValue value of the Corneal I-S Value
	 */
	public void setCornealISValue( float fCornealISValue)
	{
		/*
		 * Accept the Corneal I-S Value in String 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
		 */
		addDataElement(0x0046,0x0224, DicomConstants.DCM_DT_FL,fCornealISValue);
	}
	/**
	 * Retrieves Corneal I-S Value
	 * @return float - Float value of Corneal I-S Value
	 */
	public float getCornealISValue()
	{
		Object objValue = getValue(0x0046,0x0224);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}	
	/**
	 * Sets Analyzed Area
	 * @param fAnalyzedArea Float value of the Analyzed Area
	 */
	public void setAnalyzedArea( float fAnalyzedArea)
	{
		/*
		 * Accept the Analyzed Area in String 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
		 */
		addDataElement(0x0046,0x0227, DicomConstants.DCM_DT_FL,fAnalyzedArea);
	}
	/**
	 * Retrieves Analyzed Area
	 * @return float - Float value of Analyzed Area
	 */
	public float getAnalyzedArea()
	{
		Object objValue = getValue(0x0046,0x0227);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}	
	/**
	 * Retrieves a sequence which provides references to Maximum Corneal CurvatureSequence
	 * @return - instance of {@link Maximum Corneal CurvatureSequence}
	 */
	public MaximumCornealCurvatureSequence getMaximumCornealCurvatureSequence()
	{
		MaximumCornealCurvatureSequence objMaximumCornealCurvatureSequence = (MaximumCornealCurvatureSequence)getDicomValue(0x0046,0x0211);
		if(objMaximumCornealCurvatureSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objMaximumCornealCurvatureSequence = (MaximumCornealCurvatureSequence)objDicomV3Factory.createSequence(0x0046,0x0211, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0211, DicomConstants.DCM_DT_SQ, objMaximumCornealCurvatureSequence.getValue());
		}
		return objMaximumCornealCurvatureSequence;
	}
	/**
	 * Sets Surface Regularity Index
	 * @param fSurfaceRegularityIndex Float value of the Surface Regularity Index
	 */
	public void setSurfaceRegularityIndex( float fSurfaceRegularityIndex)
	{
		/*
		 * Accept the Surface Regularity Index in String 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
		 */
		addDataElement(0x0046,0x0230, DicomConstants.DCM_DT_FL,fSurfaceRegularityIndex);
	}
	/**
	 * Retrieves Surface Regularity Index
	 * @return float - Float value of Surface Regularity Index
	 */
	public float getSurfaceRegularityIndex()
	{
		Object objValue = getValue(0x0046,0x0230);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}	
	/**
	 * Sets Surface Asymmetry Index
	 * @param fSurfaceAsymmetryIndex Float value of the Surface Asymmetry Index
	 */
	public void setSurfaceAsymmetryIndex( float fSurfaceAsymmetryIndex)
	{
		/*
		 * Accept the Surface Asymmetry Index in String 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
		 */
		addDataElement(0x0046,0x0232, DicomConstants.DCM_DT_FL,fSurfaceAsymmetryIndex);
	}
	/**
	 * Retrieves Surface Asymmetry Index
	 * @return float - Float value of Surface Asymmetry Index
	 */
	public float getSurfaceAsymmetryIndex()
	{
		Object objValue = getValue(0x0046,0x0232);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets Corneal Eccentricity Index
	 * @param fCornealEccentricityIndex Float value of the Corneal Eccentricity Index
	 */
	public void setCornealEccentricityIndex( float fCornealEccentricityIndex)
	{
		/*
		 * Accept the Corneal Eccentricity Index in String 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
		 */
		addDataElement(0x0046,0x0234, DicomConstants.DCM_DT_FL,fCornealEccentricityIndex);
	}
	/**
	 * Retrieves Corneal Eccentricity Index
	 * @return float - Float value of Corneal Eccentricity Index
	 */
	public float getCornealEccentricityIndex()
	{
		Object objValue = getValue(0x0046,0x0234);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}	
	/**
	 * Sets Keratoconus Prediction Index
	 * @param fKeratoconusPredictionIndex Float value of the Keratoconus Prediction Index
	 */
	public void setKeratoconusPredictionIndex( float fKeratoconusPredictionIndex)
	{
		/*
		 * Accept the Keratoconus Prediction Index in String 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
		 */
		addDataElement(0x0046,0x0236, DicomConstants.DCM_DT_FL,fKeratoconusPredictionIndex);
	}
	/**
	 * Retrieves Keratoconus Prediction Index
	 * @return float - Float value of the Keratoconus Prediction Index
	 */
	public float getKeratoconusPredictionIndex()
	{
		Object objValue = getValue(0x0046,0x0236);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets the range of best spectacle-corrected distance that might be expected from a functionally normal eye with the topographical characteristics of theanalyzed cornea, measured in decimal.
	 * @param fDecimalPotentialVisualAcuity Float value of the DecimalPotentialVisualAcuity
	 */
	public void setDecimalPotentialVisualAcuity( float fDecimalPotentialVisualAcuity)
	{
		/*
		 * Accept the DecimalPotentialVisualAcuity in String 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
		 */
		addDataElement(0x0046,0x0238, DicomConstants.DCM_DT_FL,fDecimalPotentialVisualAcuity);
	}
	/**
	 * Retrieves the range of best spectacle-corrected distance that might be expected from a functionally normal eye with the topographical characteristics of theanalyzed cornea, measured in decimal.
	 * @return float - Float value of the DecimalPotentialVisualAcuity
	 */
	public float getDecimalPotentialVisualAcuity()
	{
		Object objValue = getValue(0x0046,0x0238);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets the the quality of the topography examination.
	 * @param enumCornealTopographyMapQualityEvaluation Enum value of Corneal Topography MapQuality Evaluation
	 */
	public void setCornealTopographyMapQualityEvaluation(EnumCornealTopographyMapQualityEvaluation enumCornealTopographyMapQualityEvaluation)
	{
		/* Accept Corneal Topography MapQuality Evaluation 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 Hash Map
		 */
		addDataElement(0x0046,0x0242, DicomConstants.DCM_DT_CS, enumCornealTopographyMapQualityEvaluation.getValue());
	}

	/**
	 * Retrieves the quality of the topography examination.
	 * @return String - String value of Corneal Topography MapQuality Evaluation
	 */
	public String getCornealTopographyMapQualityEvaluation()
	{
		Object objValue = getValue(0x0046,0x0242);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Retrieves a sequence which provides references to Corneal Topography Map TypeCode Sequence
	 * @return - instance of {@link CornealTopographyMapTypeCodeSequence}
	 */
	public CornealTopographyMapTypeCodeSequence getCornealTopographyMapTypeCodeSequence()
	{
		CornealTopographyMapTypeCodeSequence objCornealTopographyMapTypeCodeSequence= (CornealTopographyMapTypeCodeSequence)getDicomValue(0x0046,0x0207);
		if(objCornealTopographyMapTypeCodeSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objCornealTopographyMapTypeCodeSequence = (CornealTopographyMapTypeCodeSequence)objDicomV3Factory.createSequence(0x0046,0x0207, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0207, DicomConstants.DCM_DT_SQ, objCornealTopographyMapTypeCodeSequence.getValue());
		}
		return objCornealTopographyMapTypeCodeSequence;
	}
	/**
	 * Retrieves a sequence which provides references to Corneal Topography MappingNormals Sequence
	 * @return - instance of {@link Corneal Topography MappingNormals Sequence}
	 */
	public CornealTopographyMappingNormalsSequence getCornealTopographyMappingNormalsSequence()
	{
		CornealTopographyMappingNormalsSequence objCornealTopographyMappingNormalsSequence = (CornealTopographyMappingNormalsSequence)getDicomValue(0x0046,0x0210);
		if(objCornealTopographyMappingNormalsSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objCornealTopographyMappingNormalsSequence = (CornealTopographyMappingNormalsSequence)objDicomV3Factory.createSequence(0x0046,0x0210, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0210, DicomConstants.DCM_DT_SQ, objCornealTopographyMappingNormalsSequence.getValue());
		}
		return objCornealTopographyMappingNormalsSequence;
	}
	/**
	 * Retrieves a sequence which provides references to Source Image Sequence
	 * @return - instance of {@link Source Image Sequence}
	 */
	public SourceImageSequence getSourceImageSequence()
	{
		SourceImageSequence objSourceImageSequence = (SourceImageSequence)getDicomValue(0x0008,0x2112);
		if(objSourceImageSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objSourceImageSequence = (SourceImageSequence)objDicomV3Factory.createSequence(0x0008,0x2112, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0008,0x2112, DicomConstants.DCM_DT_SQ, objSourceImageSequence.getValue());
		}
		return objSourceImageSequence;
	}	
	/**
	 * Retrieves a sequence which provides references to Source Image Corneal ProcessedData Sequence
	 * @return - instance of {@link Source Image Corneal ProcessedData Sequence}
	 */
	public SourceImageCornealProcessedDataSequence getSourceImageCornealProcessedDataSequence()
	{
		SourceImageCornealProcessedDataSequence objSourceImageCornealProcessedDataSequence = (SourceImageCornealProcessedDataSequence)getDicomValue(0x0046,0x0244);
		if(objSourceImageCornealProcessedDataSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objSourceImageCornealProcessedDataSequence = (SourceImageCornealProcessedDataSequence)objDicomV3Factory.createSequence(0x0046,0x0244, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0046,0x0244, DicomConstants.DCM_DT_SQ, objSourceImageCornealProcessedDataSequence.getValue());
		}
		return objSourceImageCornealProcessedDataSequence;
	}
	/**
	 * This method returns the vector of keys representing the DataElements
	 * that belong to this module.
	 * 
	 * @return vector of Tags - returns the vector containing the collection of tags
	 */
	public ISingleCollection<ITag> getVectorOfKeys()
	{
		return objSingleCollection;
	}
}
