/*******************************************************************************
 *  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.Tag;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomValue;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.enums.EnumBitsAllocated;
import cdac.medinfo.sdk.dcm30_04.enums.EnumBitsStored;
import cdac.medinfo.sdk.dcm30_04.enums.EnumBurnedInAnnotation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumHighBit;
import cdac.medinfo.sdk.dcm30_04.enums.EnumLossyImageCompression;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPhotometricInterpretation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPixelRepresentation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPresentationLUTShape;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRecognizableVisualFeatures;

import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
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 specifies the attributes that describe an Ophthalmic Tomography Image Module.
 */
public class OphthalmicTomographyImageModule extends Module  
{

	 
	 /**
	  * The obj single collection.
	  */
	 public static ISingleCollection<ITag> objSingleCollection = null;
	 
		/**
		 * Creates Ophthalmic Tomography Image Module.
		 * 
		 * @param objIDataSet the obj i data set
		 */
		public OphthalmicTomographyImageModule(IDataSet objIDataSet)
		{
			super(objIDataSet);
		}

		static
		{

			objSingleCollection = new SingleCollection<ITag>();
			objSingleCollection.add(new Tag(0x0008,0x0008));
			objSingleCollection.add(new Tag(0x0028,0x0002));
			objSingleCollection.add(new Tag(0x0008,0x002A));
			objSingleCollection.add(new Tag(0x00018,0x9073));
			objSingleCollection.add(new Tag(0x0020,0x0012));
			objSingleCollection.add(new Tag(0x0028,0x0004));
			objSingleCollection.add(new Tag(0x0028,0x0103));
			objSingleCollection.add(new Tag(0x0028,0x0100));
			objSingleCollection.add(new Tag(0x0028,0x0101));
			objSingleCollection.add(new Tag(0x0028,0x0102));
			objSingleCollection.add(new Tag(0x2050,0x0020));
			objSingleCollection.add(new Tag(0x0028,0x2110));
			objSingleCollection.add(new Tag(0x0028,0x2112));
			objSingleCollection.add(new Tag(0x0028,0x2114));
			objSingleCollection.add(new Tag(0x0028,0x0301));
			objSingleCollection.add(new Tag(0x0028,0x0302));
			objSingleCollection.add(new Tag(0x0020,0x9228));
			objSingleCollection.add(new Tag(0x0020,0x9162));
			objSingleCollection.add(new Tag(0x0020,0x9163));
			objSingleCollection.add(new Tag(0x0020,0x4000));
		}
		/**
		 * This method validates each Attribute in the Module according to the Type
		 * of the Attribute.Attributes are of 5 types.
		 * Type 1,Type 2 are Mandatory:
		 * Mandatory Attributes have to present in the Module.
		 * Type 1C,2C are Conditional:
		 * Conditional Attributes' presence depend on a condition.
		 * If the condition is satisfied the Attribute has to be present.
		 * Type 3 are Optional
		 * Optional Attributes can be added as and when required.
		 * 
		 * @return boolean - returns validation status as success or failure
		 * 
		 * @throws InvalidModuleException - If validation of Module fails
		 */
		public  boolean validateModule() throws InvalidModuleException
		{

			try
			{		
			
				if(!isPresent(0x0008,0x0008))
					throw new MandatoryMissingException("0008,0008");
				if(!isPresent(0x0028,0x0002))
					throw new MandatoryMissingException("0028,0002");
				if(!isPresent(0x0008,0x002A))
					throw new MandatoryMissingException("0008,002A");
				if(!isPresent(0x00018,0x9073))
					throw new ConditionFailedException("00018,9073");
				if(!isPresent(0x0020,0x0012))
					throw new MandatoryMissingException("0020,0012");
				if(!isPresent(0x0028,0x0004))
					throw new MandatoryMissingException("0028,0004");
				if(!isPresent(0x0028,0x0103))
					throw new MandatoryMissingException("0028,0103");
				if(!isPresent(0x0028,0x0100))
					throw new MandatoryMissingException("0028,0100");
				if(!isPresent(0x0028,0x0101))
					throw new MandatoryMissingException("0028,0101");
				if(!isPresent(0x0028,0x0102))
					throw new MandatoryMissingException("0028,0102");
				if(!isPresent(0x2050,0x0020))
					throw new MandatoryMissingException("2050,0020");
				if(!isPresent(0x0028,0x2110))
					throw new MandatoryMissingException("0028,2110");
				if(!isPresent(0x0028,0x2112))
					throw new ConditionFailedException("0028,2112");
				if(!isPresent(0x0028,0x2114))
					throw new ConditionFailedException("0028,2114");
				if(!isPresent(0x0028,0x0301))
					throw new MandatoryMissingException("0028,0301");
				if(!isPresent(0x0020,0x9228))
					throw new MandatoryMissingException("0020,9228");
				if(!isPresent(0x0020,0x9162))
					throw new MandatoryMissingException("0020,9162");
				if(!isPresent(0x0020,0x9163))
					throw new MandatoryMissingException("0020,9163");
			}catch(MandatoryMissingException mme)
			{
				if(DicomConfig.createInstance().isLoggingOn())
					DicomLogger.getLogger().log(mme.getMessage());

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

			}
			catch(ConditionFailedException cfe)
			{
				if(DicomConfig.createInstance().isLoggingOn())
					DicomLogger.getLogger().log(cfe.getMessage());

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

			}
			catch(InvalidItemException iie)
			{
				if(DicomConfig.createInstance().isLoggingOn())
					DicomLogger.getLogger().log(iie.getMessage());

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

			}
			return true;
		}
		/**
		 * Sets Image identification characteristics.
		 * 
		 * @param arrStrImageType - String array of Image identification characteristics.
		 */	
		public void setImageType(String[] arrStrImageType)
		{
			/*Accept Image identification characteristics in String Array format of type CS.
			 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Hash Map
			 */
			addDataElement(0x0008, 0x0008, DicomConstants.DCM_DT_CS, arrStrImageType);
		}

