/*******************************************************************************
 *  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.CX;
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.XPN;
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;

/**
 * MRG - Merge Patient Information Segment.<p>
 * MRG segment provides receiving applications with information necessary to initiate the merging 
 * of patient data as well as groups of records.  It is intended that this segment be used throughout
 * the Standard to allow the merging of registration, accounting, and clinical records within specific applications.
 * <p>Represents an HL7 MRG message segment. 
 * This segment has the following fields:</p><p>
 * MRG-1: Prior Patient Identifier List (CX)<b>Required</b><br> 
 * MRG-2: Prior Alternate Patient ID (CX)<b>Withdrawn</b><br> 
 * MRG-3: Prior Patient Account Number (CX)<b>Optional</b><br> 
 * MRG-4: Prior Patient ID (CX)<b>Withdrawn</b><br> 
 * MRG-5: Prior Visit Number (CX)<b>Optional</b><br> 
 * MRG-6: Prior Alternate Visit ID (CX)<b>Optional</b><br> 
 * MRG-7: Prior Patient Name (XPN)<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 MRG extends Segment   
{

	

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


	/**
	 * Retrieves the Prior Alternate Visit ID.
	 * This field contains the prior alternate visit number.
	 * @return CX - priorAlternateVisitID
	 */
	public ISingleCollection<CX> getPriorAlternateVisitID()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1280);
		ISingleCollection<CX> objDataList = new SingleCollection<CX>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				CX objCX = (CX)objDataType;
				objDataList.add(objCX);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the Prior Patient Account Number.
	 * This field contains the prior patient account number. 
	 * @return CX - priorPatientAccountNumber
	 */
	public CX getPriorPatientAccountNumber() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(213);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CX)objDataCollection.elementAt(0);
		else
			return null;
	}


	/**
	 * Retrieves the Prior Patient Identifier List.
	 * This field contains the prior patient identifier list.  
	 * @return ISingleCollection<CX> - priorPatientIdentifierList
	 */
	public ISingleCollection<CX> getPriorPatientIdentifierList()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(211);
		ISingleCollection<CX> objDataList = new SingleCollection<CX>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				CX objCX = (CX)objDataType;
				objDataList.add(objCX);
			}
		}

		return objDataList;
	}

	/**
	 * Retrieves the Prior Patient Name.
	 * This field contains the prior name of the patient.
	 * @return ISingleCollection<XPN> - priorPatientName
	 */
	public ISingleCollection<XPN> getPriorPatientName()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1281);
		ISingleCollection<XPN> objDataList = new SingleCollection<XPN>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				XPN objXPN = (XPN)objDataType;
				objDataList.add(objXPN);
			}
		}

		return objDataList;
	}

	/**
	 * Retrieves the Prior Visit Number.
	 * This field contains the prior visit number.  
	 * @return CX - priorVisitNumber
	 */
	public CX getPriorVisitNumber() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1279);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CX)objDataCollection.elementAt(0);
		else
			return null;
	}


	/**
	 * Set the Prior Patient Account Number.
	 * This field contains the prior patient account number.
	 * @param strIDNumber Specifies the value of the identifier itself.
	 * @param strCheckDigit It is part of the identifying number used in the sending application. 
	 * @param strCheckDigitScheme Contains the code identifying the check digit scheme employed.
	 * 								Suggested Values NP,ISO,M10,M11.[Refer table No.0061].
	 * @param objAssigningAuthority The assigning authority is a unique name of the system (or organization or agency 
	 * 									or department) that creates the data. . 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier.In some cases, this code may be
	 * 								 used as a qualifier to the "Assigning authority" component.[Refer table No 0203]
	 * @param objAssigningFacility Specifies the place or location identifier where the identifier was first assigned 
	 * 									to the patient. 
	 * @param strEffectiveDate Specifies the first date, if known, on which the address is valid and active.
	 * @param strExpirationDate Specifies the last date, if known, on which the address is valid and active.
	 * @param objAssigningJurisdiction Specifies the geo-political body that assigned the identifier. 
	 * @param objAssigningAgencyOrDepartment Specifies agency or department that assigned the identifier. 
	 * @param strSecurityCheck is used to communicate the version code. 
	 * @param objSecurityCheckSCheme is used to transmit information intended to validate veracity of the supplied identifier
	 */  
	public void setPriorPatientAccountNumber (String strIDNumber,String strCheckDigit, String strCheckDigitScheme, HD objAssigningAuthority,
			String strIdentifierTypeCode,HD objAssigningFacility,String strEffectiveDate,String strExpirationDate, 
			CWE objAssigningJurisdiction, CWE objAssigningAgencyOrDepartment, String strSecurityCheck, String strSecurityCheckScheme)
	{
		CX priorPatientAccountNumber  = (CX)getDataElement(213);	
		priorPatientAccountNumber.setIdNumber(strIDNumber);
		priorPatientAccountNumber.setCheckDigit(strCheckDigit);
		priorPatientAccountNumber.setCheckDigitScheme(strCheckDigitScheme);
		priorPatientAccountNumber.setAssigningAuthority(objAssigningAuthority);
		priorPatientAccountNumber.setIdentifierTypeCode(strIdentifierTypeCode);
		priorPatientAccountNumber.setAssigningFacility(objAssigningFacility);
		priorPatientAccountNumber.setEffectiveDate(strEffectiveDate);
		priorPatientAccountNumber.setExpirationDate(strExpirationDate);
		priorPatientAccountNumber.setAssigningJurisdiction(objAssigningJurisdiction);
		priorPatientAccountNumber.setAssigningAgencyOrDepartment(objAssigningAgencyOrDepartment); 
		priorPatientAccountNumber.setSecurityCheck(strCheckDigit);
		priorPatientAccountNumber.setSecurityCheckScheme(strSecurityCheckScheme);
		
		setPriorPatientAccountNumber(priorPatientAccountNumber);

	} 

	/** Set the Prior Patient Account Number.
	 * This field contains the prior patient account number.
	 * @param objpriorPatientAccountNumber object of Patient Account Number. 
	 */ 
	public void setPriorPatientAccountNumber(CX objpriorPatientAccountNumber)
	{
		setDataType(213,objpriorPatientAccountNumber);
	}

	/**
	 * Set the Prior Patient Identifier List.
	 * This field contains the prior patient identifier list.
	  * @param strIDNumber Specifies the value of the identifier itself.
	 * @param strCheckDigit It is part of the identifying number used in the sending application. 
	 * @param strCheckDigitScheme Contains the code identifying the check digit scheme employed.
	 * 								Suggested Values NP,ISO,M10,M11.[Refer table No.0061].
	 * @param objAssigningAuthority The assigning authority is a unique name of the system (or organization or agency 
	 * 									or department) that creates the data. . 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier.In some cases, this code may be
	 * 								 used as a qualifier to the "Assigning authority" component.[Refer table No 0203]
	 * @param objAssigningFacility Specifies the place or location identifier where the identifier was first assigned 
	 * 									to the patient. 
	 * @param strEffectiveDate Specifies the first date, if known, on which the address is valid and active.
	 * @param strExpirationDate Specifies the last date, if known, on which the address is valid and active.
	 * @param objAssigningJurisdiction Specifies the geo-political body that assigned the identifier. 
	 * @param objAssigningAgencyOrDepartment Specifies agency or department that assigned the identifier. 
	 * @param strSecurityCheck is used to communicate the version code. 
	 * @param objSecurityCheckSCheme is used to transmit information intended to validate veracity of the supplied identifier
	 */
	public void addPriorPatientIdentifierList(String strIDNumber,String strCheckDigit, String strCheckDigitScheme, HD objAssigningAuthority,
			String strIdentifierTypeCode,HD objAssigningFacility,String strEffectiveDate,String strExpirationDate, 
			CWE objAssigningJurisdiction, CWE objAssigningAgencyOrDepartment, String strSecurityCheck, String strSecurityCheckScheme)
	{
		CX tempPriorPatientIdentifierList  = (CX)getDataElement(211);
		tempPriorPatientIdentifierList.setIdNumber(strIDNumber);
		tempPriorPatientIdentifierList.setCheckDigit(strCheckDigit);
		tempPriorPatientIdentifierList.setCheckDigitScheme(strCheckDigitScheme);
		tempPriorPatientIdentifierList.setAssigningAuthority(objAssigningAuthority);
		tempPriorPatientIdentifierList.setIdentifierTypeCode(strIdentifierTypeCode);
		tempPriorPatientIdentifierList.setAssigningFacility(objAssigningFacility);
		tempPriorPatientIdentifierList.setEffectiveDate(strEffectiveDate);
		tempPriorPatientIdentifierList.setExpirationDate(strExpirationDate);
		tempPriorPatientIdentifierList.setAssigningJurisdiction(objAssigningJurisdiction);
		tempPriorPatientIdentifierList.setAssigningAgencyOrDepartment(objAssigningAgencyOrDepartment); 
		tempPriorPatientIdentifierList.setSecurityCheck(strCheckDigit);
		tempPriorPatientIdentifierList.setSecurityCheckScheme(strSecurityCheckScheme);
		addPriorPatientIdentifierList(tempPriorPatientIdentifierList);
	}

	/** Set the Prior Patient Identifier.
	 * This field contains the prior patient identifier.
	 * @param objpriorPatientIdentifier object of Prior Patient Identifier.
	 */ 
	public void addPriorPatientIdentifierList(CX objpriorPatientIdentifier)
	{
		addDataType(211,objpriorPatientIdentifier);
	}
	/**
	 * Set the Patient Identifier.
	 * @param objPriorPatientIdentifierList List of Patient Identifier.
	 */	
	@SuppressWarnings("unchecked")
	public void setPriorPatientIdentifierList(ISingleCollection<CX> objPriorPatientIdentifierList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objPriorPatientIdentifierList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(211,objCollection);
	}

	/**
	 * Set the Prior AlternateVisit ID.
	 * This field contains the prior Alternate visit number of patient.
	 * @param strIDNumber Specifies the value of the identifier itself.
	 * @param strCheckDigit It is part of the identifying number used in the sending application. 
	 * @param strCheckDigitScheme Contains the code identifying the check digit scheme employed.
	 * 								Suggested Values NP,ISO,M10,M11.[Refer table No.0061].
	 * @param objAssigningAuthority The assigning authority is a unique name of the system (or organization or agency 
	 * 									or department) that creates the data. . 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier.In some cases, this code may be
	 * 								 used as a qualifier to the "Assigning authority" component.[Refer table No 0203]
	 * @param objAssigningFacility Specifies the place or location identifier where the identifier was first assigned 
	 * 									to the patient. 
	 * @param strEffectiveDate Specifies the first date, if known, on which the address is valid and active.
	 * @param strExpirationDate Specifies the last date, if known, on which the address is valid and active.
	 * @param objAssigningJurisdiction Specifies the geo-political body that assigned the identifier. 
	 * @param objAssigningAgencyOrDepartment Specifies agency or department that assigned the identifier. 
	 * @param strSecurityCheck is used to communicate the version code. 
	 * @param objSecurityCheckSCheme is used to transmit information intended to validate veracity of the supplied identifier
	 */ 

	public void addPriorAlternateVisitID (String strIDNumber,String strCheckDigit, String strCheckDigitScheme, HD objAssigningAuthority,
			String strIdentifierTypeCode,HD objAssigningFacility,String strEffectiveDate,String strExpirationDate, 
			CWE objAssigningJurisdiction, CWE objAssigningAgencyOrDepartment, String strSecurityCheck, String strSecurityCheckScheme)
	{
		CX tempPriorAlternateVisitID = (CX)getDataElement(1280);
		tempPriorAlternateVisitID.setIdNumber(strIDNumber);
		tempPriorAlternateVisitID.setCheckDigit(strCheckDigit);
		tempPriorAlternateVisitID.setCheckDigitScheme(strCheckDigitScheme);
		tempPriorAlternateVisitID.setAssigningAuthority(objAssigningAuthority);
		tempPriorAlternateVisitID.setIdentifierTypeCode(strIdentifierTypeCode);
		tempPriorAlternateVisitID.setAssigningFacility(objAssigningFacility);
		tempPriorAlternateVisitID.setEffectiveDate(strEffectiveDate);
		tempPriorAlternateVisitID.setExpirationDate(strExpirationDate);
		tempPriorAlternateVisitID.setAssigningJurisdiction(objAssigningJurisdiction);
		tempPriorAlternateVisitID.setAssigningAgencyOrDepartment(objAssigningAgencyOrDepartment); 
		tempPriorAlternateVisitID.setSecurityCheck(strCheckDigit);
		tempPriorAlternateVisitID.setSecurityCheckScheme(strSecurityCheckScheme);
		addPriorAlternateVisitID(tempPriorAlternateVisitID);
	}
	/**
	 * Sets the Prior Alternate Visit ID.
	 * @param objpriorAlternateVisitID object of Prior Alternate Visit ID.
	 */
	public void addPriorAlternateVisitID(CX objpriorAlternateVisitID)
	{
		addDataType(1280,objpriorAlternateVisitID);
	}
	
	/**
	 * Set the Prior Alternate Visit ID.
	 * @param objPriorAlternateVisitID List of Prior Patient Name.
	 */	
	@SuppressWarnings("unchecked")
	public void setPriorAlternateVisitID(ISingleCollection<CX> objPriorPatientNameList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objPriorPatientNameList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1280,objCollection);
	}

	/**
	 * Set the Prior Patient Name.
	 * This field contains the prior name of the patient.
	 * @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 strNameTypeCode Specifies a code that represents the type of name. Suggested values are A,B,C,D,I,L,M,N,P,R,S,T,U...[Refer table 0200.]
	 * @param strNameRepresentationCode Specifies representations of the same name/address Suggested values are I,A,P [Refer table 0465] 
	 * @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 strCalledBy Used to specify the called name.
	 */ 

	public void addPriorPatientName(FN objFamilyName, String strGivenName, String strSecondAndFurtherGivenNamesOrInitialsThereof, 
			String strSuffix, String strPrefix, String strNameTypeCode, String strNameRepresentationCode, 
			CWE objNameContext, String strNameAssemblyOrder, DTM objEffectiveDate,
			DTM objExpirationDate, String strProfessionalSuffix, String strCalledBy)
	{
		XPN tempPriorPatientName = (XPN)getDataElement(1281);
		tempPriorPatientName.setFamilyName(objFamilyName);
		tempPriorPatientName.setGivenName(strGivenName);
		tempPriorPatientName.setSecondNameOrInitials(strSecondAndFurtherGivenNamesOrInitialsThereof);
		tempPriorPatientName.setSuffix(strSuffix);
		tempPriorPatientName.setPrefix(strPrefix);
		tempPriorPatientName.setNameTypeCode(strNameTypeCode);
		tempPriorPatientName.setNameRepresentationCode(strNameRepresentationCode);
		tempPriorPatientName.setNameContext(objNameContext);
		tempPriorPatientName.setNameAssemblyOrder(strNameAssemblyOrder);
		tempPriorPatientName.setEffectiveDate(objEffectiveDate);
		tempPriorPatientName.setExpirationDate(objExpirationDate);
		tempPriorPatientName.setProfessionalSuffix(strProfessionalSuffix); 
		tempPriorPatientName.setCalledBy(strCalledBy);
		addPriorPatientName(tempPriorPatientName);
	}
	/**
	 * Sets the Prior Patient Name.
	 * @param objPriorPatientNameID object of Prior Patient Name.
	 */
	public void addPriorPatientName(XPN objPriorPatientNameID)
	{
		addDataType(1281,objPriorPatientNameID);
	}

	
	/**
	 * Set the Prior Patient Name.
	 * @param objPriorPatientNameList List of Prior Patient Name.
	 */	
	@SuppressWarnings("unchecked")
	public void setPriorPatientName(ISingleCollection<XPN> objPriorPatientNameList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objPriorPatientNameList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1281,objCollection);
	}
	/**
	 * Set the Prior Visit Number.
	 * This field contains the prior visit number.
	  * @param strIDNumber Specifies the value of the identifier itself.
	 * @param strCheckDigit It is part of the identifying number used in the sending application. 
	 * @param strCheckDigitScheme Contains the code identifying the check digit scheme employed.
	 * 								Suggested Values NP,ISO,M10,M11.[Refer table No.0061].
	 * @param objAssigningAuthority The assigning authority is a unique name of the system (or organization or agency 
	 * 									or department) that creates the data. . 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier.In some cases, this code may be
	 * 								 used as a qualifier to the "Assigning authority" component.[Refer table No 0203]
	 * @param objAssigningFacility Specifies the place or location identifier where the identifier was first assigned 
	 * 									to the patient. 
	 * @param strEffectiveDate Specifies the first date, if known, on which the address is valid and active.
	 * @param strExpirationDate Specifies the last date, if known, on which the address is valid and active.
	 * @param objAssigningJurisdiction Specifies the geo-political body that assigned the identifier. 
	 * @param objAssigningAgencyOrDepartment Specifies agency or department that assigned the identifier. 
	 * @param strSecurityCheck is used to communicate the version code. 
	 * @param objSecurityCheckSCheme is used to transmit information intended to validate veracity of the supplied identifier
	 */ 
	public void setPriorVisitNumber(String strIDNumber,String strCheckDigit, String strCheckDigitScheme, HD objAssigningAuthority,
			String strIdentifierTypeCode,HD objAssigningFacility,String strEffectiveDate,String strExpirationDate, 
			CWE objAssigningJurisdiction, CWE objAssigningAgencyOrDepartment, String strSecurityCheck, String strSecurityCheckScheme)
	{
		CX priorVisitNumber  = (CX)getDataElement(1279);
		priorVisitNumber.setIdNumber(strIDNumber);
		priorVisitNumber.setCheckDigit(strCheckDigit);
		priorVisitNumber.setCheckDigitScheme(strCheckDigitScheme);
		priorVisitNumber.setAssigningAuthority(objAssigningAuthority);
		priorVisitNumber.setIdentifierTypeCode(strIdentifierTypeCode);
		priorVisitNumber.setAssigningFacility(objAssigningFacility);
		priorVisitNumber.setEffectiveDate(strEffectiveDate);
		priorVisitNumber.setExpirationDate(strExpirationDate);
		priorVisitNumber.setAssigningJurisdiction(objAssigningJurisdiction);
		priorVisitNumber.setAssigningAgencyOrDepartment(objAssigningAgencyOrDepartment); 
		priorVisitNumber.setSecurityCheck(strCheckDigit);
		priorVisitNumber.setSecurityCheckScheme(strSecurityCheckScheme);
		setPriorVisitNumber(priorVisitNumber);
	}

	/**
	 * Sets the Prior Visit Number.
	 * @param objPriorPatientNameID object of Prior Visit Number.
	 */
	public void setPriorVisitNumber(CX objPriorPatientNameID)
	{
		setDataType(1279,objPriorPatientNameID);
	}

	/**
	 * 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 Throws when Segment Validation fails
	 */
	public boolean validate() throws InvalidSegmentException
	{
		/*
		 * Prior Patient Identifier List is required field.
		 */
		try
		{
			super.validate();
			return true;
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(enumSegments.getValue(),ex);
		}
	}
}