/*******************************************************************************
 *  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.dicommodel.modules;



import cdac.medinfo.sdk.dcm30_04.baselibs.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.RequestedProcedureCodeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.RequestingPhysicianIdentificationSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.Tag;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidModuleException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

//TODO: Auto-generated Javadoc
/**
\* This module specifies the Attributes that describe Study Scheduling Module.
*/
public class StudySchedulingModule extends Module  
{

 
 /**
  * The obj single collection.
  */
 public static ISingleCollection<ITag> objSingleCollection = null;
	 

	/**
	 * Instantiates a new study scheduling module.
	 * 
	 * @param objIDataSet the obj i data set
	 */
	public StudySchedulingModule(IDataSet objIDataSet)
	{
		super(objIDataSet);
	}

	static
	{
		objSingleCollection = new SingleCollection<ITag>();
		objSingleCollection.add(new Tag(0x0032,0x1000));
		objSingleCollection.add(new Tag(0x0032,0x1001));
		objSingleCollection.add(new Tag(0x0032,0x1010));
		objSingleCollection.add(new Tag(0x0032,0x1011));
		objSingleCollection.add(new Tag(0x0032,0x1020));
		objSingleCollection.add(new Tag(0x0032,0x1021));
		objSingleCollection.add(new Tag(0x0032,0x1030));
		objSingleCollection.add(new Tag(0x0032,0x1032));
		objSingleCollection.add(new Tag(0x0032,0x1031));
		objSingleCollection.add(new Tag(0x0032,0x1033));
		objSingleCollection.add(new Tag(0x0032,0x1060));
		objSingleCollection.add(new Tag(0x0032,0x1064));
		objSingleCollection.add(new Tag(0x0032,0x1070));
	}

	/* (non-Javadoc)
	 * @see cdac.medinfo.sdk.dcm30_04.dicommodel.modules.Module#validateModule()
	 */
	public boolean validateModule()throws InvalidModuleException
	{
		return true;
	}

	/**
	 * Sets Date on which the study is scheduled to start.
	 * 
	 * @param strScheduledStudyStartDate String value of Scheduled Study Start Date.
	 */
	public void setScheduledStudyStartDate(String strScheduledStudyStartDate)
	{
		/*Accept User or equipment generated Scheduled Study Start Date in String format of type DA.
		 * 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 Hash Map
		 */
		addDataElement(0x0032,0x1000, DicomConstants.DCM_DT_DA, strScheduledStudyStartDate);
	}

	/**
	 * Sets Time at which the study is scheduled to start.
	 * 
	 * @param strScheduledStudyStartTime String value of Scheduled Study Start Time.
	 */
	public void setScheduledStudyStartTime(String strScheduledStudyStartTime)
	{
		/*Accept User or equipment generated Scheduled Study Start Time in String format of type TM.
		 * 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 Hash Map
		 */
		addDataElement(0x0032,0x1001, DicomConstants.DCM_DT_TM, strScheduledStudyStartTime);
	}

	/**
	 * Sets Date on which the patient examination for the study is scheduled to end.
	 * 
	 * @param strScheduledStudyStopDate String value of Scheduled Study Stop Date.
	 */
	public void setScheduledStudyStopDate(String strScheduledStudyStopDate)
	{
		/*Accept User or equipment generated Scheduled Study Stop Date in String format of type DA.
		 * 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 Hash Map
		 */
		addDataElement(0x0032,0x1010, DicomConstants.DCM_DT_DA, strScheduledStudyStopDate);
	}

	/**
	 * Sets Time at which the patient examination for the study is scheduled to end.
	 * 
	 * @param strScheduledStudyStopTime String value of Scheduled Study Stop Time.
	 */
	public void setScheduledStudyStopTime(String strScheduledStudyStopTime)
	{
		/*Accept User or equipment generated Scheduled Study Stop Time in String format of type TM.
		 * 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 Hash Map
		 */
		addDataElement(0x0032,0x1011, DicomConstants.DCM_DT_TM, strScheduledStudyStopTime);
	}

