/*******************************************************************************
 *  Copyright 2017-2018 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package cdac.medinfo.sdk.dcm30_04.baselibs;



import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomValue;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDictionaryReader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITransferSyntax;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPatientPosition;
import cdac.medinfo.sdk.dcm30_04.enums.EnumSetupTechnique;
import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.exceptions.MandatoryMissingException;
import cdac.medinfo.sdk.dcm30_04.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;




/**
 * A sequence of patient setup data for current plan.
 */
public class PatientSetupSequenceItem extends Item  
{
	


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

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

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

	/**
	 * This constructor creates MultiplexedAudioChannelsDescriptionCodeSequenceItem with specified TransferSyntax and
	 * specified DictionaryReader.
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax.
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used.
	 */
	PatientSetupSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}

	/*
	 * (non-Javadoc) This mathod validates the contents of the Item
	 * @see cdac.medinfo.sdk.dcm30_04.commoninterface.IItem#validate()
	 */
	/**
	 * Validates all the attributes in CodeSequenceMacro that are present in the DataSet.
	 * @return boolean - Success -true, Failure - false.
	 * @throws InvalidItemException throws InvalidItemException If Mandatory or Conditional element fails.
	 */
	public boolean validateForModule()  throws InvalidItemException
	{
		try{
			if(!contains(0x300A,0x0182))
				throw new MandatoryMissingException("300A,0182");
			if(contains(0x0018,0x5100) && contains(0x300A,0x0184))
				throw new ConditionFailedException("only one of the conditional elements 0018,5100 and 300A,0184 should be present");

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

	/**
	 * Sets identification number of the Patient Setup.
	 * @param strPatientSetupNumber String value of Patient Setup Number.
	 */
	public void setPatientSetupNumber(String strPatientSetupNumber)
	{
		/*Accept the Patient Setup Number in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A,0x0182, strPatientSetupNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0182,DicomConstants.DCM_DT_IS, strPatientSetupNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Return identification number of the Patient Setup.
	 * @return String - value of Patient Setup Number.
	 */
	public String getPatientSetupNumber()
	{
		Object objValue = getValue(0x300A,0x0182);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets Patient Setup Label.
	 * @param strPatientSetupLabel String value of Patient Setup Label.
	 */
	public void setPatientSetupLabel(String strPatientSetupLabel)
	{
		/* Accept the Patient Setup Label in String format of type LO.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A,0x0183, strPatientSetupLabel,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x300A,0x0183,DicomConstants.DCM_DT_LO, strPatientSetupLabel);

		addDataElement(objIDataElement);
	}

	/**
	 * Return Patient Setup Label.
	 * @return String - value of Patient Setup Label.
	 */
	public String getPatientSetupLabel()
	{
		Object objValue = getValue(0x300A,0x0183);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets description of imaging subject�s position relative to the equipment.
	 * @param enumPatientPosition Enum value of Patient Position
	 */
	public void setPatientPosition(EnumPatientPosition enumPatientPosition)
	{
		/* Accept Patient Position 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018, 0x5100,enumPatientPosition.getValue(),objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018, 0x5100, DicomConstants.DCM_DT_CS,enumPatientPosition.getValue());

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves description of imaging subject�s position relative to the equipment.
	 * @return String value of Patient Position
	 */
	public String getPatientPosition()
	{
		Object objValue = getValue(0x0018, 0x5100);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Retrieves pre-initialized object of Referenced Setup Image 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 ReferencedSetupImageSequence - instance of ReferencedSetupImageSequence. 
	 */
	public ReferencedSetupImageSequence getReferencedSetupImageSequence()
	{
		ReferencedSetupImageSequence objReferencedSetupImageSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x0401);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedSetupImageSequence = (ReferencedSetupImageSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedSetupImageSequence = (ReferencedSetupImageSequence)objDicomV3Factory.createSequence(0x300A,0x01A0, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x0401, objReferencedSetupImageSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x0401, DicomConstants.DCM_DT_SQ, objReferencedSetupImageSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objReferencedSetupImageSequence;
	}

	/**
	 * Sets user-defined additional description of patient position. Required if Patient
	 * Position (0018,5100) is not present.
	 * @param strPatientAdditionalPosition  String value of Patient Additional Position.
	 */
	public void setPatientAdditionalPosition(String strPatientAdditionalPosition)
	{
		/* Accept Patient Additional Position 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 Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x0184,strPatientAdditionalPosition,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x0184, DicomConstants.DCM_DT_LO,strPatientAdditionalPosition);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves user-defined additional description of patient position. Required if Patient
	 * Position (0018,5100) is not present.
	 * @return String - value of Patient Additional Position.
	 */
	public String getPatientAdditionalPosition()
	{
		Object objValue = getValue(0x300A, 0x0184);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Retrieves pre-initialized object of Fixation Device 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 FixationDeviceSequence - instance of FixationDeviceSequence. 
	 */
	public FixationDeviceSequence getFixationDeviceSequence()
	{
		FixationDeviceSequence objFixationDeviceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x0190);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objFixationDeviceSequence = (FixationDeviceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objFixationDeviceSequence = (FixationDeviceSequence)objDicomV3Factory.createSequence(0x300A,0x0190, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x0190, objFixationDeviceSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x0190, DicomConstants.DCM_DT_SQ, objFixationDeviceSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objFixationDeviceSequence;
	}

	/**
	 * Retrieves pre-initialized object of Shielding Device 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 ShieldingDeviceSequence - instance of ShieldingDeviceSequence. 
	 */
	public ShieldingDeviceSequence getShieldingDeviceSequence()
	{
		ShieldingDeviceSequence objShieldingDeviceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x01A0);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objShieldingDeviceSequence = (ShieldingDeviceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objShieldingDeviceSequence = (ShieldingDeviceSequence)objDicomV3Factory.createSequence(0x300A,0x01A0, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x01A0, objShieldingDeviceSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x01A0, DicomConstants.DCM_DT_SQ, objShieldingDeviceSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objShieldingDeviceSequence;
	}

	/**
	 * Sets user-defined additional description of patient position. Required if Patient
	 * Position (0018,5100) is not present.
	 * @param enumSetupTechnique enum value of Setup Technique.
	 */
	public void setSetupTechnique(EnumSetupTechnique enumSetupTechnique)
	{
		/* Accept Setup Technique 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x01B0,enumSetupTechnique.getValue(),objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x01B0, DicomConstants.DCM_DT_CS,enumSetupTechnique.getValue());

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves user-defined additional description of patient position. Required if Patient
	 * Position (0018,5100) is not present.
	 * @return String - value of Patient Additional Position.
	 */
	public String getSetupTechnique()
	{
		Object objValue = getValue(0x300A, 0x01B0);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets user-defined description of Setup Technique.
	 * @param strSetupTechniqueDescription String value of Setup Technique Description.
	 */
	public void setSetupTechniqueDescription(String strSetupTechniqueDescription)
	{
		/* Accept Setup Technique Description 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 Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x01B2,strSetupTechniqueDescription,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x01B2, DicomConstants.DCM_DT_ST,strSetupTechniqueDescription);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves user-defined description of Setup Technique.
	 * @return String - value of Setup Technique Description.
	 */
	public String getSetupTechniqueDescription()
	{
		Object objValue = getValue(0x300A, 0x01B2);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Retrieves pre-initialized object of Setup Device 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 SetupDeviceSequence - instance of SetupDeviceSequence. 
	 */
	public SetupDeviceSequence getSetupDeviceSequence()
	{
		SetupDeviceSequence objSetupDeviceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x01B4);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objSetupDeviceSequence = (SetupDeviceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objSetupDeviceSequence = (SetupDeviceSequence)objDicomV3Factory.createSequence(0x300A,0x01B4, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x01B4, objSetupDeviceSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x01B4, DicomConstants.DCM_DT_SQ, objSetupDeviceSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objSetupDeviceSequence;
	}

	/**
	 * Sets vertical displacement in IEC TABLE TOP coordinate system (in mm) relative to initial
	 * Setup Position, i.e. vertical offset between patient positioning performed using setup
	 * and treatment position.
	 * @param strTableTopVerticalSetupDisplacement String value of Table Top Vertical Setup Displacement.
	 */
	public void setTableTopVerticalSetupDisplacement(String strTableTopVerticalSetupDisplacement)
	{
		/* Accept Table Top Vertical Setup Displacement 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x01D2,strTableTopVerticalSetupDisplacement,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x01D2, DicomConstants.DCM_DT_DS,strTableTopVerticalSetupDisplacement);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves vertical displacement in IEC TABLE TOP coordinate system (in mm) relative to initial
	 * Setup Position, i.e. vertical offset between patient positioning performed using setup
	 * and treatment position.
	 * @return String - value of Table Top Vertical Setup Displacement.
	 */
	public String getTableTopVerticalSetupDisplacement()
	{
		Object objValue = getValue(0x300A, 0x01D2);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets longitudinal displacement in IEC TABLE TOP coordinate system (in mm) relative to
	 * initial Setup Position, i.e. longitudinal offset between patient positioning performed
	 * using setup and treatment position.
	 * @param strTableTopLongitudinalSetupDisplacement String value of Table Top Longitudinal Setup Displacement.
	 */
	public void setTableTopLongitudinalSetupDisplacement(String strTableTopLongitudinalSetupDisplacement)
	{
		/* Accept Table Top Longitudinal Setup Displacement 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x01D4,strTableTopLongitudinalSetupDisplacement,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x01D4, DicomConstants.DCM_DT_DS,strTableTopLongitudinalSetupDisplacement);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves longitudinal displacement in IEC TABLE TOP coordinate system (in mm) relative to
	 * initial Setup Position, i.e. longitudinal offset between patient positioning performed
	 * using setup and treatment position.
	 * @return String - value of Table Top Longitudinal Setup Displacement.
	 */
	public String getTableTopLongitudinalSetupDisplacement()
	{
		Object objValue = getValue(0x300A, 0x01D4);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets lateral displacement in IEC TABLE TOP coordinate system (in mm) relative to initial
	 * Setup Position, i.e. lateral offset between patient positioning performed using setup
	 * and treatment position.
	 * @param strTableTopLateralSetupDisplacement String value of Table Top Lateral Setup Displacement.
	 */
	public void setTableTopLateralSetupDisplacement(String strTableTopLateralSetupDisplacement)
	{
		/* Accept Table Top Lateral Setup Displacement 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x300A, 0x01D6,strTableTopLateralSetupDisplacement,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x300A, 0x01D6, DicomConstants.DCM_DT_DS,strTableTopLateralSetupDisplacement);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves lateral displacement in IEC TABLE TOP coordinate system (in mm) relative to initial
	 * Setup Position, i.e. lateral offset between patient positioning performed using setup
	 * and treatment position.
	 * @return String - value of Table Top Longitudinal Setup Displacement.
	 */
	public String getTableTopLateralSetupDisplacement()
	{
		Object objValue = getValue(0x300A, 0x01D6);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Retrieves Motion Synchronization 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 FixationDeviceSequence - instance of FixationDeviceSequence. 
	 */
	public MotionSynchronizationSequence getMotionSynchronizationSequence()
	{
		MotionSynchronizationSequence objMotionSynchronizationSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x300A,0x0410);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objMotionSynchronizationSequence = (MotionSynchronizationSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objMotionSynchronizationSequence = (MotionSynchronizationSequence)objDicomV3Factory.createSequence(0x300A,0x0410, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x300A,0x0410, objMotionSynchronizationSequence.getValue(),objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x300A,0x0410, DicomConstants.DCM_DT_SQ, objMotionSynchronizationSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objMotionSynchronizationSequence;
	}
	
}
