/*******************************************************************************
 *  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.enums.EnumShutterShape;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDictionaryReader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidMacroException;
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;


/**
 * This Macro contains attributes of Display Shutter Macro.
 */
public class DisplayShutterMacro extends Macro 
{
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	SOPInstanceReferenceMacro objSOPInstanceReferenceMacro = null;

	/**
	 * This constructor constructs a Macro with specified DataSet.
	 * @param objDataSet Collection of Data Elements 
	 */
	public DisplayShutterMacro(IDataSet objDataSet)
	{
		super(objDataSet);
	}

	/**
	 * This constructor constructs a Macro with specified DataSet and DictionaryReader
	 * @param objDataSet specifies the DataSet
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	public DisplayShutterMacro(IDataSet objDataSet,IDictionaryReader objDictionaryReader)
	{
		super(objDataSet,objDictionaryReader);
	}

	/**
	 * This constructor constructs a Macro with the specified Item
	 * @param objItem specifies instance of Item class
	 */
	public DisplayShutterMacro(IItem objItem)
	{
		super(objItem);
	}

	/**
	 * This constructor constructs a Macro with the specified Item and Dictionary Reader
	 * @param objItem specifies instance of Item class
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	public DisplayShutterMacro(IItem objItem,IDictionaryReader objDictionaryReader)
	{
		super(objItem, objDictionaryReader);
	}
	
	/**
	 * Shape(s) of the shutter defined for display.
	 *Enumerated Values:
	 *RECTANGULAR
	 *CIRCULAR
	 *POLYGONAL
	 *This multi-valued Attribute shall contain at most one of each EnumeratedValue. 
	 *When multiple values are present, and the shutter is applied to adisplayed image,
	 * then all of the shapes shall be combined and appliedsimultaneously, that is,
	 *  the least amount of image remaining shall be visible
	 * @param enumSetupDeviceType enum value of Setup Device Type.
	 */
	public void setShutterShape(EnumShutterShape enumShutterShape)
	{
		/* Accept the Shutter Shape 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x1600, enumShutterShape.getValue(),objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1600,DicomConstants.DCM_DT_CS, enumShutterShape.getValue());

		addDataElement(objIDataElement);
	}

	/**
	 * Return type of setup device used for Patient alignment. 
	 * @return String - value of Setup Device Type.
	 */
	public String getShutterShape()
	{
		Object objValue = getValue(0x0018,0x1600);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Required if Shutter Shape (0018,1600) is RECTANGULAR. Location of theleft edge of the rectangular shutter with respect to pixels in the image givenas column.
	 * @param strReferencedReferenceImageNumber String value of Referenced Reference Image Number.
	 */
	public void setShutterLeftVerticalEdge (String strShutterLeftVerticalEdge )
	{
		/*Accept the Referenced Shutter Left Vertical Edge  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(0x0018,0x1602, strShutterLeftVerticalEdge ,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1602,DicomConstants.DCM_DT_IS, strShutterLeftVerticalEdge );

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Referenced Shutter Left Vertical Edge
	 * @return String - value of Referenced Shutter Left Vertical Edge.
	 */
	public String getShutterLeftVerticalEdge()
	{
		Object objValue = getValue(0x0018,0x1602);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is RECTANGULAR. Location of theright edge of the rectangular shutter with respect to pixels in the image givenas column.
	 * @param strReferencedReferenceImageNumber String value of Referenced Shutter Right Vertical Edge.
	 */
	public void setShutterRightVerticalEdge(String strShutterRightVerticalEdge )
	{
		/*Accept the Referenced Shutter Right Vertical Edge  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(0x0018,0x1604, strShutterRightVerticalEdge,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1604,DicomConstants.DCM_DT_IS, strShutterRightVerticalEdge);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Referenced Shutter Right Vertical Edge 
	 * @return String - value of Referenced Shutter Right Vertical Edge 
	 */
	public String getShutterRightVerticalEdge()
	{
		Object objValue = getValue(0x0018,0x1604);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is RECTANGULAR. Location of theright edge of the rectangular shutter with respect to pixels in the image givenas column.
	 * @param strReferencedReferenceImageNumber String value of Shutter Upper Horizontal Edge.
	 */
	public void setShutterUpperHorizontalEdge(String strShutterUpperHorizontalEdge)
	{
		/*Accept the Referenced Shutter Upper Horizontal Edge 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(0x0018,0x1606, strShutterUpperHorizontalEdge,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1606,DicomConstants.DCM_DT_IS, strShutterUpperHorizontalEdge);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Referenced Shutter Upper Horizontal Edge
	 * @return String - value of Referenced Shutter Upper Horizontal Edge
	 */
	public String getShutterUpperHorizontalEdge()
	{
		Object objValue = getValue(0x0018,0x1606);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is RECTANGULAR. Location of theright edge of the rectangular shutter with respect to pixels in the image givenas column.
	 * @param strReferencedReferenceImageNumber String value of Shutter Lower HorizontalEdge.
	 */
	public void setShutterLowerHorizontalEdge(String strShutterLowerHorizontalEdge)
	{
		/*Accept the Referenced Shutter Lower HorizontalEdge(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(0x0018,0x1608, strShutterLowerHorizontalEdge,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1608,DicomConstants.DCM_DT_IS, strShutterLowerHorizontalEdge);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Referenced Shutter Lower HorizontalEdge
	 * @return String - value of Referenced Shutter Lower HorizontalEdge
	 */
	public String getShutterLowerHorizontalEdge()
	{
		Object objValue = getValue(0x0018,0x1608);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is CIRCULAR. Radius of the circularshutter with respect to pixels in the image given as a number of pixels alongthe row direction.
	 * @param strNumericValue String Value component of a Name/Value pair when the Concept implied by Concept Name
	 * Code Sequence (0018,1610) is Center Of Circular Shutter .
	 */
	public void setCenterOfCircularShutter(String strCenterOfCircularShutter)
	{
		/*Accept the Center Of Circular Shutter 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,0x1610, strCenterOfCircularShutter,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1610,DicomConstants.DCM_DT_CS, strCenterOfCircularShutter);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Center Of Circular Shutter component of a Name/Value pair
	 * @return String Array -  Value component of a Name/Value pair when the Concept implied by Concept Name
	 * Code Sequence (0018,1610) is a Center Of Circular Shutter.
	 */
	public String[] getCenterOfCircularShutter()
	{
		if(getDataElement(0x0018,0x1610)!=null)
		{
			if(getDataElement(0x0018,0x1610).getValue()!=null)
			{
				Object objValue = getDataElement(0x0018,0x1610).getValue();
				if(objValue!=null)
				{
					if(objValue instanceof String)
					{
						String strTemp = (String)objValue;
						String[] strArr = new String[1];
						strArr[0] = strTemp;
						return strArr;
					}
					else
						return (String[])objValue;
				}
			}
		}
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is CIRCULAR. Radius of the circularshutter with respect to pixels in the image given as a number of pixels alongthe row direction.
	 *  @param strReferencedReferenceImageNumber String value of Shutter Lower HorizontalEdge.
	 */
	public void setRadiusOfCircularShutter(String strRadiusOfCircularShutter)
	{
		/*Accept the Referenced Radius of Circular Shutter 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(0x0018,0x1612, strRadiusOfCircularShutter,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1612,DicomConstants.DCM_DT_IS, strRadiusOfCircularShutter);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves Referenced Radius of Circular Shutter 
	 * @return String - value of Referenced Radius of Circular Shutter 
	 */
	public String getRadiusOfCircularShutter()
	{
		Object objValue = getValue(0x0018,0x1612);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Required if Shutter Shape (0018,1600) is POLYGONAL.Multiple Values where the first set of two values are:row of the origin vertexcolumn of the origin vertex Two or more pairs of values follow and are the row and column coordinates of the other vertices of the polygon shutter. 
	 * Polygon shutters are implicitly closed from the last vertex to the origin vertex and all edges shall be non-intersecting except at the vertices. 
	 * @param strNumericValue String Value component of a Name/Value pair when the Concept implied by Concept Name
	 * Code Sequence (0018,1620) is Vertices of the Polygonal Shutter.
	 */
	public void setVerticesOfThePolygonalShutter(String strVerticesOfThePolygonalShutter)
	{
		/*Accept the Vertices of the Polygonal Shutter 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,0x1620, strVerticesOfThePolygonalShutter,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1620,DicomConstants.DCM_DT_CS, strVerticesOfThePolygonalShutter);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Vertices of the Polygonal Shutter. component of a Name/Value pair
	 * @return String Array -  Value component of a Name/Value pair when the Concept implied by Concept Name
	 * Code Sequence (0018,1620) is a Vertices of the Polygonal Shutter..
	 */
	public String[] getVerticesOfThePolygonalShutter()
	{
		if(getDataElement(0x0018,0x1620)!=null)
		{
			if(getDataElement(0x0018,0x1620).getValue()!=null)
			{
				Object objValue = getDataElement(0x0018,0x1620).getValue();
				if(objValue!=null)
				{
					if(objValue instanceof String)
					{
						String strTemp = (String)objValue;
						String[] strArr = new String[1];
						strArr[0] = strTemp;
						return strArr;
					}
					else
						return (String[])objValue;
				}
			}
		}
		return null;
	}

	/**
	 * Sets Number of significant bits within the Shutter Presentation Value
	 * @param shShutterPresentationValue short value of Number of significant bits
	 */
	public void setShutterPresentationValue(short shShutterPresentationValue)
	{
		/* Accept the ShutterPresentationValue 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(0x0018,0x1622,shShutterPresentationValue,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1622,DicomConstants.DCM_DT_US, shShutterPresentationValue);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Number of significant bits within the Shutter Presentation Value
	 * @return short - short value of Number of significant bits
	 */
	public short ShutterPresentationValue()
	{
		Object objValue = getValue(0x0018,0x1622);
		if(objValue != null)
			return Short.parseShort(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * A color triplet value used to replace those parts of the image occluded by the shutter, when rendered on a color display. The units are specified in PCS-Values, and the value is encoded as CIELab. See Section C.10.7.1.1
	 * @param arrShShutterPresentationColorCIELabValue
	 */
	public void setShutterPresentationColorCIELabValue(short[] arrShShutterPresentationColorCIELabValue)
	{
		/*Accept the Shutter Presentation Color CIELab Value in Array of 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
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0018,0x1624, arrShShutterPresentationColorCIELabValue,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1624,DicomConstants.DCM_DT_US, arrShShutterPresentationColorCIELabValue);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves one or more Shutter Presentation Color CIELab Value.
	 * @return short Array - Shutter Presentation Color CIELab Value
	 */
	public short[] getShutterPresentationColorCIELabValue()
	{
		Object objValue = getValue(0x0018,0x1624);
		if(objValue != null)
			return (short[])objValue;
		return null;
	}


	/**
	 * Validates all the attributes in Image SOP Instance Reference Macro
	 * @return boolean - Success -true, Failure -false.
	 * @throws InvalidMacroException throws InvalidMacroException If Mandatory or Conditional element fails.
	 */
	public boolean validate() throws InvalidMacroException
	{
		if(iMacroLevel == DicomConstants.DCM_MODULE_LEVEL_MACRO)
			return validate(objIDataSet);
		else if(iMacroLevel == DicomConstants.DCM_ITEM_LEVEL_MACRO)
			return validate(objIItem);
		return false;
	}
	

	/**
	 * Validates all the attributes in Display Shutter Macro Attributes that are present in the DataSet
	 * @param objIDataSet collection of DataElements
	 * @return boolean - Success -true, Failure - false
	 * @throws InvalidMacroException throws InvalidMacroException If Mandatory or Conditional element fails.
	 */
	public static boolean validate(IDataSet objIDataSet) throws InvalidMacroException
	{
		try
		{
			/*
			 * Validation Rules for Mandatory and Conditional Elements
			 */
			
			if(!objIDataSet.isPresent(0x0018,0x1600))
				throw new MandatoryMissingException("0018,1600");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIDataSet.isPresent(0x0018,0x1602))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1602 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIDataSet.isPresent(0x0018,0x1604))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1604 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIDataSet.isPresent(0x0018,0x1606))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1606 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIDataSet.isPresent(0x0018,0x1608))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1608 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.CIRCULAR))
				if(!objIDataSet.isPresent(0x0018,0x1610))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1610 required if value of Shutter Shape 0x0018, 0x1600 is CIRCULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.CIRCULAR))
				if(!objIDataSet.isPresent(0x0018,0x1612))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1612 required if value of Shutter Shape 0x0018, 0x1600 is CIRCULAR");
			if(!objIDataSet.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.POLYGONAL))
				if(!objIDataSet.isPresent(0x0018,0x1620))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1620 required if value of Shutter Shape 0x0018, 0x1600 is POLYGONAL");
					
		}
		catch(ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new ValidationException(DisplayShutterMacro.class.getClass().getSimpleName(),ce); 
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new ValidationException(DisplayShutterMacro.class.getClass().getSimpleName(),me);
		}
		catch( InvalidMacroException ime)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ime.getMessage());
			}
			throw new InvalidItemException(DisplayShutterMacro.class.getClass().getSimpleName(),ime);
		}
		return true;
	}

	/**
	 * Validates all the attributes in Image SOP Instance Reference Macro that are present in the DataSet
	 * @param objIItem collection of DataElements in a sequence
	 * @return boolean Success -true, Failure - false
	 * @throws InvalidMacroException throws InvalidMacroException If Mandatory or Conditional element fails.
	 */
	public static boolean validate(IItem objIItem) throws InvalidMacroException
	{
		try
		{
			/*
			 * Validation Rules for Mandatory and Conditional Elements
			 */
			
			if(!objIItem.contains(0x0018,0x1600))
				throw new MandatoryMissingException("0018,1600");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIItem.contains(0x0018,0x1602))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1602 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIItem.contains(0x0018,0x1604))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1604 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIItem.contains(0x0018,0x1606))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1606 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.RECTANGULAR))
				if(!objIItem.contains(0x0018,0x1608))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1608 required if value of Shutter Shape 0x0018, 0x1600 is RECTANGULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.CIRCULAR))
				if(!objIItem.contains(0x0018,0x1610))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1610 required if value of Shutter Shape 0x0018, 0x1600 is CIRCULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.CIRCULAR))
				if(!objIItem.contains(0x0018,0x1612))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1612 required if value of Shutter Shape 0x0018, 0x1600 is CIRCULAR");
			if(!objIItem.getDataForTag(0x0018, 0x1600).getValue().toString().equals(EnumShutterShape.POLYGONAL))
				if(!objIItem.contains(0x0018,0x1620))
					throw new ConditionFailedException("value for conditional Element 0x0018,0x1620 required if value of Shutter Shape 0x0018, 0x1600 is POLYGONAL");
		}
		catch(ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new ValidationException(DisplayShutterMacro.class.getClass().getSimpleName(),ce); 
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new ValidationException(DisplayShutterMacro.class.getClass().getSimpleName(),me);
		}
		catch( InvalidMacroException ime)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ime.getMessage());
			}
			throw new InvalidItemException(DisplayShutterMacro.class.getClass().getSimpleName(),ime);
		}
		return true;
	}
}
