/*******************************************************************************
 *  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.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.exceptions.MandatoryMissingException;
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 item class contains the methods to set, get and validate the attribute present in Display Sets Sequence  .
 */
public class DisplaySetsSequenceItem extends Item
{


	private static final long serialVersionUID = 1L;
	/**
	 * This constructor creates the item and internal code sequence macro with default TransferSyntax 
	 */
	DisplaySetsSequenceItem()
	{
		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
	 */
	DisplaySetsSequenceItem(ITransferSyntax objITransferSyntax)
	{
		super(objITransferSyntax);
	}

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

	public boolean validateForModule()  throws InvalidItemException
	{
		try
		{
			if(!contains(0x0072,0x0202))
				throw new MandatoryMissingException("0072,0202") ;
			if(!contains(0x0072,0x0204))
				throw new MandatoryMissingException("0072,0202") ;
			if(!contains(0x0072,0x0032))
				throw new MandatoryMissingException("0072,0032") ;
			if(!contains(0x0072,0x0300))
				throw new MandatoryMissingException("0072,0300") ;
			
		}
		catch( MandatoryMissingException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),ce); 
		}
		return true;
	}
	/**
	 * Set DisplaySetNumber
	 * It shall be used to identify linked display sets in the Display Set Scrolling Group (0072,0212).
	 * @return short Array - frames in a Multi-frame SOP Instance.
	 */
	public void setDisplaySetNumber(short[] arrDisplaySetNumber)
	{
		/* Accept the Referenced Frame Numbers in Array of short format of type US.
		 * A monotonically increasing integer, starting from 1, incrementing by 1, 
		 * unique within the Hanging Protocol Instance.
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)	
			objIDataElement = new ImplicitDE(0x0072, 0x0202, arrDisplaySetNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072, 0x0202,DicomConstants.DCM_DT_US, arrDisplaySetNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Display Set Number.
	 * @return short Array - Display Set Number SOP Instance.
	 */
	public short[] getDisplaySetNumber()
	{
		Object objValue = getValue(0x0072, 0x0202);
		if(objValue != null)
			return (short[])objValue;
		return null;
	}
	
	/**
	 * Sets Display Set Label.
	 * @param strDisplaySetLabel String value of strDisplaySetLabel Type.
	 */
	public void setDisplaySetLabel(String strDisplaySetLabel)
	{
		/* Accept the strDisplaySetLabel Type in String format of type LO.
		 * 
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0203, strDisplaySetLabel,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0203,DicomConstants.DCM_DT_LO, strDisplaySetLabel);

		addDataElement(objIDataElement);
	}

	/**
	 * Return user-defined label identifier for strDisplaySetLabel.
	 * @return String - value of strDisplaySetLabel Type.
	 */
	public String getRescaleType()
	{
		Object objValue = getValue(0x0072,0x0203);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	
	/**
	 * Sets Display Set Presentation Group.
	 * Positive integer value that designates this Display Set as part of a specific presentation group. 
	 * All Display Sets with the same Display Set Presentation Group (0072,0204) value shall be displayed at the same time.
	 * @param strDisplaySetPresentationGroup String value of strDisplaySetPresentationGroup Type.
	 */
	public void setDisplaySetPresentationGroup(String strDisplaySetPresentationGroup)
	{
		/* Accept the strDisplaySetLabel Type in String format of type LO.
		 * The value 1 shall indicate that this Display Set is part of the initial presentation group. 
		 * Subsequent values incrementing by 1 shall imply successive temporal ordering of display.
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0204, strDisplaySetPresentationGroup,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0204,DicomConstants.DCM_DT_LO, strDisplaySetPresentationGroup);

		addDataElement(objIDataElement);
	}

	/**
	 * Return user-defined label identifier for DisplaySetPresentationGroup.
	 * @return String - value of strDisplaySetLabel Type.
	 */
	public String getDisplaySetPresentationGroup()
	{
		Object objValue = getValue(0x0072,0x0204);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	

	/**
	 * Sets Image Set Number.
	 * Image Set Number (0072,0032) value from a Time Based Image Sets Sequence (0072,0030) Item within the Image Sets Sequence (0072,0020) 
	 * Item that is selected for display by this Display Set.
	 * @param strImageSetNumber String value of strImageSetNumber Type.
	 */
	public void setImageSetNumber(String strImageSetNumber)
	{
		/* Accept the strImageSetNumber Type in String format of type LO.
		 * Image Set Number (0072,0032) value from a Time Based Image Sets Sequence (0072,0030)
		 * Multiple Image Boxes Sequence (0072,0300) Items within a Display Sets Sequence (0072,0200) 
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0072,0x0032, strImageSetNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0072,0x0032,DicomConstants.DCM_DT_LO, strImageSetNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Return user-defined label identifier for Image Set Number.
	 * @return String - value of strImageSetNumber Type.
	 */
	public String getImageSetNumber()
	{
		Object objValue = getValue(0x0072,0x0032);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Retrieves pre-initialized object of Image Boxes 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 ImageBoxesSequence - instance of ImageBoxesSequence. 
	 */
	public ImageBoxesSequence getImageBoxesSequence()
	{
		ImageBoxesSequence objImageBoxesSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0072, 0x0300);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objImageBoxesSequence = (ImageBoxesSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objImageBoxesSequence = (ImageBoxesSequence)objDicomV3Factory.createSequence(0x0072, 0x0300, objITransferSyntax, objIDictionaryReader);

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

}
