/*******************************************************************************
 *  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.EnumDisplaySetHorizontalJustification;
import cdac.medinfo.sdk.dcm30_04.enums.EnumDisplaySetVerticalJustification;
import cdac.medinfo.sdk.dcm30_04.enums.EnumImageBoxLayoutType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumInitialCineRunState;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPreferredPlaybackSequencing;
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;
import cdac.medinfo.sdk.dcm30_04.utils.EnumFeatureList;
/**
* This item class contains methods to validate, set and get the attributes of Structured Display Image Box Sequence .
 */
public class StructuredDisplayImageBoxSequenceItem extends Item
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * This constructor creates the item and internal code sequence macro with default TransferSyntax 
	 */
	StructuredDisplayImageBoxSequenceItem()
	{
		super();
	}


	/**
	 * This constructor creates the item and internal code sequence macro with specified TransferSyntax 
	 * and default DictionaryReader
	 * @param objITransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 */
	StructuredDisplayImageBoxSequenceItem(ITransferSyntax objITransferSyntax)
	{
		super(objITransferSyntax);
	}

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

	
	/**
	 * Validates all the attributes in StructuredDisplayImageBoxSequenceItem that are present in the DataSet
	 * @return boolean - Success -true, Failure - false
	 * @throws MandatoryMissingException throws MandatoryMissingException If Conditional element fails.
	 */
	public boolean validateForModule()  throws InvalidItemException
	{
		try
		{	
			if(!contains(0x0072,0x0108))
				throw new MandatoryMissingException("(0072,0108") ;
			if(!contains(0x0072,0x0302))
				throw new MandatoryMissingException("0072,0302") ;
			if(!contains(0x0070,0x0304))
				throw new MandatoryMissingException("0072,0304") ;
	if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.TILED))
				if(!contains(0x0072,0x0306))
					throw new ConditionFailedException("0x300A,0x034C");
					
if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.TILED))
	if(!contains(0x0072,0x0306))
				throw new ConditionFailedException("0072,0306 Required if the value of Image Box Layout Type (0072,0304) is TILED.") ;

if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.TILED))
	if(!contains(0x0072,0x0308))
				throw new ConditionFailedException("0072,0308 Required if the value of Image Box Layout Type (0072,0304) is TILED. ") ;

if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0018,0x1244))
				throw new ConditionFailedException("0018,1244 Required if the value of Image Box Layout Type (0072,0304) is CINE.") ;

if(!contains(0x0072,0x0330)&&getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0008,0x2144))
				throw new ConditionFailedException("0008,2144 Required if the value of Image Box Layout Type (0072,0304) is CINE and if Cine Relative to Real-Time (0072,0330) is not present.") ;

if(!contains(0x0008,0x2144)&&getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0072,0x0330))
				throw new ConditionFailedException("0072,0330 Required if the value of Image Box Layout Type (0072,0304) is CINE andif Recommended Display Frame Rate (0008,2144) is not present.") ;

if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0018,0x0042))
				throw new ConditionFailedException("0018,0042 Required if the value of Image Box Layout Type (0072,0304) is CINE.") ;
			
if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0018,0x2142))
				throw new ConditionFailedException("0008,2142 Required if the value of Image Box Layout Type (0072,0304) is CINE.") ;
			
if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.CINE))
	if(!contains(0x0018,0x2143))
				throw new ConditionFailedException("0008,2143 Required if the value of Image Box Layout Type (0072,0304) is CINE.") ;
			
if(getDataForTag(0x0072, 0x0304).getValue().toString().equals(EnumImageBoxLayoutType.STACK))
	if(!contains(0x0072,0x0427))
				throw new ConditionFailedException("0072,0427 Required if the value of Image Box Layout Type (0072,0304) is STACK") ;
			
if(!contains(0x0008,0x9237)&&!contains(0x0008,0x1134)&&!contains(0x0008,0x114A))
			if(!contains(0x0008,0x1140))
				throw new ConditionFailedException("0008,1140 Required if Referenced Presentation State Sequence (0008,9237),Referenced Stereometric Instance Sequence (0008,1134), and ReferencedInstance Sequence (0008,114A) are not present. ") ;

if(!contains(0x0008,0x1140)&&!contains(0x0008,0x1134)&&!contains(0x0008,0x114A))
			if(!contains(0x0008,0x9237))
				throw new ConditionFailedException("0008,9237 Required if Referenced Image Sequence (0008,1140), ReferencedStereometric Instance Sequence (0008,1134), and Referenced InstanceSequence (0008,114A) are not present.") ;
			