	/**
	 * Sets User-defined location at which the study will be performed.
	 * 
	 * @param strScheduledStudyLocation String value of Scheduled Study Location
	 */
	public void setScheduledStudyLocation(String strScheduledStudyLocation)
	{
		/*Accept User or equipment generated Scheduled Study Location 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 Hash Map
		 */
		addDataElement(0x0032,0x1020, DicomConstants.DCM_DT_LO, strScheduledStudyLocation);
	}

	/**
	 * Sets A list of Application Entity Title(s) of the location at which the study will be performed.
	 * 
	 * @param arrStrScheduledStudyLocationAETitles String value of Scheduled Study Location AE Titles.
	 */
	public void setScheduledStudyLocationAETitles(String[] arrStrScheduledStudyLocationAETitles)
	{
		/*Accept Scheduled Study Location AE Title(s) 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 Data Set
		 */
		addDataElement(0x0032, 0x1021, DicomConstants.DCM_DT_AE, arrStrScheduledStudyLocationAETitles);
	}

	/**
	 * Sets Describes the reason for performing study.
	 * 
	 * @param strReasonForStudy String value of Reason For Study.
	 */
	public void setReasonForStudy(String strReasonForStudy)
	{
		/*Accept User or equipment generated Reason for Study 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 Hash Map
		 */
		addDataElement(0x0032,0x1030, DicomConstants.DCM_DT_LO, strReasonForStudy);
	}

	/**
	 * Sets Name of the physician who requested the study.
	 * 
	 * @param strRequestingPhysician String value of Requesting Physician.
	 */
	public void setRequestingPhysician(String strRequestingPhysician)
	{
		/* Accept user-defined comments on the Requesting Physician in String 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
		 */
		addDataElement(0x0032,0x1032, DicomConstants.DCM_DT_PN, strRequestingPhysician);
	}

	/**
	 * Sets Institutional department where the request initiated.
	 * 
	 * @param strRequestingService String value of Requesting Service.
	 */
	public void setRequestingService(String strRequestingService)
	{
		/*Accept user-defined comments on the Requesting Service 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
		 */
		addDataElement(0x0032,0x1033, DicomConstants.DCM_DT_LO, strRequestingService);	
	}

	/**
	 * Sets Institution-generated description or classification of requested procedure.
	 * 
	 * @param strRequestedProcedureDescription String value of Requested Procedure Description.
	 */
	public void setRequestedProcedureDescription(String strRequestedProcedureDescription)
	{
		/*Accept User or equipment generated Requested Procedure Description 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 Hash Map
		 */
		addDataElement(0x0032,0x1060, DicomConstants.DCM_DT_LO, strRequestedProcedureDescription);
	}

	/**
	 * Sets Contrast agent requested for use in the procedure.
	 * 
	 * @param strRequestedContrastAgent String value of Requested Contrast Agent.
	 */
	public void setRequestedContrastAgent(String strRequestedContrastAgent)
	{
		/*Accept User or equipment generated Requested Contrast Agent 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 Hash Map
		 */
		addDataElement(0x0032,0x1070, DicomConstants.DCM_DT_LO, strRequestedContrastAgent);
	}

