/*******************************************************************************
 *  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;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
/**
* This item class contains the methods to set, get and validate the attribute present in HPGL Document Sequence.
 */

public class HPGLDocumentSequenceItem extends CodeSequenceMacroDependentItem
{
	
	private static final long serialVersionUID = 1L;

	/**
	 * This constructor creates the item and internal code sequence macro with default TransferSyntax 
	 * and default DictionaryReader
	 */
	HPGLDocumentSequenceItem()
	{
		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 objTransferSyntax specifies the DICOM Standard defined TransfeSyntax  
	 */
	HPGLDocumentSequenceItem(ITransferSyntax objITransferSyntax)
	{
		super(objITransferSyntax);
	}
	/**
	 * This constructor creates Item with specified transferSyntax and specified DictionaryReader
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	HPGLDocumentSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}

	/**
	 * Validates all the attributes in HPGLDocumentSequenceItem 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(0x0068,0x62D0))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,62D0");
			if(!contains(0x0068,0x6340))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,62E0");
			if(!contains(0x0068,0x62F2))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,62F2");
			if(!contains(0x0068,0x6300))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,6300");
			if(!contains(0x0068,0x6310))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,6310");
			if(!contains(0x0068,0x6320))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,6320");
			if(!contains(0x0068,0x6346))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,6346");
			if(!contains(0x0068,0x6347))
				throw new MandatoryMissingException("Mandatory Element Missing 0068,6347");
						
		}
		catch( MandatoryMissingException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidItemException(this.getClass().getSimpleName(),ce); 
		}
		return true;
	}
	/**
	 * Sets HPGL Document ID
	 * @param shHPGLDocumentID short value of HPGL Document ID
	 */
	public void setHPGLDocumentIDshort (short shHPGLDocumentID)
	{
		/* Accept the HPGL Document ID 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(0x0068,0x62D0,shHPGLDocumentID,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x62D0,DicomConstants.DCM_DT_US, shHPGLDocumentID);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves HPGL Document ID
	 * @return short - short value of HPGL Document ID
	 */
	public short getHPGLDocumentID()
	{
		Object objValue = getValue(0x0068,0x62D0);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets HPGL Document Label.
	 * @param strHPGLDocumentLabel String value of HPGLDocumentLabel
	 */
	public void setHPGLDocumentLabel(String strHPGLDocumentLabel)
	{
		/* Accept the HPGLDocumentLabel 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(0x0068,0x62D5, strHPGLDocumentLabel,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x62D5,DicomConstants.DCM_DT_LO, strHPGLDocumentLabel);

		addDataElement(objIDataElement);
	}

	/**
	 * Return HPGL Document Label
	 * @return String - value of HPGLDocumentLabel
	 */
	public String getHPGLDocumentLabel()
	{
		Object objValue = getValue(0x0068,0x62D5);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Retrieves pre-initialized object of ViewOrientationCodeSequence.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 ViewOrientationCodeSequence - instance of ViewOrientationCodeSequence. 
	 */
	public ViewOrientationCodeSequence getViewOrientationCodeSequence()
	{
		ViewOrientationCodeSequence objViewOrientationCodeSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0068, 0x62E0); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objViewOrientationCodeSequence = (ViewOrientationCodeSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objViewOrientationCodeSequence = (ViewOrientationCodeSequence)objDicomV3Factory.createSequence(0x0068, 0x62E0, objITransferSyntax, objIDictionaryReader);

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

	/**
	 * Sets the View Orientation Modifier
	 * @param dblArrViewOrientationModifier Double value of ViewOrientationModifier
	 */
	public void setViewOrientationModifier(double[] dblArrViewOrientationModifier)
	{
		/*Accept the View Orientation Modifier 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(0x0068,0x62F0, dblArrViewOrientationModifier,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x62F0,DicomConstants.DCM_DT_FD, dblArrViewOrientationModifier);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the View Orientation Modifier
	 * @return double - double value of ViewOrientationModifier
	 */
	public double[] getViewOrientationModifier()
	{
		Object objValue = getValue(0x0068,0x62F0);
		if(objValue != null)
			return (double[])objValue;
		return null;
	}
	/**
	 * Sets the HPGL Document Scaling.
	 * @param dblHPGLDocumentScaling Double value of HPGLDocumentScaling
	 */
	public void setHPGLDocumentScaling(double dblHPGLDocumentScaling)
	{
		/*Accept the HPGLDocumentScaling 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(0x0068,0x62F2, dblHPGLDocumentScaling,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x62F2,DicomConstants.DCM_DT_FD, dblHPGLDocumentScaling);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves HPGL Document Scaling
	 * @return double - double value of HPGLDocumentScaling
	 */
	public double getHPGLDocumentScaling()
	{
		Object objValue = getValue(0x0068,0x62F2);
		if(objValue != null)
			return Double.parseDouble(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets the HPGL document as a byte stream
	 * @param vectHPGLDocument collection of byte array of HPGL document
	 */
	public void setHPGLDocument(ISingleCollection<byte[]> vectHPGLDocument)
	{
		/*Accept the HPGL document as a byte stream in vector of byte array format of type OB.
		 * 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(0x0068, 0x6300, vectHPGLDocument,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068, 0x6300,DicomConstants.DCM_DT_OB, vectHPGLDocument);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves HPGL document as a byte stream
	 * @return ISingleCollection<byte[]> - collection of byte array of HPGL document 
	 */
	@SuppressWarnings("unchecked")
	public ISingleCollection<byte[]> getHPGLDocument()
	{
		Object objValue = getValue(0x0068, 0x6300);
		if(objValue != null)
			return (ISingleCollection<byte[]>)objValue;
		return null;
	}
	/**
	 * Sets HPGL Contour Pen Number
	 * @param shHPGLContourPenNumber short value of HPGL Contour Pen Number
	 */
	public void setHPGLContourPenNumber(short shHPGLContourPenNumber)
	{
		/* Accept the HPGL Contour Pen 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(0x0068,0x6310,shHPGLContourPenNumber,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x6310,DicomConstants.DCM_DT_US, shHPGLContourPenNumber);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves HPGL Contour Pen Number
	 * @return short - short value of HPGL Contour Pen Number
	 */
	public short getHPGLContourPenNumber()
	{
		Object objValue = getValue(0x0068,0x6310);
		if(objValue != null)
			return Short.parseShort(objValue.toString());

		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Retrieves pre-initialized object of HPGLPenSequence.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 HPGLPenSequence - instance of HPGLPenSequence. 
	 */
	public HPGLPenSequence getHPGLPenSequence()
	{
		HPGLPenSequence objHPGLPenSequencee = null;
		IDataElement objIDataElement =  getDataForTag(0x0068, 0x6320); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objHPGLPenSequencee = (HPGLPenSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objHPGLPenSequencee = (HPGLPenSequence)objDicomV3Factory.createSequence(0x0068, 0x6320, objITransferSyntax, objIDictionaryReader);

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

	

	/**
	 * Sets the Recommended Rotation Point
	 * @param dblArrRecommendedRotationPoint Double value of Recommended Rotation Point
	 */
	public void setRecommendedRotationPoint(double[] dblArrRecommendedRotationPoint)
	{
		/*Accept the Recommended Rotation Point 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(0x0068,0x6346, dblArrRecommendedRotationPoint,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x6346,DicomConstants.DCM_DT_FD, dblArrRecommendedRotationPoint);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the Recommended Rotation Point
	 * @return double - double value of Recommended Rotation Point
	 */
	public double[] getRecommendedRotationPoint()
	{
		Object objValue = getValue(0x0068,0x6346);
		if(objValue != null)
			return (double[])objValue;
		return null;
	}
	
	

	/**
	 * Sets the Bounding Rectangle
	 * @param dblArrBoundingRectangle Double value of BoundingRectangle
	 */
	public void setBoundingRectangle(double[] dblArrBoundingRectangle)
	{
		/*Accept the BoundingRectangle 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(0x0068,0x6347, dblArrBoundingRectangle,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0068,0x6347,DicomConstants.DCM_DT_FD, dblArrBoundingRectangle);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves the Bounding Rectangle
	 * @return double - double value of BoundingRectangle
	 */
	public double[] getBoundingRectangle()
	{
		Object objValue = getValue(0x0068,0x6347);
		if(objValue != null)
			return (double[])objValue;
		return null;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
