/*******************************************************************************
 *  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.CoatingMaterialsCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.DerivationImplantTemplateSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.FixationMethodCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImplantRegulatoryDisapprovalCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImplantTargetAnatomySequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImplantTypeCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.InformationFromManufacturerSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.MaterialsCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.NotificationFromManufacturerSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.OriginalImplantTemplateSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ReplacedImplantTemplateSequence;
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.EnumImplantType;
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.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.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;
/**
\* This module is used for Generic Implant Template Description Module.
*/
public class GenericImplantTemplateDescriptionModule extends Module
{

	 /**
	  * The obj single collection.
	  */
	 public static ISingleCollection<ITag> objSingleCollection = null;
		 

		/**
		 * Instantiates a new Generic Implant Template Description Module
		 * 
		 * @param objIDataSet the obj i data set
		 */
		public GenericImplantTemplateDescriptionModule(IDataSet objIDataSet)
		{
			super(objIDataSet);
		}
		static
		{
			objSingleCollection = new SingleCollection<ITag>();
			objSingleCollection.add(new Tag(0x0008,0x0070));
			objSingleCollection.add(new Tag(0x0020,0x0052));
			objSingleCollection.add(new Tag(0x0022,0x1095));
			objSingleCollection.add(new Tag(0x0068,0x6210));
			objSingleCollection.add(new Tag(0x0022,0x1097));
			objSingleCollection.add(new Tag(0x0068,0x6221));
			objSingleCollection.add(new Tag(0x0068,0x6223));
			objSingleCollection.add(new Tag(0x0068,0x6226));
			objSingleCollection.add(new Tag(0x0068,0x6222));
			objSingleCollection.add(new Tag(0x0068,0x6225));
			objSingleCollection.add(new Tag(0x0068,0x6224));
			objSingleCollection.add(new Tag(0x0068,0x6230));
			objSingleCollection.add(new Tag(0x0068,0x6265));
			objSingleCollection.add(new Tag(0x0068,0x6260));
			objSingleCollection.add(new Tag(0x0068,0x62A0));
			objSingleCollection.add(new Tag(0x0068,0x62A5));
			objSingleCollection.add(new Tag(0x0068,0x63A0));
			objSingleCollection.add(new Tag(0x0068,0x63A4));
			objSingleCollection.add(new Tag(0x0068,0x63A8));
			objSingleCollection.add(new Tag(0x0068,0x63AC));
		}