if(!contains(0x0008,0x9237)&&!contains(0x0008,0x1134)&&!contains(0x0008,0x1140))
			if(!contains(0x0008,0x114A))
				throw new ConditionFailedException("0008,114A Required if Referenced Presentation State Sequence (0008,9237),Referenced Stereometric Instance Sequence (0008,1134), and ReferencedImage Sequence (0008,1140) are not present.") ;

if(!contains(0x0008,0x9237)&&!contains(0x0008,0x1140)&&!contains(0x0008,0x114A))
	if(!contains(0x0008,0x1134))
				throw new ConditionFailedException("0008,1134 Required if Referenced Presentation State Sequence (0008,9237),Referenced Instance Sequence (0008,114A), and Referenced ImageSequence (0008,1140) are not present.");
					
		}
		catch( MandatoryMissingException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),ce); 
		}
		catch(ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new ValidationException(this.getClass().getSimpleName(),ce); 
		}
		return true;
	}
	/**
	 * Sets the Display Environment SpatialPosition
	 * @param dblArrDisplayEnvironmentSpatialPosition Double value of Display Environment SpatialPosition
	 */
	public void setDisplayEnvironmentSpatialPosition(double[] dblArrDisplayEnvironmentSpatialPosition)
	{
		/*Accept the Display Environment SpatialPosition 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0108, dblArrDisplayEnvironmentSpatialPosition,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0108,DicomConstants.DCM_DT_FD, dblArrDisplayEnvironmentSpatialPosition);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the Display Environment SpatialPosition
	 * @return double - double value of DisplayEnvironmentSpatialPosition
	 */
	public double[] getDisplayEnvironmentSpatialPosition()
	{
		Object objValue = getValue(0x0072,0x0108);
		if(objValue != null)
			return (double[])objValue;
		return null;
	}
	/**
	 * Sets Image Box Number
	 * @param shImageBoxNumber short value of Image Box Number
	 */
	public void setImageBoxNumber(short shImageBoxNumber)
	{
		/* Accept the Image Box Number 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0072,0x0302,shImageBoxNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0302,DicomConstants.DCM_DT_US, shImageBoxNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Image Box Number
	 * @return short - short value of Image Box Number
	 */
	public short getImageBoxNumber()
	{
		Object objValue = getValue(0x0072,0x0302);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets type of layout of the Image Box.
	 * @param enumImageBoxLayoutType enum value of ImageBoxLayoutType
	 */
	public void setImageBoxLayoutType(EnumImageBoxLayoutType enumImageBoxLayoutType)
	{
		/* Accept the ImageBoxLayoutType in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0304, enumImageBoxLayoutType.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0304,DicomConstants.DCM_DT_CS, enumImageBoxLayoutType.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return type of layout of the Image Box.
	 * @return String - value of ImageBoxLayoutType.
	 */
	public String getImageBoxLayoutType()
	{
		Object objValue = getValue(0x0072,0x0304);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Image Box Tile HorizontalDimension
	 * @param shImageBoxTileHorizontalDimension short value of Image Box Tile HorizontalDimension
	 */
	public void setImageBoxTileHorizontalDimension(short shImageBoxTileHorizontalDimension)
	{
		/* Accept the Image Box Tile HorizontalDimension 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0072,0x0306,shImageBoxTileHorizontalDimension,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0306,DicomConstants.DCM_DT_US, shImageBoxTileHorizontalDimension);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Image Box Tile HorizontalDimension
	 * @return short - short value of Image Box Tile HorizontalDimension
	 */
	public short getImageBoxTileHorizontalDimension()
	{
		Object objValue = getValue(0x0072,0x0306);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets Image Box Tile Vertical Dimension
	 * @param shImageBoxTileVerticalDimension short value of Image Box Tile Vertical Dimension
	 */
	public void setImageBoxTileVerticalDimension(short shImageBoxTileVerticalDimension)
	{
		/* Accept the Image Box Tile Vertical Dimension 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0072,0x0308,shImageBoxTileVerticalDimension,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0308,DicomConstants.DCM_DT_US, shImageBoxTileVerticalDimension);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Image Box Tile Vertical Dimension
	 * @return short - short value of Image Box Tile Vertical Dimension
	 */
	public short getImageBoxTileVerticalDimension()
	{
		Object objValue = getValue(0x0072,0x0308);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets Image Box Overlap Priority
	 * @param shImageBoxOverlapPriority short value of Image Box Overlap Priority
	 */
	public void setImageBoxOverlapPriority(short shImageBoxOverlapPriority)
	{
		/* Accept the ImageBoxOverlapPriority 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0072,0x0320,shImageBoxOverlapPriority,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0320,DicomConstants.DCM_DT_US, shImageBoxOverlapPriority);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Image Box Overlap Priority
	 * @return short - short value of Image Box Overlap Priority
	 */
	public short getImageBoxOverlapPriority()
	{
		Object objValue = getValue(0x0072,0x0320);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets direction in which to horizontally justify the image within anImage Box that is not the same shape (aspect ratio) as the image.
	 * @param enumDisplaySetHorizontalJustification enum value of Display Set Horizontal Justification
	 */
	public void setDisplaySetHorizontalJustification(EnumDisplaySetHorizontalJustification enumDisplaySetHorizontalJustification)
	{
		/* Accept the Display Set Horizontal Justification in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0717, enumDisplaySetHorizontalJustification.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0717,DicomConstants.DCM_DT_CS, enumDisplaySetHorizontalJustification.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Display Set Horizontal Justification
	 * @return String - value of Display Set Horizontal Justification
	 */
	public String getDisplaySetHorizontalJustification()
	{
		Object objValue = getValue(0x0072,0x0717);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets direction in which to vertically justify the image within anImage Box that is not the same shape (aspect ratio) as the image.
	 * @param enumDisplaySetVerticalJustification enum value of Display Set Vertical Justification
	 */
	public void setDisplaySetVerticalJustification(EnumDisplaySetVerticalJustification enumDisplaySetVerticalJustification)
	{
		/* Accept the Display Set Vertical Justification in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0718, enumDisplaySetVerticalJustification.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0718,DicomConstants.DCM_DT_CS, enumDisplaySetVerticalJustification.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Display Set Vertical Justification
	 * @return String - value of Display Set Vertical Justification
	 */
	public String getDisplaySetVerticalJustification()
	{
		Object objValue = getValue(0x0072,0x0718);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets the preferred playback sequencing for the Image Box. Overridesany Preferred Playback Sequencing (0018,1244) value in the imageobjects being displayed.
	 * @param enumPreferredPlaybackSequencing value of Preferred Playback Sequencing
	 */
	public void setPreferredPlaybackSequencing(EnumPreferredPlaybackSequencing enumPreferredPlaybackSequencing)
	{
		/* Accept the Preferred Playback Sequencing in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x1244, enumPreferredPlaybackSequencing.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x1244,DicomConstants.DCM_DT_US, enumPreferredPlaybackSequencing.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return  Preferred Playback Sequencing
	 * @return String - value of Preferred Playback Sequencing
	 */
	public String getPreferredPlaybackSequencing()
	{
		Object objValue = getValue(0x0018,0x1244);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets recommended rate at which the frames of a multi-frame image shall bedisplayed, in frames/second. 
	 * @param strRecommendedDisplayFrameRate String value of Recommended Display FrameRate
	 */
	public void setRecommendedDisplayFrameRate(String strRecommendedDisplayFrameRate )
	{
		/*Accept the Recommended Display FrameRate 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(0x0008,0x2144, strRecommendedDisplayFrameRate ,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0008,0x2144,DicomConstants.DCM_DT_IS, strRecommendedDisplayFrameRate );

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves recommended rate at which the frames of a multi-frame image shall bedisplayed, in frames/second. 
	 * @return String - value of Recommended Display FrameRate
	 */
	public String getRecommendedDisplayFrameRate()
	{
		Object objValue = getValue(0x0008,0x2144);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets the positive dimensionless floating point numeric factor equal to playbackrate divided by acquisition rate.
	 * @param dblCineRelativeToRealTime Double value of Cine Relative toReal-Time
	 */
	public void getCineRelativeToRealTime(double dblCineRelativeToRealTime)
	{
		/*Accept the Cine Relative to Real-Time 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0330, dblCineRelativeToRealTime,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0330,DicomConstants.DCM_DT_FD, dblCineRelativeToRealTime);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the positive dimensionless floating point numeric factor equal to playbackrate divided by acquisition rate.
	 * @return double - double value of Cine Relative toReal-Time
	 */
	public double getCineRelativeToRealTime()
	{
		Object objValue = getValue(0x0072,0x0330);
		if(objValue != null)
			return Double.parseDouble(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets Initial Cine Run State
	 * @param enumInitialCineRunState enum value of Initial Cine Run State
	 */
	public void setInitialCineRunState(EnumInitialCineRunState enumInitialCineRunState)
	{
		/* Accept the Initial Cine Run State in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x0042, enumInitialCineRunState.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0018,0x0042,DicomConstants.DCM_DT_CS, enumInitialCineRunState.getValue());

		addDataElement(objIDataElement);
	}
	/**
	 * Return Initial Cine Run State
	 * @return String - value of Initial Cine Run State
	 */
	public String getInitialCineRunState()
	{
		Object objValue = getValue(0x0018,0x0042);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets frame number of the first frame of the multi-frame image to bedisplayed in a CINE Image Box.
	 * @param strStartTrim String value of Start Trim
	 */
	public void setStartTrim(String strStartTrim )
	{
		/*Accept the Start Trim 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(0x0008,0x2142, strStartTrim ,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0008,0x2142,DicomConstants.DCM_DT_IS, strStartTrim );

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves frame number of the first frame of the multi-frame image to bedisplayed in a CINE Image Box.
	 * @return String - value of Start Trim
	 */
	public String getStartTrim()
	{
		Object objValue = getValue(0x0008,0x2142);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Sets Frame Number of the last frame of the multi-frame image to bedisplayed in a CINE Image Box.
	 * @param strStopTrim String value of Stop Trim
	 */
	public void setStopTrim(String strStopTrim )
	{
		/*Accept the Stop Trim 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(0x0008,0x2143, strStopTrim ,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0008,0x2143,DicomConstants.DCM_DT_IS, strStopTrim );

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Frame Number of the last frame of the multi-frame image to bedisplayed in a CINE Image Box.
	 * @return String - value of Stop Trim
	 */
	public String getStopTrim()
	{
		Object objValue = getValue(0x0008,0x2143);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Retrieves pre-initialized object of Referenced First FrameSequence.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 ReferencedFirstFrameSequence - instance of Referenced First FrameSequence. 
	 */
	public ReferencedFirstFrameSequence getPrimaryFluenceModeSequence()
	{
		ReferencedFirstFrameSequence objReferencedFirstFrameSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0072, 0x0427); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedFirstFrameSequence = (ReferencedFirstFrameSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedFirstFrameSequence = (ReferencedFirstFrameSequence)objDicomV3Factory.createSequence(0x0072, 0x0427, objITransferSyntax, objIDictionaryReader);

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

	/**
	 * Retrieves pre-initialized object of Referenced 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 ReferencedImageSequence - instance of Referenced Image Sequence 
	 */
	public ReferencedImageSequence getReferencedImageSequence()
	{
		ReferencedImageSequence objReferencedImageSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008, 0x1140); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedImageSequence = (ReferencedImageSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedImageSequence = (ReferencedImageSequence)objDicomV3Factory.createSequence(0x0008, 0x1140, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0008, 0x1140, objReferencedImageSequence.getValue(), objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0008, 0x1140, DicomConstants.DCM_DT_SQ, objReferencedImageSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objReferencedImageSequence;
	}
	/**
	 * Retrieves pre-initialized object of Referenced Presentation StateSequence.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 ReferencedPresentationStateSequence - instance of Referenced Presentation StateSequence
	 */
	public ReferencedPresentationStateSequence getReferencedPresentationStateSequence()
	{
		ReferencedPresentationStateSequence objReferencedPresentationStateSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008, 0x9237); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedPresentationStateSequence = (ReferencedPresentationStateSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedPresentationStateSequence = (ReferencedPresentationStateSequence)objDicomV3Factory.createSequence(0x0008, 0x9237, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0008, 0x9237, objReferencedPresentationStateSequence.getValue(), objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0008, 0x9237, DicomConstants.DCM_DT_SQ, objReferencedPresentationStateSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objReferencedPresentationStateSequence;
	}
	/**
	 * Retrieves pre-initialized object of Referenced Instance 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 ReferencedInstanceSequence - instance of Referenced Instance Sequence
	 */
	public ReferencedInstanceSequence getReferencedInstanceSequence()
	{
		ReferencedInstanceSequence objReferencedInstanceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008, 0x114A); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedInstanceSequence = (ReferencedInstanceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedInstanceSequence = (ReferencedInstanceSequence)objDicomV3Factory.createSequence(0x0008, 0x114A, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0008, 0x114A, objReferencedInstanceSequence.getValue(), objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0008, 0x114A, DicomConstants.DCM_DT_SQ, objReferencedInstanceSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objReferencedInstanceSequence;
	}
	/**
	 * Retrieves pre-initialized object of Referenced Stereometric InstanceSequence.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 ReferencedStereometricInstanceSequence - instance of Referenced Stereometric InstanceSequence
	 */
	public ReferencedStereometricInstanceSequence getReferencedStereometricInstanceSequence()
	{
		ReferencedStereometricInstanceSequence objReferencedStereometricInstanceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008, 0x1134); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedStereometricInstanceSequence = (ReferencedStereometricInstanceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedStereometricInstanceSequence = (ReferencedStereometricInstanceSequence)objDicomV3Factory.createSequence(0x0008, 0x1134, objITransferSyntax, objIDictionaryReader);

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