/*******************************************************************************
 *  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.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomValue;
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.InvalidMacroException;
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 macro records the context for a set of collected display QA results: when they were produced, the person/device that produced them.
 */
public class DisplayQAResultContextMacro extends Macro
{
	

	private static final long serialVersionUID = 1L;


	/**
	 * This constructor constructs a Macro with specified DataSet.
	 * @param objDataSet Collection of DataElements 
	 */
	public DisplayQAResultContextMacro(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 DisplayQAResultContextMacro(IDataSet objDataSet,IDictionaryReader objDictionaryReader)
	{
		super(objDataSet,objDictionaryReader);
	}

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

	/**
	 * This constructor constructs a Macro with the specified Item and DictionaryReader
	 * @param objItem specifies instance of Item class
	 * @param objDictionaryReader specifies the DICOM Dictionary reader to be used 
	 */
	public DisplayQAResultContextMacro(IItem objItem,IDictionaryReader objDictionaryReader)
	{
		super(objItem, objDictionaryReader);
	}

	/**
	 * Validates all the attributes in DisplayQAResultContextMacro
	 * @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 DisplayQAResultContextMacro 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
		{ 

			//validate condition here
		}
		catch( ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidMacroException( LensometryMeasurementsMacro.class.getSimpleName() ,ce); 
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new InvalidMacroException(LensometryMeasurementsMacro.class.getSimpleName() ,me);
		}
		return true;
	}

	/**
	 * Validates all the attributes in DisplayQAResultContextMacro 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
		{  
			//validate condition here
		}
		catch( ConditionFailedException ce)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(ce.getMessage());
			}
			throw new InvalidMacroException(LensometryMeasurementsMacro.class.getSimpleName(),ce); 
		}
		catch( MandatoryMissingException me)
		{
			if(DicomConfig.createInstance().isLoggingOn())
			{
				DicomLogger.getLogger().log(me.getMessage());
			}
			throw new InvalidMacroException(LensometryMeasurementsMacro.class.getSimpleName(),me);
		}
		return true;
	}
	
	/**
	 * Sets Date and Time at which the QA job that generated the results started
	 * @param strPerformedProcedureStepStartDateTime String value of Date and Time at which the QA job that generated the results started
	 */
	public void setPerformedProcedureStepStartDateTime(String strPerformedProcedureStepStartDateTime)
	{
		/* Accept the PerformedProcedureStepStartDateTime of type DT.
		 * 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(0x0040,0x4050,strPerformedProcedureStepStartDateTime,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0040,0x4050,DicomConstants.DCM_DT_DT, strPerformedProcedureStepStartDateTime);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Date and Time at which the QA job that generated the results started
	 * @return String - value of Date and Time at which the QA job that generated the results started
	 */
	public String getPerformedProcedureStepStartDateTime()
	{
		Object objValue = getValue(0x0040,0x4050);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	
	/**
	 * Sets Date and Time at which the QA job that generated the results ended.
	 * @param strPerformedProcedureStepEndDateTime String value of Date and Time at which the QA job that generated the results ended.
	 */
	public void setPerformedProcedureStepEndDateTime(String strPerformedProcedureStepEndDateTime)
	{
		/* Accept the PerformedProcedureStepEndDateTime of type DT.
		 * 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(0x0040,0x4051,strPerformedProcedureStepEndDateTime,objIDictionaryReader);
		else
			objIDataElement = new ExplicitDE(0x0040,0x4051,DicomConstants.DCM_DT_DT, strPerformedProcedureStepEndDateTime);

		addDataElement(objIDataElement);
	}

	/**
	 * Retrieves Date and Time at which the QA job that generated the results ended.
	 * @return String - value of Date and Time at which the QA job that generated the results ended.
	 */
	public String getPerformedProcedureStepEndDateTime()
	{
		Object objValue = getValue(0x0040,0x4051);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * Retrieves pre-initialized object of Actual Human Performers 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 ActualHumanPerformersSequence - instance of ActualHumanPerformersSequence. 
	 */
	public ActualHumanPerformersSequence getActualHumanPerformersSequence()
	{
		ActualHumanPerformersSequence objActualHumanPerformersSequence = null;
		IDataElement objIDataElement =  getDataElement(0x0040,0x4035); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objActualHumanPerformersSequence = (ActualHumanPerformersSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objActualHumanPerformersSequence = (ActualHumanPerformersSequence)objDicomV3Factory.createSequence(0x0040,0x4035, objITransferSyntax, objIDictionaryReader);

			if(iVRTransferSyntax == DicomConstants.DCM_VR_IMPLICIT)
				objIDataElement = new ImplicitDE(0x0040,0x4035, objActualHumanPerformersSequence.getValue(), objIDictionaryReader);
			else
				objIDataElement = new ExplicitDE(0x0040,0x4035, DicomConstants.DCM_DT_SQ, objActualHumanPerformersSequence.getValue());
			objIDataElement.setTransferSyntax(objITransferSyntax);
			if(objIDataElement != null)
				addDataElement(objIDataElement);
		}
		return objActualHumanPerformersSequence;
	}
	
	/**
	 * Retrieves pre-initialized object of Measurement Equipment 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 MeasurementEquipmentSequence - instance of MeasurementEquipmentSequence. 
	 */
	public MeasurementEquipmentSequence getMeasurementEquipmentSequence()
	{
		MeasurementEquipmentSequence objMeasurementEquipmentSequence = null;
		IDataElement objIDataElement =  getDataElement(0x0028, 0x7012); //getDataElement
		if(objIDataElement != null)
		{
			IDicomValue objIDicomValue = objIDataElement.getDicomValue();
			if(objIDicomValue != null)
				objMeasurementEquipmentSequence = (MeasurementEquipmentSequence)objIDicomValue;
		}
		else
		{
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			int iVRTransferSyntax = objITransferSyntax.getVRTransferSyntax();
			objIDataElement = null;
			objMeasurementEquipmentSequence = (MeasurementEquipmentSequence)objDicomV3Factory.createSequence(0x0028, 0x7012, objITransferSyntax, objIDictionaryReader);

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

	
	
	
	
	
	
	
	
}
