/*******************************************************************************
 *  Copyright 2017 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.hl7282.baselibs.segments;

import cdac.medinfo.sdk.hl7282.baselibs.CWE;
import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.FN;
import cdac.medinfo.sdk.hl7282.baselibs.HD;
import cdac.medinfo.sdk.hl7282.baselibs.XCN;
import cdac.medinfo.sdk.hl7282.commoninterface.IDataType;
import cdac.medinfo.sdk.hl7282.commoninterface.ISingleCollection;
import cdac.medinfo.sdk.hl7282.exceptions.FieldMissingException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidSegmentException;
import cdac.medinfo.sdk.hl7282.utils.EnumSegments;
import cdac.medinfo.sdk.hl7282.utils.SingleCollection;

/**
 * EVN - Event Type Segment<p>
 * The EVN segment is used to communicate necessary trigger 
 * event information to receiving applications. 
 * Valid event types for all chapters are contained in HL7 Table 0003 - Event Type.
 * <p>Represents an HL7 EVN message segment. 
 * This segment has the following fields:</p><p>
 * EVN-1: Event Type Code (ID)<b>Withdrawn</b><br> 
 * EVN-2: Recorded Date/Time (DTM)<b>Required</b><br> 
 * EVN-3: Date/Time Planned Event (DTM)<b>Optional</b><br> 
 * EVN-4: Event Reason Code (CWE)<b>Optional</b><br> 
 * EVN-5: Operator ID (XCN)<b>Optional</b><br> 
 * EVN-6: Event Occurred (DTM)<b>Optional</b><br> 
 * EVN-7: Event Facility (HD)<b>Optional</b><br><p>
 * This class provides mechanism to validate message against HL7 v 2.8.2 standard.
 * The class provides accessors & mutators for the elements mentioned above.
 * The class has validate method which validates Message against HL7 v 2.8.2 standard.
 *
 * <p>User can also create Segment through {@link SegmentFactory}
 */
 public class EVN extends Segment    
{

	

	/**
	 * Constructs the EVN segment.
	 */
	public EVN()
	{super(EnumSegments.HL7_SEG_EVN);
	}
	//Integer values used in getter/setter is unique item id defined 
	//for each attribute.