	/**
	 * Retrieves Date on which the study is scheduled to start.
	 * 
	 * @return String - String value of Scheduled Study Start Date.
	 */
	public String getScheduledStudyStartDate()
	{Object objectValue = getValue(0x0032,0x1000);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Time at which the study is scheduled to start.
	 * 
	 * @return String - String value of Scheduled Study Start Time.
	 */
	public String getScheduledStudyStartTime()
	{Object objectValue = getValue(0x0032,0x1001);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Date on which the patient examination for the study is scheduled to end.
	 * 
	 * @return String - String value of Scheduled Study Stop Date.
	 */
	public String getScheduledStudyStopDate()
	{Object objectValue = getValue(0x0032,0x1010);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Time at which the patient examination for the study is scheduled to end.
	 * 
	 * @return String - String value of Scheduled Study Stop Time.
	 */
	public String getScheduledStudyStopTime()
	{Object objectValue = getValue(0x0032,0x1011);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves User-defined location at which the study will be performed.
	 * 
	 * @return String - String value of Scheduled Study Location.
	 */
	public String getScheduledStudyLocation()
	{Object objectValue = getValue(0x0032,0x1020);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves A list of Application Entity Title(s) of the location at which the study will be performed.
	 * 
	 * @return String[] - String array of Scheduled Study Location AE Titles.
	 */
	public String[] getScheduledStudyLocationAETitles()
	{Object objectValue = getValue(0x0032,0x1021);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * Retrieves the reason for performing study.
	 * 
	 * @return String - String value of Reason For Study.
	 */
	public String getReasonForStudy()
	{Object objectValue = getValue(0x0032,0x1030);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Name of the physician who requested the study.
	 * 
	 * @return String - String value of Requesting Physician.
	 */
	public String getRequestingPhysician()
	{Object objectValue = getValue(0x0032,0x1032);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Institutional department where the request initiated.
	 * 
	 * @return String - String value of Requested Procedure Description.
	 */
	public String getRequestingService()
	{Object objectValue = getValue(0x0032,0x1033);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Institution-generated description or classification of requested procedure.
	 * 
	 * @return String - String value of Requested Procedure Description.
	 */
	public String getRequestedProcedureDescription()
	{Object objectValue = getValue(0x0032,0x1060);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves Contrast agent requested for use in the procedure.
	 * 
	 * @return String - String value of Requested Contrast Agent
	 */
	public String getRequestedContrastAgent()
	{Object objectValue = getValue(0x0032,0x1070);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves pre-initialized object of Requested Procedure 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 RequestedProcedureCodeSequence - instance of Requested Procedure Code Sequence.
	 */
	public RequestedProcedureCodeSequence getRequestedProcedureCodeSequence()
	{
		RequestedProcedureCodeSequence objRequestedProcedureCodeSequence = (RequestedProcedureCodeSequence)getDicomValue(0x0032,0x1064);
		if(objRequestedProcedureCodeSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objRequestedProcedureCodeSequence = (RequestedProcedureCodeSequence)objDicomV3Factory.createSequence(0x0032,0x1064, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0032,0x1064, DicomConstants.DCM_DT_SQ, objRequestedProcedureCodeSequence.getValue());
		}
		return objRequestedProcedureCodeSequence;
	}

	/**
	 * Retrieves pre-initialized object of Requesting 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 RequestingPhysicianIdentificationSequence - instance of Requesting Physician Identification Sequence.
	 */
	public RequestingPhysicianIdentificationSequence getRequestingPhysicianIdentificationSequence()
	{
		RequestingPhysicianIdentificationSequence objRequestingPhysicianIdentificationSequence = (RequestingPhysicianIdentificationSequence)getDicomValue(0x0032,0x1031);
		if(objRequestingPhysicianIdentificationSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objRequestingPhysicianIdentificationSequence = (RequestingPhysicianIdentificationSequence)objDicomV3Factory.createSequence(0x0032,0x1031, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0032,0x1031, DicomConstants.DCM_DT_SQ, objRequestingPhysicianIdentificationSequence.getValue());
		}
		return objRequestingPhysicianIdentificationSequence;
	}

	/* 
	 * I have modified the collection type from vector to custom class
	 * This method is used by the Module Iterator to iterate through the DataSet and return only
	 * those elements that belong to the respective Module class whose getVectorOfKeys is called.
	 */
	/**
	 * This method returns the vector of keys representing the DataElements
	 * that belong to this module.
	 * 
	 * @return vector of Tags - returns the vector containing the collection of tags
	 */
	public ISingleCollection<ITag> getVectorOfKeys()
	{
		return objSingleCollection;
	}
}
