/*******************************************************************************
 *  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.EI;
import cdac.medinfo.sdk.hl7282.baselibs.HD;
import cdac.medinfo.sdk.hl7282.baselibs.ID;
import cdac.medinfo.sdk.hl7282.baselibs.PL;
import cdac.medinfo.sdk.hl7282.baselibs.XON;
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;

/**
 * LRL - Location Relationship Segment<p>
 * The Technical Steward for the LRL segment is PA.The LRL segment is used to identify one
 * location's relationship to another location, the nearest lab, pharmacy, etc.
 * <p>Represents an HL7 LRL message segment. 
 * This segment has the following fields:</p><p>
 * LRL-1: Primary Key Value - LRL (PL)<b>Required</b><br> 
 * LRL-2: Segment Action Code (ID)<b>Optional</b><br> 
 * LRL-3: Segment Unique Key (EI)<b>Optional</b><br> 
 * LRL-4: Location Relationship ID (CWE)<b>Required</b><br> 
 * LRL-5: Organizational Location Relationship Value (XON)<b>Conditional</b><br> 
 * LRL-6: Patient Location Relationship Value (PL)<b>Conditional</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 LRL extends Segment   
{

	

	/**
	 * Constructs the LRL segment.
	 */
	public LRL()
	{super(EnumSegments.HL7_SEG_LRL);
	}

	//Integer values used in getter/setter is unique item id defined 
	//for each attribute.

	/**
	 * Retrieves the Location Relationship ID.
	 * This field contains an identifier code to show WHICH relationship is being communicated with this segment. 
	 * @return CWE - locationRelationshipID
	 */
	public CWE getLocationRelationshipID() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1277);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CWE)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Organizational Location Relationship Value.
	 * This field holds that organization's extended name i.e., the value of this
	 *  field is conditional on the value of LRL-4 - Location Relationship ID.  
	 * @return ISingleCollection<XON> - organizationalLocationRelationshipValue
	 */
	public ISingleCollection<XON> getOrganizationalLocationRelationshipValue() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1301);
		ISingleCollection<XON> objDataList = new SingleCollection<XON>(); 
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				XON objXON = (XON)objDataType;
				objDataList.add(objXON);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the Patient Location Relationship Value.
	 * This field is conditional on the value of LRL-4 - Location Relationship ID.  
	 * @return PL - patientLocationRelationshipValue
	 */
	public PL getPatientLocationRelationshipValue() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1292);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (PL)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Primary Key Value LRL.
	 * This field contains the institution's identification code for the location.  
	 * @return PL - primaryKeyValueLRL
	 */
	public PL getPrimaryKeyValueLRL() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(943);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (PL)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Segment Action Code.
	 * This field indicates whether this repetition of the segment is being added, changed or deleted.    
	 * @return ID - segmentActionCode
	 */
	public ID getSegmentActionCode() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(763);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Segment Unique Key.
	 * This field contains a unique identifier for one of the multiple repetitions of this segment, 
	 * to be used in conjunction with the preceding field.  
	 * @return EI - segmentUniqueKey
	 */
	public EI getSegmentUniqueKey() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(764);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Set the Location Relationship ID.
	 * This field contains an identifier code to show WHICH relationship is being communicated with this segment. 
	 * @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 setLocationRelationshipID (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 cwe  = (CWE)getDataElement(1277);
		cwe.setIdentifier(strIdentifier);
		cwe.setText(strText);
		cwe.setNameOfCodingSystem(strNameOfCodingSystem);
		cwe.setAlternateIdentifier(strAlternateIdentifier);
		cwe.setAlternateText(strAlternateText);
		cwe.setNameOfAlternateCodingSystem(strNameOfAlternateCodingSystem); 
		cwe.setCodingSystemVersionID(strCodingSystemVersionID);
		cwe.setAlternateCodingSystemVersionId(strAlternateCodingSystemVersionId);
		cwe.setOriginalText(strOriginalText);
		cwe.setSecondAlternateIdentifier(strSecondAlternateIdentifier);
		cwe.setSecondAlternateText(strSecondAlternateText);
		cwe.setNameofSecondAlternateCodingSystem(strNameofSecondAlternateCodingSystem);
		cwe.setSecondAlternateCodingSystemVersionID(strSecondAlternateCodingSystemVersionID);
		cwe.setCodingSystemOID(strCodingSystemOID);
		cwe.setValueSetOID(strValueSetOID);
		cwe.setValueSetVersionID(strValueSetVersionID);
		cwe.setAlternateCodingSystemOID(strAlternateCodingSystemOID);
		cwe.setAlternateValueSetOID(strAlternateValueSetOID);
		cwe.setAlternateValueSetVersionID(strAlternateValueSetVersionID);
		cwe.setSecondAlternateCodingSystemOID(strSecondAlternateCodingSystemOID);
		cwe.setSecondAlternateValueSetOID(strSecondAlternateValueSetOID);
		cwe.setSecondAlternateValueSetVersionID(strSecondAlternateValueSetVersionID);
		setLocationRelationshipID(cwe);

	} 

	/** 
	 * Set the Location Relationship ID.
	 * This field contains an identifier code to show WHICH relationship is being communicated with this segment. 
	 * @param objlocationRelationshipID Object of Location Relationship ID. 
	 */ 
	public void setLocationRelationshipID(CWE objlocationRelationshipID)
	{
		setDataType(1277,objlocationRelationshipID);

	}

	/**
	 * Add the Organizational Location Relationship Value.
	 * This field holds that organization's extended name i.e., the value of this
	 *  field is conditional on the value of LRL-4 - Location Relationship ID.
	 * @param strOrganizationName Specifies name of the specified organization.
	 * @param objOrganizationNameTypeCode Specifies a code that represents the type of name i.e., legal name, display name.
	 * 										Suggested Values A,L,D,SL.[Refer to table No.0204]  
	 * @param objAssigningAuthority Specifies The assigning authority is a unique identifier of the system 
	 * 									(or organization or agency or department) that creates the data. 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier. 
	 * @param objAssigningFacility Specifies The place or location identifier where the identifier was first assigned to the person. 
	 * @param strNameRepresentationCode Specifies representations of the same name/address Suggested values are I,A,P [Refer table 0465] 
	 * @param strOrganizationIdentifier This component contains the sequence of characters (the code) that uniquely 
	 * 									  identifies the item being referenced by XON.1 Organization Name. 
	 * 									  This component replaces XON.3 ID Number as of v 2.5.
	 */ 
	public void addOrganizationalLocationRelationshipValue(String strOrganizationName, CWE objOrganizationNameTypeCode,
			 HD objAssigningAuthority,
			String strIdentifierTypeCode, HD objAssigningFacility, String strNameRepresentationCode,
			String strOrganizationIdentifier)
	{
		XON xon  = (XON)getDataElement(1301);
		xon.setOrganizationName(strOrganizationName);
		xon.setOrganizationNameTypeCode(objOrganizationNameTypeCode);
		xon.setAssigningAuthority(objAssigningAuthority);
		xon.setIdentifierTypeCode(strIdentifierTypeCode);
		xon.setAssigningFacility(objAssigningFacility);
		xon.setNameRepresentationCode(strNameRepresentationCode);
		xon.setOrganizationIdentifier(strOrganizationIdentifier); 
		addOrganizationalLocationRelationshipValue(xon);
	}

	/**
	 * Add the Organizational Location Relationship Value.
	 * This field holds that organization's extended name i.e., the value of this
	 *  field is conditional on the value of LRL-4 - Location Relationship ID.
	 * @param objorganizationalLocationRelationshipValue Object of Organizational Location Relationship Value.
	 */
	public void addOrganizationalLocationRelationshipValue(XON objorganizationalLocationRelationshipValue)
	{
		addDataType(1301,objorganizationalLocationRelationshipValue);
	}

	/**
	 * Set the Organizational Location Relationship Value.
	 * This field holds that organization's extended name i.e., the value of this
	 *  field is conditional on the value of LRL-4 - Location Relationship ID.
	 * @param objorganizationalLocationRelationshipValueList List of Organizational Location Relationship Value.
	 */
	@SuppressWarnings("unchecked")
	public void setOrganizationalLocationRelationshipValue(ISingleCollection<XON> objorganizationalLocationRelationshipValueList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objorganizationalLocationRelationshipValueList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1301,objCollection);
	}

	/**
	 * Set the Patient Location Relationship Value.
	 * This field is conditional on the value of LRL-4 - Location Relationship ID.
	 * @param objPointOfCare Specifies the code for the point where patient care is administered.
	 * @param objRoom Specifies the code for the patient's room. 
	 * @param objBed Specifies the code for the patient's bed. 
	 * @param objFacility Specifies to site interpretation but generally describes 
	 * 							the highest level physical designation of an institution, 
	 * 							medical center or enterprise. 
	 * @param strLocationStatus Specifies the code for the status or availability of the location. 
	 * @param strPersonLocationType Specifies the categorization of the person's location defined by 
	 * 									facility, building, floor, point of care, room or bed. 
	 * @param objBuilding Specifies code for the building where the person is located. 
	 * @param objFloor Specifies the code for the floor where the person is located.
	 * @param strLocationDescription Specifies describes the location in free text.
	 * @param objComprehensiveLocationIdentifier Specifies represents the physical location as 
	 *													a whole without regard for the individual components. 
	 * @param objAssigningAuthorityForLocation Specifies the entity that creates the data for the individual physical location components. 
	 */ 
	public void setPatientLocationRelationshipValue (HD objPointOfCare, HD objRoom, HD objBed, HD objFacility,
			String strLocationStatus, String strPersonLocationType, HD objBuilding, HD objFloor, 
			String strLocationDescription, EI objComprehensiveLocationIdentifier, HD objAssigningAuthorityForLocation)
	{
		PL pl  = (PL)getDataElement(1292);
		pl.setPointOfCare(objPointOfCare);
		pl.setRoom(objRoom);
		pl.setBed(objBed);
		pl.setFacility(objFacility);
		pl.setLocationStatus(strLocationStatus);
		pl.setPersonLocationType(strPersonLocationType);
		pl.setBuilding(objBuilding);
		pl.setFloor(objFloor);
		pl.setLocationDescription(strLocationDescription);
		pl.setComprehensiveLocationIdentifier(objComprehensiveLocationIdentifier);
		pl.setAssigningAuthorityForLocation(objAssigningAuthorityForLocation);  
		setPatientLocationRelationshipValue(pl);

	} 

	/** 
	 * Set the Patient Location Relationship Value.
	 * This field is conditional on the value of LRL-4 - Location Relationship ID.
	 * @param objpatientLocationRelationshipValue Object of Patient Location Relationship Value.
	 */ 
	public void setPatientLocationRelationshipValue(PL objpatientLocationRelationshipValue)
	{
		setDataType(1292,objpatientLocationRelationshipValue);

	}

	/**
	 * Set the Primary Key Value LRL.
	 * This field contains the institution's identification code for the location.    
	 * @param objPointOfCare Specifies the code for the point where patient care is administered.
	 * @param objRoom Specifies the code for the patient's room. 
	 * @param objBed Specifies the code for the patient's bed. 
	 * @param objFacility Specifies to site interpretation but generally describes 
	 * 							the highest level physical designation of an institution, 
	 * 							medical center or enterprise. 
	 * @param strLocationStatus Specifies the code for the status or availability of the location. 
	 * @param strPersonLocationType Specifies the categorization of the person's location defined by 
	 * 									facility, building, floor, point of care, room or bed. 
	 * @param objBuilding Specifies code for the building where the person is located. 
	 * @param objFloor Specifies the code for the floor where the person is located.
	 * @param strLocationDescription Specifies describes the location in free text.
	 * @param objComprehensiveLocationIdentifier Specifies represents the physical location as 
	 *													a whole without regard for the individual components. 
	 * @param objAssigningAuthorityForLocation Specifies the entity that creates the data for the individual physical location components. 
	 */ 
	public void setPrimaryKeyValueLRL  (HD objPointOfCare, HD objRoom, HD objBed, HD objFacility,
			String strLocationStatus, String strPersonLocationType, HD objBuilding, HD objFloor, 
			String strLocationDescription, EI objComprehensiveLocationIdentifier, HD objAssigningAuthorityForLocation)
	{
		PL pl  = (PL)getDataElement(943);
		pl.setPointOfCare(objPointOfCare);
		pl.setRoom(objRoom);
		pl.setBed(objBed);
		pl.setFacility(objFacility);
		pl.setLocationStatus(strLocationStatus);
		pl.setPersonLocationType(strPersonLocationType);
		pl.setBuilding(objBuilding);
		pl.setFloor(objFloor);
		pl.setLocationDescription(strLocationDescription);
		pl.setComprehensiveLocationIdentifier(objComprehensiveLocationIdentifier);
		pl.setAssigningAuthorityForLocation(objAssigningAuthorityForLocation); 
		setPrimaryKeyValueLRL (pl);

	} 

	/** 
	 * Set the Primary Key Value LRL.
	 * This field contains the institution's identification code for the location.    
	 * @param objprimaryKeyValueLRL Object of Primary Key Value LRL.
	 */ 
	public void setPrimaryKeyValueLRL(PL objprimaryKeyValueLRL)
	{
		setDataType(943,objprimaryKeyValueLRL);

	}

	/**
	 * Set the Segment Action Code.
	 * This field indicates whether this repetition of the segment is being added, changed or deleted.    
	 * @param strBPstatus - String which to set as BP Status 
	 */ 
	public void setSegmentActionCode (String strBPstatus) 
	{
		ID segmentActionCode  = (ID)getDataElement(763);
		segmentActionCode.setValue(strBPstatus); 
		setSegmentActionCode(segmentActionCode);

	} 

	/** 
	 * Set the Segment Action Code.
	 * This field indicates whether this repetition of the segment is being added, changed or deleted.    
	 * @param objsegmentActionCode Object of Segment Action Code.
	 */ 
	public void setSegmentActionCode(ID objsegmentActionCode)
	{
		setDataType(763,objsegmentActionCode);

	}

	/**
	 * Set the Segment Unique Key.
	 * This field contains a unique identifier for one of the multiple repetitions of this segment, 
	 * to be used in conjunction with the preceding field.  
	 * @param strEntityIdentifier Specifies defined by a hierarchic designator, represented by components 2 through 4.
	 * 								[Reference Section 2.A.33, "HD - hierarchic designator".] 
	 * @param strNamespaceId Specifies  the HL7 identifier for the user-defined table of values for this component.
	 * 						   [Refer to User-defined Table 0363 - Assigning authority] 	 
	 * @param strUniversalId Specifies string formatted according to the scheme defined by the component, 
	 * 							<universal ID type> (UID type). 
	 * @param strUniversalIdType Specifies  the interpretation of the second component of the HD. 
	 */ 
	public void setSegmentUniqueKey (String strEntityIdentifier,String strNamespaceId,
			String strUniversalId,String strUniversalIdType)
	{
		EI segmentUniqueKey  = (EI)getDataElement(764);
		segmentUniqueKey.setEntityIdentifier(strEntityIdentifier);
		segmentUniqueKey.setNamespaceId(strNamespaceId);
		segmentUniqueKey.setUniversalId(strUniversalId);
		segmentUniqueKey.setUniversalIdType(strUniversalIdType); 
		setSegmentUniqueKey(segmentUniqueKey);

	} 

	/** 
	 * Set the Segment Unique Key.
	 * This field contains a unique identifier for one of the multiple repetitions of this segment, 
	 * to be used in conjunction with the preceding field.  
	 * @param objsegmentUniqueKey Object of Segment Unique Key.
	 */ 
	public void setSegmentUniqueKey(EI objsegmentUniqueKey)
	{
		setDataType(764,objsegmentUniqueKey);

	}

	/**
	 * Validates HL7 Message objects .
	 * Validate method checks for validation each and every segments in side the Message object against specified message Structure. 
	 * Validation checks 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 
	 */	
	@Override
	public boolean validate() throws InvalidSegmentException 
	{
		/*
		 * Primary Key Value - LRL,Location Relationship ID  are required fields.
		 */
		try 
		{
			super.validate();

			return true;
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(enumSegments.getValue(),ex);
		}
	}
}