	/**
	 * Retrieves the Date Time Planned Event.
	 * This field contains the date/time of the event is plan. 
	 * @return DTM - dateTimePlannedEvent
	 */
	public DTM getDateTimePlannedEvent()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(101);
		if(objDataCollection != null) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Event Facility.
	 * This field identify the actual facility where the event occurr and differentiate from the sending facility (MSH-4).
	 * @return HD - eventFacility
	 */
	public HD getEventFacility()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1534);
		if(objDataCollection != null) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Event Occurred.
	 * This field contains the date/time of the event actually occurr.  
	 * @return DTM - eventOccurred
	 */
	public DTM getEventOccurred()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1278);
		if(objDataCollection != null) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Event Reason Code.
	 * This field contains the reason for this event.  
	 * @return String - eventReasonCode
	 */
	public CWE getEventReasonCode() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(102);
		if(objDataCollection != null) 
			return (CWE)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Operator ID.
	 * This field identify the individual, responsible for triggering the event.  
	 * @return ISingleCollection<XCN> - operatorID
	 */
	public ISingleCollection<XCN> getOperatorID()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(103);
		ISingleCollection<XCN> objDataList = new SingleCollection<XCN>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				XCN objXCN = (XCN)objDataType;
				objDataList.add(objXCN);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the Recorded Date Time.
	 * @return DTM - recordedDateTime
	 */
	public DTM getRecordedDateTime() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(100);
		if(objDataCollection != null) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Set the Recorded Date Time.
	 * @param strRecordedDateTime Specifies recorded date time. 
	 */ 
	public void setRecordedDateTime (String strRecordedDateTime) 
	{
		DTM recordedDateTime  = (DTM)getDataElement(100);
		recordedDateTime.setValue(strRecordedDateTime);
		setRecordedDateTime(recordedDateTime);
	} 

	/** Set the Recorded Date Time.
	 * @param objrecordedDateTime object of Recorded Date Time.
	 */ 
	public void setRecordedDateTime(DTM objrecordedDateTime)
	{
		setDataType(100,objrecordedDateTime);
	}	/**
	 * Set the Date Time Planned Event.
	 * This field contains the date/time of the event is plan. 
	 * @param strDateTimePlannedEvent This field contains the date/time that the event is planned. 
	 */ 
	public void setDateTimePlannedEvent (String strDateTimePlannedEvent) 
	{
		DTM dateTimePlannedEvent  = (DTM)getDataElement(101);
		dateTimePlannedEvent.setValue(strDateTimePlannedEvent);
		setDateTimePlannedEvent(dateTimePlannedEvent);
	} 

	/**
	 * set the Date Time Planned Event.
	 * @param objDateTimePlannedEvent This field contains the date/time that the event is planned.
	 */
	public void setDateTimePlannedEvent(DTM objDateTimePlannedEvent)
	{
		setDataType(101,objDateTimePlannedEvent);

	}
	/**
	 * Set the Event Reason Code.
	 * This field contains the reason for this event.  
	 * @param strIdentifier Specifies of characters (the code) that uniquely identifies the item being referenced. 
	 * @param strText Specifies The descriptive or textual name of the identifier, e.g., myocardial infarction. 
	 * @param strNameOfCodingSystem Identifies the coding scheme being used in the identifier component.
	 * @param strAlternateIdentifier Specifies an alternate sequence of characters (the code) that uniquely identifies the item being referenced.
	 * @param strAlternateText Specifies the descriptive or textual name of the alternate identifier. See usage note in section introduction.
	 * @param strNameOfAlternateCodingSystem Identifies the coding scheme being used in the alternate identifier component. 
	 * @param strCodingSystemVersionID A sequence of characters that uniquely identifies a second alternate code.
	 * @param strAlternateCodingSystemVersionId This component carries the version for the coding system identified by components 4-6.
	 * @param strOriginalText The text as seen and/or selected by the user who entered the data.
	 * @param strSecondAlternateIdentifier A sequence of characters that uniquely identifies a second alternate code.
	 * @param strSecondAlternateText The descriptive or textual name of the alternate identifier.
	 * @param strNameofSecondAlternateCodingSystem Identifies the coding scheme being used in the alternate identifier component.
	 * @param strSecondAlternateCodingSystemVersionID This component carries the version for the coding system identified by components 10-12.
	 * @param strCodingSystemOID This component contains the ISO Object Identifier (OID) for the coding system or value set named in CWE.3.
	 * @param strValueSetOID This component contains the ISO Object Identifier (OID) to allow identification of the value set from which the value in CWE.1 is obtained.
	 * @param strValueSetVersionID This component carries the version for the value set identified by CWE.15. The version is a date. The date is the date/time that the value set being used was published.
	 * @param strAlternateCodingSystemOID This component contains the ISO Object Identifier (OID) for the coding system or value set named in CWE.6.
	 * @param strAlternateValueSetOID This component contains the ISO Object Identifier (OID) to allow identification of the value set from which the value in CWE.4 is obtained.
	 * @param strAlternateValueSetVersionID This component carries the version for the value set identified by CWE.18. The version is a date.
	 * @param strSecondAlternateCodingSystemOID This component contains the ISO Object Identifier (OID) for the coding system or value set named in CWE.12.
	 * @param strSecondAlternateValueSetOID This component contains the ISO Object Identifier (OID) to allow identification of the value set from which the value in CWE.10 is obtained.
	 * @param strSecondAlternateValueSetVersionID This component carries the version for the value set identified by CWE.21. The version is a date.
	 */	
	public void setEventReasonCode(String strIdentifier,String strText,String strNameOfCodingSystem,
			String strAlternateIdentifier,String strAlternateText,String strNameOfAlternateCodingSystem, String strCodingSystemVersionID, String strAlternateCodingSystemVersionId,
			String strOriginalText, String  strSecondAlternateIdentifier, String strSecondAlternateText, 
			String strNameofSecondAlternateCodingSystem, String strSecondAlternateCodingSystemVersionID, String strCodingSystemOID, String strValueSetOID,
			String strValueSetVersionID, String strAlternateCodingSystemOID, String strAlternateValueSetOID, String strAlternateValueSetVersionID,
			String  strSecondAlternateCodingSystemOID, String strSecondAlternateValueSetOID, String strSecondAlternateValueSetVersionID)
	{
		CWE EventReasonCode  = (CWE)getDataElement(102);
		EventReasonCode.setIdentifier(strIdentifier);
		EventReasonCode.setText(strText);
		EventReasonCode.setNameOfCodingSystem(strNameOfCodingSystem);
		EventReasonCode.setAlternateIdentifier(strAlternateIdentifier);
		EventReasonCode.setAlternateText(strAlternateText);
		EventReasonCode.setNameOfAlternateCodingSystem(strNameOfAlternateCodingSystem); 
		EventReasonCode.setCodingSystemVersionID(strCodingSystemVersionID);
		EventReasonCode.setAlternateCodingSystemVersionId(strAlternateCodingSystemVersionId);
		EventReasonCode.setOriginalText(strOriginalText);
		EventReasonCode.setSecondAlternateIdentifier(strSecondAlternateIdentifier);
		EventReasonCode.setSecondAlternateText(strSecondAlternateText);
		EventReasonCode.setNameofSecondAlternateCodingSystem(strNameofSecondAlternateCodingSystem);
		EventReasonCode.setSecondAlternateCodingSystemVersionID(strSecondAlternateCodingSystemVersionID);
		EventReasonCode.setCodingSystemOID(strCodingSystemOID);
		EventReasonCode.setValueSetOID(strValueSetOID);
		EventReasonCode.setValueSetVersionID(strValueSetVersionID);
		EventReasonCode.setAlternateCodingSystemOID(strAlternateCodingSystemOID);
		EventReasonCode.setAlternateValueSetOID(strAlternateValueSetOID);
		EventReasonCode.setAlternateValueSetVersionID(strAlternateValueSetVersionID);
		EventReasonCode.setSecondAlternateCodingSystemOID(strSecondAlternateCodingSystemOID);
		EventReasonCode.setSecondAlternateValueSetOID(strSecondAlternateValueSetOID);
		EventReasonCode.setSecondAlternateValueSetVersionID(strSecondAlternateValueSetVersionID);
		setEventReasonCode(EventReasonCode);
	}
	/**
	 * set the Event Reason Code.
	 * @param objEventReasonCode object of Event Reason Code.
	 */
	public void setEventReasonCode(CWE objEventReasonCode)
	{
		setDataType(102,objEventReasonCode);
	}
	
	/**
	 * Set the Operator ID.
	 * This field identify the individual, responsible for triggering the event.  
	 * @param strIDNumber Refers to the coded ID according to a user-defined table
	 * @param objFamilyName Specifies the surname of a person.
	 * @param strGivenName Specifies First name.
	 * @param strSecondAndFurtherGivenNamesOrInitialsThereof Specifies multiple middle names that may be included by 
	 * 														   separating them with spaces.
	 * @param strSuffix Used to specify a name suffix (e.g., Jr. or III).
	 * @param strPrefix Used to specify a name prefix (e.g., Dr.).
	 * @param strSourceTable Used as the HL7 identifier for the user-defined table of values for this component. [Refer User-defined Table 0297 - CN ID.]
	 * @param objAssigningAuthority Specifies a unique identifier of the system (or organization or agency of department)
	 * 								  that creates the data. [Refer User-defined Table 0363 - Assigning authority]
	 * @param strNameTypeCode Specifies a code that represents the type of name. 
	 * @param strIdentifierCheckDigit Specifies part of the identifying number used in the sending application. 
	 * @param strCheckDigitScheme Specifies the code identifying the check digit scheme employed.[Refer HL7 Table 0061 - Check digit scheme].
	 * @param strIdentifierTypeCode Specifies A code corresponding to the type of identifier.[Refer HL7 Table 0203 - Identifier type].
	 * @param objAssigningFacility Specifies the place or location identifier where the identifier was first assigned to the person
	 * @param strNameRepresentationCode provides an indication of the representation provided by the data item.  
	 * @param objNameContext Designates the context in which a name is used. [Refer User-defined Table 0448 ]
	 * @param strNameAssemblyOrder Specifies a code that represents the preferred display order of the components of this person name. Suggested values are G,F[Refer table 0444.]
	 * @param objEffectiveDate Specifies the first date, if known, on which the address is valid and active.
	 * @param objExpirationDate Specifies the last date, if known, on which the address is valid and active.
	 * @param strProfessionalSuffix Used to specify an abbreviation, or a string of abbreviations, denoting qualifications that support the person's profession, (e.g., licenses).
	 * @param objAssigningJurisdiction Specifies the geo-political body that assigned the identifier.
	 * @param objAssigningAgencyOrDepratment Specifies the agency or department that assigned the identifier
	 */ 
	public void addOperatorID (String strIDNumber,FN objFamilyName,String strGivenName,String strSecondAndFurtherGivenNamesOrInitialsThereof,
			String 	strSuffix,String strPrefix,String strSourceTable,HD objAssigningAuthority,
			String strNameTypeCode,String strIdentifierCheckDigit,String strCheckDigitScheme,String strIdentifierTypeCode,
			HD objAssigningFacility,String strNameRepresentationCode,CWE objNameContext,
			String strNameAssemblyOrder,DTM objEffectiveDate,DTM objExpirationDate,String strProfessionalSuffix,
			CWE objAssigningJurisdiction,CWE objAssigningAgencyOrDepratment)
	{
		XCN DiagnosingClinician  = (XCN)getDataElement(103);
		DiagnosingClinician.setIdNumber(strIDNumber);
		DiagnosingClinician.setFamilyName(objFamilyName);
		DiagnosingClinician.setGivenName(strGivenName);
		DiagnosingClinician.setSecondNameOrInitials(strSecondAndFurtherGivenNamesOrInitialsThereof);
		DiagnosingClinician.setSuffix(strSuffix);
		DiagnosingClinician.setPrefix(strPrefix);
//		DiagnosingClinician.setDegree(strDegree);
		DiagnosingClinician.setSourceTable(strSourceTable);
		DiagnosingClinician.setAssigningAuthority(objAssigningAuthority);
		DiagnosingClinician.setNameTypeCode(strNameTypeCode);
		DiagnosingClinician.setIdentifierCheckDigit(strIdentifierCheckDigit);
		DiagnosingClinician.setCheckDigitScheme(strCheckDigitScheme);
		DiagnosingClinician.setIdentifierTypeCode(strIdentifierTypeCode);
		DiagnosingClinician.setAssigningFacility(objAssigningFacility);
		DiagnosingClinician.setNameRepresentationCode(strNameRepresentationCode);
		DiagnosingClinician.setNameContext(objNameContext);
//		DiagnosingClinician.setNameValidityRange(objNameValidityRange);
		DiagnosingClinician.setNameAssemblyOrder(strNameAssemblyOrder);
		DiagnosingClinician.setEffectiveDate(objEffectiveDate);
		DiagnosingClinician.setExpirationDate(objExpirationDate);
		DiagnosingClinician.setProfessionalSuffix(strProfessionalSuffix);
		DiagnosingClinician.setAssigningJurisdiction(objAssigningJurisdiction);
		DiagnosingClinician.setAssigningAgencyOrDepartment(objAssigningAgencyOrDepratment); 
		addOperatorID(DiagnosingClinician);

	} 

	/** Sets the Operator ID.
	 * @param objOperatorID object of Operator ID.
	 */ 
	public void addOperatorID(XCN objOperatorID)
	{
		addDataType(103,objOperatorID);
	}	
	/**
	 * This sets the Operator ID.
	 * @param objOpeartorID Collection of Operator ID.
	 */
	@SuppressWarnings("unchecked")
	public void setOperatorID(ISingleCollection<XCN> objOpeartorID)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objOpeartorID;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(103,objCollection);
	}
	/**
	 * Set the Event Occurred.
	 * This field contains the date/time of the event actually occurr.  
	 * @param strEventOccurred The date/time that the event actually occurred. 
	 */ 
	public void setEventOccurred (String strEventOccurred) 
	{
		DTM eventOccurred  = (DTM)getDataElement(1278);
		eventOccurred.setValue(strEventOccurred);
		setEventOccurred(eventOccurred);
	} 

	/**Sets the Event Occurred.
	 * @param objeventOccurred object of Event Occurred.
	 */ 
	public void setEventOccurred(DTM objeventOccurred)
	{
		setDataType(1278,objeventOccurred);
	}	/**
	 * Set the Event Facility.
	 * This field identify the actual facility where the event occurr and differentiate from the sending facility (MSH-4).
	 * @param strNamespaceID Specifies Specifies  the HL7 identifier for the user-defined table of values for this component.[Refer Table No.300]
	 * @param strUniversalID Specifies a string formatted according to the scheme defined by the component, <universal ID type> (UID type). 
	 * @param strUniversalIDType Governs the interpretation of the strUniversalId. 
	 */ 
	public void setEventFacility (String strNamespaceID,String strUniversalID,String strUniversalIDType) 
	{
		HD eventFacility  = (HD)getDataElement(1534);
		eventFacility.setNamespaceId(strNamespaceID);
		eventFacility.setUniversalId(strUniversalID);
		eventFacility.setUniversalIdType(strUniversalIDType); 
		setEventFacility(eventFacility);
	} 

	/** Set the Event Facility.
	 * This field identify the actual facility where the event occurr and differentiate from the sending facility (MSH-4).
	 * @param objeventFacility object of Event Facility. 
	 */ 
	public void setEventFacility(HD objeventFacility)
	{
		setDataType(1534,objeventFacility);
	}
	/**
	 * Validates HL7 Message objects .
	 * Validate method checks for validation each and every segments in side the Message object against specified message Structure. 
	 * Validation chcecks include optionality of segment or group.
	 * It also verifies the number of times segment or group is repeated in message.
	 * e.g 
	 * {PSH} while parsing PSH segment validate method will check for its mandatory presence.
	 * [PSH] in this case validate will throw exception if one tries to enter more than one PSH segment.
	 * @return boolean - true or false.
	 * @throws InvalidSegmentException If Segment Validation fails
	 */
	public boolean validate()throws InvalidSegmentException
	{
		try
		{
			super.validate();
			return true;
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(enumSegments.getValue(),ex);
		}
	}
}