		/**
		 * Return Image Type.
		 * 
		 * @return String[]- String array of Image identification characteristics.
		 */
		public String[] getImageType()
		{
			if (objIDataSet == null)
				return null;
			IDataElement objIDataElement =  objIDataSet.getDataForTag(0x0008, 0x0008);
			if(objIDataElement == null)
				return null;
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue == null)
				return null;
			if(objIDicomValue.getValue()==null)
				return null;
			return (String[])objIDicomValue.getValue();
		}
		/**
		 * Method is used to set Number of samples (planes) in this image
		 * The function accepts a String Value and creates the
		 * DE based on the transfer syntax and populates the DE with right values.
		 * This De is then added to the Module HashMap
		 * 
		 * @param sSamplesPerPixel the s samples per pixel
		 */
		public void setSamplesPerPixel(short sSamplesPerPixel)
		{
			/*Accept Number of samples (planes) in this image in short format of type US.
			 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Hash Map
			 */
			addDataElement(0x0028, 0x0002, DicomConstants.DCM_DT_US, sSamplesPerPixel);
		}
		/**
		 * Return the short value of the attribute Samples Per Pixel.
		 * 
		 * @return short - returns the Samples per pixel
		 */
		public short getSamplesPerPixel()
		{Object objectValue = getValue(0x0028, 0x0002);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * The method is used to set The Date and Time the acquisition of data that resulted in this image started
		 * The function accepts a String Value and creates the
		 * DE based on the transfer syntax and populates the DE with right values.
		 * This De is then added to the Module HashMap
		 * 
		 * @param strAcquisitionDatetime - String value of Acquisition Date and Time
		 */
		public void setAcquisitionDatetime(String strAcquisitionDatetime)
		{
			/*Accept The Date and Time the acquisition of data that resulted in this image started in String format of type TM.
			 * 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(0x0008, 0x002A, DicomConstants.DCM_DT_DT, strAcquisitionDatetime);
		}

		/**
		 * Retrieves the Date and Time of Acquisition.
		 * 
		 * @return String - returns the Date and Time of Acquisition
		 */
		public String getAcquisitionDatetime()
		{
			 Object objValue = getValue(0x0008,0x002A);
	   if(objValue!=null)
	      return objValue.toString();
	   return null;

		}
		/**
		 * Sets the time in seconds needed to run the prescribed pulse sequence.
		 * 
		 * @param dAcquisitionDuration - double value of Acquisition Duration.
		 */
		public void setAcquisitionDuration(double dAcquisitionDuration)
		{
			/* Accept Acquisition Duration 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(0x0018, 0x9073, DicomConstants.DCM_DT_FD, dAcquisitionDuration);
		}

		/**
		 * Retrieves the time in seconds needed to run the prescribed pulse sequence.
		 * 
		 * @return double - double value of Acquisition Duration.
		 */
		public double getAcquisitionDuration()
		{Object objectValue = getValue(0x0018, 0x9073);
			if(objectValue!=null)
				return Double.parseDouble(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}

		/**
		 * Sets a number identifying the single continuous gathering of data over a period of time which resulted in this image.
		 * 
		 * @param strAcquisitionNumber - String value of Acquisition Number.
		 */
		public void setAcquisitionNumber(String strAcquisitionNumber)
		{
			/*Accept number identifying the single continuous gathering of data
			 * 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 Hash Map
			 */
			addDataElement(0x0020, 0x0012, DicomConstants.DCM_DT_IS, strAcquisitionNumber);
		}

		/**
		 * Return the String value of the attribute Acquisition Number.
		 * 
		 * @return String - returns the Acquisition Number
		 */
		public String getAcquisitionNumber()
		{
			Object objectValue = getValue(0x0020, 0x0012);
			if(objectValue!=null)
				return objectValue.toString();
			return null;
		}
		/**
		 * Sets Specifies the intended interpretation of the pixel data.
		 * 
		 * @param enumPhotometricInterpretation - Enum value Photometric Interpretation
		 */
		public void setPhotometricInterpretation(EnumPhotometricInterpretation enumPhotometricInterpretation)
		{
			/*Accept Specifies the intended interpretation of the pixel data in String format of type ST.
			 * 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(0x0028, 0x0004, DicomConstants.DCM_DT_CS, enumPhotometricInterpretation.getValue());
		}

		/**
		 * Retrieves the photometric interpretation.
		 * 
		 * @return String - returns the photometric interpretation
		 */
		public String getPhotometricInterpretation()
		{
			Object objectValue = getValue(0x0028, 0x0004);
			if(objectValue!=null)
				return objectValue.toString();
			return null;
		}
		/**
		 * Sets Data representation of the pixel samples. Each sample shall have the same pixel
		 * representation. Enumerated Values: 0000H = unsigned integer. 0001H = 2's complement
		 * 
		 * @param enumPixelRepresentation the enum pixel representation
		 */
		public void setPixelRepresentation(EnumPixelRepresentation enumPixelRepresentation)
		{
			/*Accept Data representation of pixel in this image in short format of type US.
			 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Data Set
			 */
			addDataElement(0x0028, 0x0103, DicomConstants.DCM_DT_US, enumPixelRepresentation.getValue());
		}

		/**
		 * Retrieves the pixel representation.
		 * 
		 * @return - returns the pixel representation
		 */
		public short getPixelRepresentation()
		{
			Object objectValue = getValue(0x0028, 0x0103);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets Number of bits allocated for each pixel sample. Each sample shall have the same
		 * number of bits allocated.
		 * Enumerated Values: 8, 16
		 * 
		 * @param enumBitsAllocated the enum bits allocated
		 */
		public void setBitsAllocated(EnumBitsAllocated enumBitsAllocated)
		{
			/*Accept bits allocated for each pixel in this image in short format of type US.
			 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Data Set
			 */
			addDataElement(0x0028, 0x0100, DicomConstants.DCM_DT_US, enumBitsAllocated.getValue());
		}

		/**
		 * Retrieves the number of bits allocated.
		 * 
		 * @return - returns the number of bits allocated
		 */
		public short getBitsAllocated()
		{
			Object objectValue = getValue(0x0028, 0x0100);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets Number of bits stored for each pixel sample. Each sample shall have the same
		 * number of bits stored.
		 * Enumerated Values: 6 to 16
		 * 
		 * @param enumBitsStored the enum bits stored
		 */
		public void setBitsStored(EnumBitsStored enumBitsStored)
		{
			/*Accept bits stored for each pixel in this image in short format of type US.
			 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Data Set
			 */
			addDataElement(0x0028, 0x0101, DicomConstants.DCM_DT_US, enumBitsStored.getValue());
		}

		/**
		 * Retrieves the number of bits stored.
		 * 
		 * @return - returns the number of bits stored
		 */
		public short getBitsStored()
		{
			Object objectValue = getValue(0x0028, 0x0101);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets Most significant bit for pixel sample data. Each sample shall have the same high bit.
		 * 
		 * @param enumHighBit the enum high bit
		 */
		public void setHighBit(EnumHighBit enumHighBit)
		{
			/*Accept Most significant bit for pixel in this image in short format of type US.
			 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
			 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
			 * Set the iVRType
			 * Set length from the element
			 * Add this element to the Data Set
			 */
			addDataElement(0x0028, 0x0102, DicomConstants.DCM_DT_US, enumHighBit.getValue());
		}

		/**
		 * Retrieves the high bit.
		 * 
		 * @return - returns the high bit
		 */
		public short getHighBit()
		{
			Object objectValue = getValue(0x0028, 0x0102);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets a subset of a conceptual Presentation LUT.This Attribute defines an identity transformation or inverse
		 * identity transformation.
		 * Enumerated Values:
		 * IDENTITY - output is in P-Values - shall be
		 * used if Photometric Interpretation
		 * (0028,0004) is MONOCHROME2.
		 * INVERSE - output after inversion is in PValues
		 * - shall be used if Photometric
		 * Interpretation (0028,0004) is
		 * MONOCHROME1.
		 * 
		 * @param enumPresentationLUTShape the enum presentation lut shape
		 */
		public void setPresentationLUTShape(EnumPresentationLUTShape enumPresentationLUTShape)
		{
			/* Accept Presentation LUT 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 Hash Map
			 */
			addDataElement(0x2050,0x0020, DicomConstants.DCM_DT_CS, enumPresentationLUTShape.getValue());
		}

		/**
		 * Retrieves a subset of a conceptual Presentation LUT.
		 * 
		 * @return - String value of Presentation LUT Shape
		 */
		public String getPresentationLUTShape()
		{Object objectValue = getValue(0x2050,0x0020);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
		}
		/**
		 * Sets a value that specifies whether an Image has undergone lossy compression.
		 * Enumerated Values:
		 * 00 = Image has NOT been subjected to lossy compression,
		 * 01 = Image has been subjected to lossy compression.
		 * 
		 * @param enumLossyImageCompression the enum lossy image compression
		 */
		public void setLossyImageCompression(EnumLossyImageCompression enumLossyImageCompression)
		{
			/*Accept Specifies whether an Image has undergone lossy compression.
			 * 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(0x0028, 0x2110, DicomConstants.DCM_DT_CS, enumLossyImageCompression.getValue());
		}

		/**
		 * Retrieves the Lossy Image Compression.
		 * 
		 * @return - returns the Lossy Image Compression
		 */
		public String getLossyImageCompression()
		{
			Object objectValue = getValue(0x0028, 0x2110);
			if(objectValue!=null)
				return objectValue.toString();
			return null;
		}

		/**
		 * Sets the approximate lossy compression ratio(s) that have been applied to this image.
		 * 
		 * @param arrStrLossyImageCompressionRatio - String array of Lossy Image Compression Ratio
		 */
		public void setLossyImageCompressionRatio(String[] arrStrLossyImageCompressionRatio)
		{
			/*Accept the approximate lossy compression ratio(s) that have been applied to this image.
			 * 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 Hash Map
			 */
			addDataElement(0x0028, 0x2112, DicomConstants.DCM_DT_DS, arrStrLossyImageCompressionRatio);
		}

		/**
		 * Retrieves the Lossy Image Compression.
		 * 
		 * @return - returns the Lossy Image Compression
		 */
		public String[] getLossyImageCompressionRatio()
		{
			Object objValue = getValue(0x0028,0x2112);
			if(objValue!=null)
				return (String[])objValue;
			return null;

		}
		/**
		 * The method is used to set lossy compression method(s) that have been applied to this image.
		 * The function accepts a String Value and creates the
		 * DE based on the transfer syntax and populates the DE with right values.
		 * This De is then added to the Module HashMap
		 * 
		 * @param arrStrLossyImageCompressionMethod - Lossy Image Compression Method
		 */
		public void setLossyImageCompressionMethod(String[] arrStrLossyImageCompressionMethod)
		{
			/*Accept lossy compression method(s) that have been applied to this image
			 * 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(0x0028, 0x2114, DicomConstants.DCM_DT_CS, arrStrLossyImageCompressionMethod);
		}

		/**
		 * Retrieves the Lossy Image Compression Method.
		 * 
		 * @return String[] - the Lossy Image Compression Method
		 */
		public String[] getLossyImageCompressionMethod()
		{
			Object objValue = objIDataSet.getValue(0x0028, 0x2114);
			if(objValue != null)
				return (String[])objValue;
			return null;
		}
		/**
		 * Sets value that indicates whether or not image contains sufficient burned in annotation to identify the
		 * patient and date the image was acquired.
		 * Enumerated Values:
		 * YES
		 * NO
		 * 
		 * @param enumBurnedInAnnotation the enum burned in annotation
		 */
		public void setBurnedInAnnotation(EnumBurnedInAnnotation enumBurnedInAnnotation)
		{
			/*Accept Indicates whether or not image contains 
			 * sufficient burned in annotation to identify the patient and date the image was acquired 
			 * 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(0x0028, 0x0301, DicomConstants.DCM_DT_CS, enumBurnedInAnnotation.getValue());
		}

		/**
		 * Retrieves value that indicates whether or not image contains sufficient burned in annotation to identify the
		 * patient and date the image was acquired.
		 * 
		 * @return - String value of Burned In Annotation(Yes or No)
		 */
		public String getBurnedInAnnotation()
		{Object objectValue = getValue(0x0028,0x0301);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
		}
		/**
		 * Sets Recognizable Visual Features.
		 * Indicates whether or not the image contains sufficiently recognizable visual features 
		 * to allow the image or a reconstruction from a set of images to identify the patient.
		 * Enumerated Values:
		 * 1) YES 
		 * 2) NO
		 * 
		 * @param enumRecognizableVisualFeatures the enum Recognizable Visual Features
		 */
		public void setRecognizableVisualFeatures(EnumRecognizableVisualFeatures  enumRecognizableVisualFeatures)
		{
			/* Accept Recognizable Visual Features 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
			 */
			addDataElement(0x0028, 0x0302, DicomConstants.DCM_DT_CS, enumRecognizableVisualFeatures.getValue());
		}

		/**
		 * Retrieves Recognizable Visual Features.
		 * 
		 * @return String - String value of Recognizable Visual Features.
		 */ 
		public String getRecognizableVisualFeatures()
		{
			Object objValue = getValue(0x0028,0x0302);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Offset of the first frame in a multi-frame image of a concatenation.
		 * 
		 * @param dConcatenationFrameOffsetNumber - Offset of the first frame in a multi-frame image of a concatenation.
		 */	
		public void setConcatenationFrameOffsetNumber(long dConcatenationFrameOffsetNumber)
		{
			/*Accept the InstanceNumber 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 Hash Map
			 */
			addDataElement(0x0020,0x9228, DicomConstants.DCM_DT_UL, dConcatenationFrameOffsetNumber);
		}

		/**
		 * Retrieves Offset of the first frame in a multi-frame image of a concatenation.
		 * 
		 * @return - Double value of Concatenation Frame Offset Number.
		 */
		public long getConcatenationFrameOffsetNumber()
		{
			Object objectValue = getValue(0x0020,0x9228);
			if(objectValue!=null)
				return Long.parseLong(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets Identifier for one SOP Instance belonging to a concatenation.
		 * 
		 * @param shInConcatenationNumber - short value of In Concatenation Number.
		 */	
		public void setInConcatenationNumber(short shInConcatenationNumber)
		{
			/*Accept the InstanceNumber 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 Hash Map
			 */
			addDataElement(0x0020,0x9162, DicomConstants.DCM_DT_US, shInConcatenationNumber);
		}

		/**
		 * Retrieves IIdentifier for one SOP Instance belonging to a concatenation.
		 * 
		 * @return - String value of In Concatenation Number.
		 */
		public short getInConcatenationNumber()
		{
			Object objectValue = getValue(0x0020,0x9162);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets Identifier for one SOP Instance belonging to a concatenation.
		 * 
		 * @param InConcatenationTotalNumber - short value of In Concatenation Number.
		 */	
		public void setInConcatenationTotalNumber(short shInConcatenationTotalNumber)
		{
			/*Accept the InstanceNumber 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 Hash Map
			 */
			addDataElement(0x0020,0x9163, DicomConstants.DCM_DT_US, shInConcatenationTotalNumber);
		}

		/**
		 * Retrieves IIdentifier for one SOP Instance belonging to a concatenation.
		 * 
		 * @return - String value of In Concatenation Total Number.
		 */
		public short getInConcatenationTotalNumber()
		{
			Object objectValue = getValue(0x0020,0x9163);
			if(objectValue!=null)
				return Short.parseShort(objectValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}
		/**
		 * Sets User-defined comments about the image.
		 * 
		 * @param strImageComments - String value of Image Comments.
		 * 
		 * @return the int
		 */
		public void setImageComments(String strImageComments)
		{
			/*Accept the Image Comments in String format 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
			 */
			addDataElement(0x0020, 0x4000, DicomConstants.DCM_DT_LT, strImageComments);
		}

		/**
		 * Retrieves User-defined comments about the image.
		 * 
		 * @return String - String value of Image Comments.
		 */
		public String getImageComments()
		{
			Object objectValue = getValue(0x0020, 0x4000);
			if(objectValue!=null)
				return objectValue.toString();
			return null;
		}
}

