/*******************************************************************************
 *  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.IDictionaryReader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITransferSyntax;
import cdac.medinfo.sdk.dcm30_04.enums.EnumFilmOrientation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumFilmSizeID;
import cdac.medinfo.sdk.dcm30_04.enums.EnumImageDisplayFormat;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRequestedImageSizeFlag;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRequestedResolutionID;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;

/**
* This item class contains the methods to set,get and validate the attribute present in Supported Image Display Formats Sequence Item.
 */
public class SupportedImageDisplayFormatsSequenceItem extends Item  
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

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

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

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

	/**
	 * Sets Number of printable rows in an Image Box.
	 * @param shRows short value of Number of printable rows in an Image Box.
	 */
	public void setRows(short shRows)
	{
		/* Accept the Rows 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(0x0028,0x0010, shRows,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0028,0x0010,DicomConstants.DCM_DT_US, shRows);

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Number of printable rows in an Image Box.
	 * @return short - short value of Number of printable rows in an Image Box.
	 */
	public short getRows()
	{
		Object objValue = getValue(0x0028,0x0010);
		if(objValue != null)
			return Short.parseShort(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Number of printable Columns in an Image Box.
	 * @param shColumns short value of Number of printable Columns in an Image Box.
	 */
	public void setColumns(short shColumns)
	{
		/* Accept the Columns 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(0x0028,0x0011, shColumns,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0028,0x0011,DicomConstants.DCM_DT_US, shColumns);

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Number of printable Columns in an Image Box.
	 * @return short - short value of Number of printable Columns in an Image Box.
	 */
	public short getColumns()
	{
		Object objValue = getValue(0x0028,0x0011);
		if(objValue != null)
			return Short.parseShort(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Type of image display format.
	 * Enumerated Values:
	 * STANDARD\C,R : film contains equal size rectangular image boxes with R rows of image boxes and C columns of image boxes; C and R are integers
	 * ROW\R1,R2,R3, etc. : film contains rows with equal size rectangular image boxes with R1 image boxes in the first row, R2 image boxes in second row, R3 image boxes in third row, etc.; R1, R2, R3, etc. are integers.
	 * COL\C1,C2,C3, etc.: film contains columns with equal size rectangular image boxes with C1 image boxes in the first column, C2 image boxes in second column, C3 image boxes in third column, etc.; C1, C2, C3, etc. are integers.
	 * SLIDE : film contains 35mm slides; the number of slides for a particular film size is configuration dependent.
	 * SUPERSLIDE : film contains 40mm slides; the number of slides for a particular film size is configuration dependent.
	 * CUSTOM\i : film contains a customized ordering of rectangular image boxes; i identifies the image display format; the definition of the image display formats is defined in the Conformance Statement; i formats is defined in the Conformance Statement; i
	 * @param enumImageDisplayFormat enum value of Image Display Format.
	 */
	public void setImageDisplayFormat(EnumImageDisplayFormat enumImageDisplayFormat)
	{
		/* Accept the Image Display Format of type ST.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x2010,0x0010, enumImageDisplayFormat.getValue() ,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2010,0x0010,DicomConstants.DCM_DT_ST, enumImageDisplayFormat.getValue());

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Type of image display format.
	 * @return String - value of image display format.
	 */
	public String getImageDisplayFormat()
	{
		Object objValue = getValue(0x2010,0x0010);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets Film orientation. Enumerated Values:
	 * PORTRAIT = vertical film position
	 * LANDSCAPE = horizontal film position
	 * @param enumFilmOrientation enum value of Film Orientation.
	 */
	public void setFilmOrientation(EnumFilmOrientation enumFilmOrientation)
	{
		/* Accept the Image Display Format of type ST.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x2010,0x0040, enumFilmOrientation.getValue() ,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2010,0x0040,DicomConstants.DCM_DT_CS, enumFilmOrientation.getValue());

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Film orientation.
	 * @return String - value of Film orientation.
	 */
	public String getFilmOrientation()
	{
		Object objValue = getValue(0x2010,0x0040);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets Film size identification.
	 * Defined Terms: 
	 * 8INX10IN, 8_5INX11IN, 10INX12IN ,10INX14IN, 11INX14IN, 11INX17IN, 14INX14IN, 14INX17IN, 24CMX24CM, 24CMX30CM, A4, A3.
	 * @param enumFilmSizeID Enum value of Film Size ID.
	 */
	public void setFilmSizeID(EnumFilmSizeID enumFilmSizeID)
	{
		/* Accept the Film Size ID 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(0x2010,0x0050, enumFilmSizeID.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2010,0x0050,DicomConstants.DCM_DT_CS, enumFilmSizeID.getValue());

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Film size identification.
	 * @return String - value of Film size identification.
	 */
	public String getFilmSizeID()
	{
		Object objValue = getValue(0x2010,0x0050);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets Printer Resolution identification. Defined Terms are the same as Requested Resolution ID (2020,0050).
	 * @param enumPrinterResolutionID Enum value of Printer Resolution ID.
	 */
	public void setPrinterResolutionID(EnumRequestedResolutionID enumPrinterResolutionID)
	{
		/* Accept the Printer Resolution ID 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(0x2010,0x0052, enumPrinterResolutionID.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2010,0x0052,DicomConstants.DCM_DT_CS, enumPrinterResolutionID.getValue());

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves  Printer Resolution identification.
	 * @return String - value of  Printer Resolution identification.
	 */
	public String getPrinterResolutionID()
	{
		Object objValue = getValue(0x2010,0x0052);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Sets Physical distance on the printed film between the center of each pixel, specified by a numeric pair - 
	 * adjacent row spacing (delimiter) adjacent column spacing in mm.
	 * @param strArrPrinterPixelSpacing String array of Printer Pixel Spacing.
	 */
	public void setPrinterPixelSpacing(String[] strArrPrinterPixelSpacing)
	{
		/* Accept the Printer Pixel Spacing 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 Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x2010,0x0376, strArrPrinterPixelSpacing,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2010,0x0376,DicomConstants.DCM_DT_DS, strArrPrinterPixelSpacing);

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves  Printer Pixel Spacing.
	 * @return String - value of  Printer Pixel Spacing.
	 */
	public String[] getPrinterPixelSpacing()
	{
		Object objValue = getValue(0x2010,0x0376);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}

	/**
	 * Indicates whether the printer supports Requested Image Size (2020,0030) for this display format and film orientation and size combination.
	 * Enumerated Values:
	 * NO = not supported,
	 * YES = supported
	 * @param enumRequestedImageSizeFlag Enum value of Requested Image Size Flag.
	 */
	public void setRequestedImageSizeFlag(EnumRequestedImageSizeFlag enumRequestedImageSizeFlag)
	{
		/* Accept the Requested Image Size Flag 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(0x2020,0x00A0, enumRequestedImageSizeFlag.getValue(),getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x2020,0x00A0,DicomConstants.DCM_DT_CS, enumRequestedImageSizeFlag.getValue());

		addDataElement(objIDataElement);

	}

	/**
	 * Retrieves Requested Image Size Flag
	 * @return String - value of  Requested Image Size Flag.
	 */
	public String getRequestedImageSizeFlag()
	{
		Object objValue = getValue(0x2020,0x00A0);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * Validates all the attributes in SupportedImageDisplayFormatsSequenceItem that are present in the DataSet
	 * @return boolean - Success -true, Failure - false
	 * @throws InvalidItemException throws InvalidItemException Conditional element fails.
	 */
	public boolean validateForModule()  throws InvalidItemException
	{
		return true;
	}
}