		/**
		 * 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 - returns validation status as success or failure
		 * 
		 * @throws InvalidModuleException - If validation of Module fails
		 */
		public boolean validateModule() throws InvalidModuleException
		{
			try
			{			//Check for the Type 1,2 Mandatory Attributes.
				if(!isPresent(0x0008,0x0070))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0008,0070");
				}
				if(!isPresent(0x0020,0x0052))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0020,0052");
				}
				if(!isPresent(0x0022,0x1095))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0022,1095");
				}
				if(!isPresent(0x0022,0x1097))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0022,1097");
				}
				if(!isPresent(0x0068,0x6221))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,6221");
				}
				if(!isPresent(0x0068,0x6223))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,6223");
				}
				if(!isPresent(0x0068,0x6226))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,6226");
				}
				if(!isPresent(0x0068,0x62A5))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,62A5");
				}
				if(!isPresent(0x0068,0x63A8))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,63A8");
				}
				if(!isPresent(0x0068,0x63AC))
				{
					throw new MandatoryMissingException("Missing Mandatory DataElement 0068,63AC");
				}
							
				if(!isPresent(0x0068,0x6210))
				{
					throw new ConditionFailedException("Failed Conditional DataElement 0068,6210");
				}
				if(!isPresent(0x0068,0x6222))
				{
					throw new ConditionFailedException("Failed Conditional DataElement 0068,6222");
				}
				String strConcatenationUID = getImplantType();
				if(strConcatenationUID.toString().equals(EnumImplantType.DERIVED) && (!isPresent(0x0068,0x6225)))
					throw new ConditionFailedException("0068,6225 isRequired if Implant Assembly Template Type (0076,000A) isDERIVED.");
				
				if(strConcatenationUID.toString().equals(EnumImplantType.DERIVED) && (!isPresent(0x0068,0x6224)))
					throw new ConditionFailedException("0068,6224 isRequired if Implant Assembly Template Type (0076,000A) isDERIVED.");
				
				if(!isPresent(0x0068,0x6265))
				{
					throw new ConditionFailedException("Failed Conditional DataElement 0068,6265");
				}
			
				
			}
			catch(MandatoryMissingException mme)
			{
				if(DicomConfig.createInstance().isLoggingOn())
					DicomLogger.getLogger().log(mme.getMessage());

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

			}
			catch(ConditionFailedException ce)
			{
				if(DicomConfig.createInstance().isLoggingOn())
				{
					DicomLogger.getLogger().log(ce.getMessage());
				}
				throw new ValidationException(this.getClass().getSimpleName(),ce); 
			}
			catch(ValidationException ve)
			{
				if(DicomConfig.createInstance().isLoggingOn())
					DicomLogger.getLogger().log(ve.getMessage());

				
					throw new InvalidModuleException(this.getClass().getSimpleName(),ve);
			}
		
		return true;
		}
		/**
		 * Sets Manufacturer
		 * @param strManufacturer String value of Manufacturer
		 */
		public void setManufacturer(String strManufacturer)
		{
			/* Accept the Manufacturer 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
			 */
			addDataElement(0x0008, 0x0070,DicomConstants.DCM_DT_LO,strManufacturer);
		}

		/**
		 * Return Manufacturer
		 * @return String - value of Manufacturer
		 */
		public String getManufacturer()
		{
			Object objValue = getValue(0x0008, 0x0070);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets a Frame of Reference UID
		 * @param strFrameOfReferenceUID String value of Frame of Reference UID
		 */
		public void setFrameOfReferenceUID(String strFrameOfReferenceUID)
		{
			/*Accept the Frame of Reference UID in String format of type UI.
			 * 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, 0x0052,DicomConstants.DCM_DT_UI,strFrameOfReferenceUID);
		}

		/**
		 * Retrieves a Frame of Reference UID
		 * @return String - value of Frame of Reference UID
		 */
		public String getFrameOfReferenceUID()
		{
			Object objValue = getValue(0x0020, 0x0052);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Implant Name
		 * @param strImplantName String value of Implant Name
		 */
		public void setImplantName(String strImplantName)
		{
			/* Accept the Implant Name 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
			 */
			addDataElement(0x0022, 0x1095,DicomConstants.DCM_DT_LO,strImplantName);
		}

		/**
		 * Return Implant Name
		 * @return String - value of Implant Name
		 */
		public String getImplantName()
		{
			Object objValue = getValue(0x0022, 0x1095);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Implant Size
		 * @param strImplantSize String value of Implant Size
		 */
		public void setImplantSize(String strImplantSize)
		{
			/* Accept the Implant Size 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
			 */
			addDataElement(0x0068, 0x6210,DicomConstants.DCM_DT_LO,strImplantSize);
		}

		/**
		 * Return Implant Size
		 * @return String - value of Implant Size
		 */
		public String getImplantSize()
		{
			Object objValue = getValue(0x0068, 0x6210);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Implant Part Number
		 * @param strImplantPartNumber String value of ImplantPartNumber
		 */
		public void setImplantPartNumber(String strImplantSize)
		{
			/* Accept the ImplantPartNumber 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
			 */
			addDataElement(0x0022, 0x1097,DicomConstants.DCM_DT_LO,strImplantSize);
		}

		/**
		 * Return Implant Part Number
		 * @return String - value of ImplantPartNumber
		 */
		public String getImplantPartNumber()
		{
			Object objValue = getValue(0x0022, 0x1097);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Implant Template Version
		 * @param strImplantTemplateVersion String value of ImplantTemplateVersion
		 */
		public void setImplantTemplateVersion(String strImplantTemplateVersion)
		{
			/* Accept the ImplantPartNumber 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
			 */
			addDataElement(0x0068, 0x6221,DicomConstants.DCM_DT_LO,strImplantTemplateVersion);
		}

		/**
		 * Return Implant Template Version
		 * @return String - value of ImplantTemplateVersion
		 */
		public String getImplantTemplateVersion()
		{
			Object objValue = getValue(0x0068, 0x6221);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets whether the Implant Template is derived from nother Implant Template.
		 *Enumerated Values:
		 *ORIGINAL
		 *DERIVED
		 * @param enumImplantType enum value of Setup Device Type.
		 */
		public void setImplantType(EnumImplantType enumImplantType)
		{
			/* Accept the Setup Device 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
			 * */
			addDataElement(0x0068, 0x6223,DicomConstants.DCM_DT_CS,enumImplantType);
		}
		/**
		 * Return Implant Type
		 * @return String - value of ImplantType
		 */ 
		public String getImplantType()
		{
			Object objValue = getValue(0x0068,0x6223);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		/**
		 * Sets Effective DateTime
		 * @param strEffectiveDateTime String value of Effective DateTime
		 */
		public void setEffectiveDateTime(String strEffectiveDateTime)
		{
			/* Accept the Effective DateTime of type DT.
			 * 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(0x0068, 0x6226,DicomConstants.DCM_DT_DT,strEffectiveDateTime);
		}

		/**
		 * Retrieves Effective DateTime
		 * @return String - value of Effective DateTime
		 */
		public String getEffectiveDateTime()
		{
			Object objValue = getValue(0x0068, 0x6226);
			if(objValue != null)
				return objValue.toString();
			return null;
		}
		
		/**
		 * Sets the OverallTemplateSpatialTolerance
		 * @param dblOverallTemplateSpatialTolerance Double value of OverallTemplateSpatialTolerance
		 */
		public void setOverallTemplateSpatialTolerance(double dblOverallTemplateSpatialTolerance)
		{
			/*Accept the Overall Template Spatial Tolerance in double format of type FD.
			 * 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(0x0068, 0x62A5,DicomConstants.DCM_DT_FD,dblOverallTemplateSpatialTolerance);
		}
		/**
		 * Retrieves OverallTemplateSpatialTolerance
		 * @return double - double value of OverallTemplateSpatialTolerance
		 */
		public double getOverallTemplateSpatialTolerance()
		{
			Object objValue = getValue(0x0068,0x62A5);
			if(objValue != null)
				return Double.parseDouble(objValue.toString());
			return DicomConstants.DCM_NO_VALUE;
		}

		
		
		/**
		 * Retrieves pre-initialized object of Replaced Implant Template Sequence. If the module contains the sequence object
		 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
		 * and then returns the object of sequence
		 * 
		 * @return ReplacedImplantTemplateSequence - Replaced Implant Template Sequence.
		 */
		public ReplacedImplantTemplateSequence getReplacedImplantTemplateSequence()
		{
			ReplacedImplantTemplateSequence objReplacedImplantTemplateSequence = (ReplacedImplantTemplateSequence)getDicomValue(0x0068, 0x6222);
			if(objReplacedImplantTemplateSequence == 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();
				objReplacedImplantTemplateSequence = (ReplacedImplantTemplateSequence)objDicomV3Factory.createSequence(0x0068, 0x6222, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x6222, DicomConstants.DCM_DT_SQ, objReplacedImplantTemplateSequence.getValue());
			}
			return objReplacedImplantTemplateSequence;
		}
		/**
		 * Retrieves pre-initialized object of Original Implant Template Sequence. If the module contains the sequence object
		 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
		 * and then returns the object of sequence
		 * 
		 * @return OriginalImplantTemplateSequence - Original Implant Template Sequence.
		 */
		public OriginalImplantTemplateSequence getOriginalImplantTemplateSequence()
		{
			OriginalImplantTemplateSequence objOriginalImplantTemplateSequence= (OriginalImplantTemplateSequence)getDicomValue(0x0068,0x6225);
			if(objOriginalImplantTemplateSequence == 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();
				objOriginalImplantTemplateSequence = (OriginalImplantTemplateSequence)objDicomV3Factory.createSequence(0x0068,0x6225, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068,0x6225, DicomConstants.DCM_DT_SQ, objOriginalImplantTemplateSequence.getValue());
			}
			return objOriginalImplantTemplateSequence;
		}
		
		/**
		 * Retrieves pre-initialized object of Derivation Implant Template Sequence. If the module contains the sequence object
		 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
		 * and then returns the object of sequence
		 * 
		 * @return DerivationImplantTemplateSequence - Derivation Implant Template Sequence.
		 */
		public DerivationImplantTemplateSequence getDerivationImplantTemplateSequence()
		{
			DerivationImplantTemplateSequence objDerivationImplantTemplateSequence = (DerivationImplantTemplateSequence)getDicomValue(0x0068, 0x6224);
			if(objDerivationImplantTemplateSequence == 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();
				objDerivationImplantTemplateSequence = (DerivationImplantTemplateSequence)objDicomV3Factory.createSequence(0x0068, 0x6224, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x6224, DicomConstants.DCM_DT_SQ, objDerivationImplantTemplateSequence.getValue());
			}
			return objDerivationImplantTemplateSequence;
		}	
		/**
		 * Retrieves pre-initialized object of Implant TargetAnatomy Sequence. If the module contains the sequence object
		 * it returns the same otherwise it creates the sequence adds to the module with proper initialization
		 * and then returns the object of sequence
		 * 
		 * @return ImplantTargetAnatomySequence - Implant TargetAnatomy Sequence
		 */
		public ImplantTargetAnatomySequence getImplantTargetAnatomySequence()
		{
			ImplantTargetAnatomySequence objImplantTargetAnatomySequence= (ImplantTargetAnatomySequence)getDicomValue(0x0068, 0x6230);
			if(objImplantTargetAnatomySequence == 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();
				objImplantTargetAnatomySequence = (ImplantTargetAnatomySequence)objDicomV3Factory.createSequence(0x0068, 0x6230, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x6230, DicomConstants.DCM_DT_SQ, objImplantTargetAnatomySequence.getValue());
			}
			return objImplantTargetAnatomySequence;
		}	
		
		/**
		 * Retrieves pre-initialized object of NotificationFromManufacturerSequence. 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 NotificationFromManufacturerSequence - NotificationFromManufacturerSequence
		 */
		public NotificationFromManufacturerSequence getNotificationFromManufacturerSequence()
		{
			NotificationFromManufacturerSequence objNotificationFromManufacturerSequence= (NotificationFromManufacturerSequence)getDicomValue(0x0068, 0x6265);
			if(objNotificationFromManufacturerSequence == 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();
				objNotificationFromManufacturerSequence = (NotificationFromManufacturerSequence)objDicomV3Factory.createSequence(0x0068, 0x6265, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x6265, DicomConstants.DCM_DT_SQ, objNotificationFromManufacturerSequence.getValue());
			}
			return objNotificationFromManufacturerSequence;
		}
		
		/**
		 * Retrieves pre-initialized object of InformationFromManufacturerSequence. 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 InformationFromManufacturerSequence 
		 */
		public InformationFromManufacturerSequence getInformationFromManufacturerSequence()
		{
			InformationFromManufacturerSequence objInformationFromManufacturerSequence= (InformationFromManufacturerSequence)getDicomValue(0x0068, 0x6260);
			if(objInformationFromManufacturerSequence == 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();
				objInformationFromManufacturerSequence = (InformationFromManufacturerSequence)objDicomV3Factory.createSequence(0x0068, 0x6260, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x6260, DicomConstants.DCM_DT_SQ, objInformationFromManufacturerSequence.getValue());
			}
			return objInformationFromManufacturerSequence;
		}

		/**
		 * Retrieves pre-initialized object of ImplantRegulatoryDisapprovalCodeSequence. 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 ImplantRegulatoryDisapprovalCodeSequence 
		 */
		public ImplantRegulatoryDisapprovalCodeSequence getImplantRegulatoryDisapprovalCodeSequence()
		{
			ImplantRegulatoryDisapprovalCodeSequence objImplantRegulatoryDisapprovalCodeSequence= (ImplantRegulatoryDisapprovalCodeSequence)getDicomValue(0x0068, 0x62A0);
			if(objImplantRegulatoryDisapprovalCodeSequence == 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();
				objImplantRegulatoryDisapprovalCodeSequence = (ImplantRegulatoryDisapprovalCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x62A0, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x62A0, DicomConstants.DCM_DT_SQ, objImplantRegulatoryDisapprovalCodeSequence.getValue());
			}
			return objImplantRegulatoryDisapprovalCodeSequence;
		}
		/**
		 * Retrieves pre-initialized object of MaterialsCodeSequence. 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 MaterialsCodeSequence 
		 */
		public MaterialsCodeSequence getMaterialsCodeSequence()
		{
			MaterialsCodeSequence objMaterialsCodeSequence= (MaterialsCodeSequence)getDicomValue(0x0068, 0x63A0);
			if(objMaterialsCodeSequence == 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();
				objMaterialsCodeSequence = (MaterialsCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x63A0, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x63A0, DicomConstants.DCM_DT_SQ, objMaterialsCodeSequence.getValue());
			}
			return objMaterialsCodeSequence;
		}
		/**
		 * Retrieves pre-initialized object of CoatingMaterialsCodeSequence. 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 CoatingMaterialsCodeSequence 
		 */
		public CoatingMaterialsCodeSequence getCoatingMaterialsCodeSequence()
		{
			CoatingMaterialsCodeSequence objCoatingMaterialsCodeSequence= (CoatingMaterialsCodeSequence)getDicomValue(0x0068, 0x63A4);
			if(objCoatingMaterialsCodeSequence == 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();
				objCoatingMaterialsCodeSequence = (CoatingMaterialsCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x63A4, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x63A4, DicomConstants.DCM_DT_SQ, objCoatingMaterialsCodeSequence.getValue());
			}
			return objCoatingMaterialsCodeSequence;
		}
		
		
		/**
		 * Retrieves pre-initialized object of ImplantTypeCodeSequence. 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 ImplantTypeCodeSequence 
		 */
		public ImplantTypeCodeSequence getImplantTypeCodeSequence()
		{
			ImplantTypeCodeSequence objImplantTypeCodeSequence= (ImplantTypeCodeSequence)getDicomValue(0x0068, 0x63A8);
			if(objImplantTypeCodeSequence == 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();
				objImplantTypeCodeSequence = (ImplantTypeCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x63A8, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x63A8, DicomConstants.DCM_DT_SQ, objImplantTypeCodeSequence.getValue());
			}
			return objImplantTypeCodeSequence;
		}
		
		/**
		 * Retrieves pre-initialized object of FixationMethodCodeSequence. 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 FixationMethodCodeSequence 
		 */
		public FixationMethodCodeSequence getFixationMethodCodeSequence()
		{
			FixationMethodCodeSequence objFixationMethodCodeSequence= (FixationMethodCodeSequence)getDicomValue(0x0068, 0x63AC);
			if(objFixationMethodCodeSequence == 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();
				objFixationMethodCodeSequence = (FixationMethodCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x63AC, objITransferSyntax, objIDictionaryReader);
				
				// This will add Data Element of SQ to the DataSet.
				addDataElement(0x0068, 0x63AC, DicomConstants.DCM_DT_SQ, objFixationMethodCodeSequence.getValue());
			}
			return objFixationMethodCodeSequence;
		}
		
		/*
		 * This method is used by the Module Iterator to iterate through the DataSet and return only
		 * those elements that belong to the respective Module class whose this is called.
		 */
		/**
		 * This method returns the collection of keys representing the DataElements
		 * that belong to this module.
		 * 
		 * @return ISingleCollection - the customized collection containing the dataelement tags
		 * that beling to this module
		 */
		public ISingleCollection<ITag> getVectorOfKeys()
		{
			return objSingleCollection;
		}
}
