/*******************************************************************************
 *  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.EnumArchiveRequested;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidItemException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;




/**
* This item class contains methods to validate, set and get attributes in {@link PerformedSeriesSequence}
 */
public class PerformedSeriesSequenceItem extends Item  
{
	

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * This constructor creates the item and with default TransferSyntax 
	 */
	PerformedSeriesSequenceItem()
	{
		super();
	}

	/*
	 * This constructor calls the respective superclass constructor
	 * This constructor should throw exception if null TS is tried to be set
	 */
	/**
	 * This constructor creates Item with specified transferSyntax
	 * @param objTransferSyntax specifies the DICOM Standard defined TransfeSyntax
	 */
	PerformedSeriesSequenceItem(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 
	 */
	PerformedSeriesSequenceItem(ITransferSyntax objTransferSyntax, IDictionaryReader objDictionaryReader)
	{
		super(objTransferSyntax,objDictionaryReader);
	}

	/**
	 * Validates all the attributes in Presentation LUT Sequence Item 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
	{
		return true;
	}

	/**
	 * Sets Name of the physician(s) administering this Series.
	 * @param arrStrPerformingPhysiciansName String array of Name of the physician(s) administering this Series.
	 */	
	public void setPerformingPhysiciansName(String[] arrStrPerformingPhysiciansName)
	{
		/*Accept Performing Physicians Name in String Array format of type PN.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0008,0x1050,arrStrPerformingPhysiciansName,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0008,0x1050, DicomConstants.DCM_DT_PN,arrStrPerformingPhysiciansName);
		addDataElement(objIDataElement);
	}

	/**
	 * Return Name of the physician(s) administering this Series.
	 * @return String[]- String array of Name of the physician(s) administering this Series.
	 */
	public String[] getPerformingPhysiciansName()
	{
		Object objValue = getValue(0x0008,0x1050);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}

	/**
	 * Retrieves pre-initialized object of Performing Physician Identification 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 PerformingPhysicianIdentificationSequence - instance of Performing Physician Identification Sequence 
	 */
	public PerformingPhysicianIdentificationSequence getPerformingPhysicianIdentificationSequence()
	{
		PerformingPhysicianIdentificationSequence objPerformingPhysicianIdentificationSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008,0x1052);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objPerformingPhysicianIdentificationSequence = (PerformingPhysicianIdentificationSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objPerformingPhysicianIdentificationSequence = (PerformingPhysicianIdentificationSequence)objDicomV3Factory.createSequence(0x0008,0x1052, objITransferSyntax, objIDictionaryReader);

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


	/**
	 * Sets Name(s) of the operator(s) who supporting this Series.
	 * @param arrStrOperatorsName String array of Name(s) of the operator(s). 
	 */	
	public void setOperatorsName(String[] arrStrOperatorsName)
	{
		/*Accept Name(s) of the operator(s)in String Array format of type PN.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0008,0x1070,arrStrOperatorsName,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0008,0x1070, DicomConstants.DCM_DT_PN,arrStrOperatorsName);
		addDataElement(objIDataElement);
	}

	/**
	 * Return Name(s) of the operator(s) who supporting this Series.
	 * @return String[]- String array of Name(s) of the operator(s).
	 */
	public String[] getOperatorsName()
	{
		Object objValue = getValue(0x0008,0x1070);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}


	/**
	 * Retrieves pre-initialized object of Operator Identification 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 OperatorIdentificationSequence - instance of Operator Identification Sequence
	 */
	public OperatorIdentificationSequence getOperatorIdentificationSequence()
	{
		OperatorIdentificationSequence objOperatorIdentificationSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008,0x1072);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objOperatorIdentificationSequence = (OperatorIdentificationSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objOperatorIdentificationSequence = (OperatorIdentificationSequence)objDicomV3Factory.createSequence(0x0008,0x1072, objITransferSyntax, objIDictionaryReader);

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

	/**
	 * Sets attribute identifies User-defined description of the conditions under which the Series was performed.
	 * @param StrProtocolName String User-defined description 
	 */	
	public void setProtocolName(String StrProtocolName)
	{
		/*Accept Procol Nmae in String format of type LO.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0018,0x1030,StrProtocolName,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0018,0x1030, DicomConstants.DCM_DT_LO,StrProtocolName);
		addDataElement(objIDataElement);
	}

	/**
	 * Return User-defined description of the conditions under which the Series was performed.
	 * @return String - User-defined description.
	 */
	public String getProtocolName()
	{
		Object objValue = getValue(0x0018,0x1030);
		if(objValue != null)
			return objValue.toString();
		return null;
	}


	/**
	 * Sets attribute identifies Unique Identifier of the Series.
	 * @param StrSeriesInstanceUID String Unique Identifier.
	 */	
	public void setSeriesInstanceUID(String StrSeriesInstanceUID)
	{
		/*Accept Unique Identifier in String format of type UI.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0020,0x000E,StrSeriesInstanceUID,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0020,0x000E, DicomConstants.DCM_DT_UI,StrSeriesInstanceUID);
		addDataElement(objIDataElement);
	}

	/**
	 * Return Unique Identifier of the Series.
	 * @return String - Unique Identifier.
	 */
	public String getSeriesInstanceUID()
	{
		Object objValue = getValue(0x0020,0x000E);
		if(objValue != null)
			return objValue.toString();
		return null;
	}


	/**
	 * Sets attribute identifies User provided description of the Series
	 * @param StrSeriesDescription String User provided description
	 */	
	public void setSeriesDescription(String StrSeriesDescription)
	{
		/*Accept Series Description in String format of type LO.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0008,0x103E,StrSeriesDescription,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0008,0x103E, DicomConstants.DCM_DT_LO,StrSeriesDescription);
		addDataElement(objIDataElement);
	}

	/**
	 * Return User provided description of the Series
	 * @return String - User provided description
	 */
	public String getSeriesDescription()
	{
		Object objValue = getValue(0x0008,0x103E);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Retrieves pre-initialized object of Series Description Code 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 SeriesDescriptionCodeSequence - instance of SeriesDescriptionCodeSequence. 
	 */
	public SeriesDescriptionCodeSequence getSeriesDescriptionCodeSequence()
	{
		SeriesDescriptionCodeSequence objSeriesDescriptionCodeSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0008, 0x103F);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objSeriesDescriptionCodeSequence = (SeriesDescriptionCodeSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objSeriesDescriptionCodeSequence = (SeriesDescriptionCodeSequence)objDicomV3Factory.createSequence(0x0008, 0x103F, objITransferSyntax, objIDictionaryReader);

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

	/**
	 * Sets Title of the DICOM Application Entity where the Images and Standalone SOP Instances in 
	 * this Series may be retrieved on the network.
	 * @param arrStrRetrieveAETitle String array of Title of the DICOM Application Entity
	 */	
	public void setRetrieveAETitle(String[] arrStrRetrieveAETitle)
	{
		/*Accept Retrieve AE Title in String Array format of type AE.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0008,0x0054,arrStrRetrieveAETitle,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0008,0x0054, DicomConstants.DCM_DT_AE,arrStrRetrieveAETitle);
		addDataElement(objIDataElement);
	}

	/**
	 * Return Title of the DICOM Application Entity where the Images and Standalone SOP Instances in 
	 * this Series may be retrieved on the network.
	 * @return String[]- String array of Title of the DICOM Application Entity
	 */
	public String[] getRetrieveAETitle()
	{
		Object objValue = getValue(0x0008,0x0054);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}

	
	
	
	/**
	 * Sets the ArchiveRequested Defined in Terms of TEXT,NUMERIC,CODE,DATE,TIME,PNAME
	 * @param enumArchiveRequested Specifies type of the value encoded in this Item
	 */
	public void setArchiveRequested(EnumArchiveRequested enumArchiveRequested)
	{
		/* Accept the Archive Requested in String format of type CS.
		 * 
		 * Add this element to the Data Set
		 */
		IDataElement objIDataElement = null;
		if(objITransferSyntax.getVRTransferSyntax() == DicomConstants.DCM_VR_IMPLICIT)
			objIDataElement = new ImplicitDE(0x0040, 0xA494, enumArchiveRequested,getDictionaryReader());
		else
			objIDataElement = new ExplicitDE(0x0040, 0xA494,DicomConstants.DCM_DT_CS, enumArchiveRequested);

		addDataElement(objIDataElement);
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getArchiveRequested()
	{
		Object objValue = getValue(0x0040, 0xA494);
		if(objValue != null)
			return objValue.toString();
		return null;
	}


	
	
	
	/**
	 * 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);
		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 Non Image Composite SOP 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 ReferencedNonImageCompositeSOPInstanceSequence - instance of Referenced Non-Image Composite SOP Instance Sequence
	 */
	public ReferencedNonImageCompositeSOPInstanceSequence getReferencedNonImageCompositeSOPInstanceSequence()
	{
		ReferencedNonImageCompositeSOPInstanceSequence objReferencedNonImageCompositeSOPInstanceSequence = null;
		IDataElement objIDataElement =  getDataForTag(0x0040,0x0220);
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objReferencedNonImageCompositeSOPInstanceSequence = (ReferencedNonImageCompositeSOPInstanceSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objReferencedNonImageCompositeSOPInstanceSequence = (ReferencedNonImageCompositeSOPInstanceSequence)objDicomV3Factory.createSequence(0x0040,0x0220, objITransferSyntax, objIDictionaryReader);

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