/*******************************************************************************
 *  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 java.io.IOException;
import java.util.Locale;

import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.HD;
import cdac.medinfo.sdk.hl7282.baselibs.ST;
import cdac.medinfo.sdk.hl7282.commoninterface.IDataType;
import cdac.medinfo.sdk.hl7282.commoninterface.IDelimiter;
import cdac.medinfo.sdk.hl7282.commoninterface.IHL7Stream;
import cdac.medinfo.sdk.hl7282.commoninterface.ISingleCollection;
import cdac.medinfo.sdk.hl7282.exceptions.DelimiterMissingException;
import cdac.medinfo.sdk.hl7282.exceptions.FieldMissingException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidDataTypeException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidDelimiterException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidFieldException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidSegmentException;
import cdac.medinfo.sdk.hl7282.exceptions.SerializeException;
import cdac.medinfo.sdk.hl7282.utils.EnumSegments;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.HL7Constants;
import cdac.medinfo.sdk.hl7282.utils.ResourceBundleWrapper;

/**
 * BHS - batch header segment <p>
 * The BHS segment defines the intent, source, destination, and some specifics of the
 * syntax of a Batch.
 * <p>Represents an HL7 BHS Batch header segment. 
 * This segment has the following fields:</p><p>
 * BHS-1: Field Separator (ST)<b>Required</b><br> 
 * BHS-2: Encoding Characters (ST)<b>Required</b><br> 
 * BHS-3: Sending Application (HD)<b>Optional</b><br> 
 * BHS-4: Sending Facility (HD)<b>Optional</b><br> 
 * BHS-5: Receiving Application (HD)<b>Optional</b><br> 
 * BHS-6: Receiving Facility (HD)<b>Optional</b><br> 
 * BHS-7: Date/Time Of Batch (DTM)<b>Optional</b><br> 
 * BHS-8: Batch Security (ST)<b>Optional</b><br> 
 * BHS-9: Batch Type (ST)<b>Optional</b><br> 
 * BHS-10: Batch Comment (ST)<b>Optional</b><br> 
 * BHS-11: Batch Control ID (ST)<b>Optional</b><br> 
 * BHS-12: Reference Batch Control ID (ST)<b>Optional</b><br>
 * BHS-13: Batch Sending Network Address (HD)<b>Optional</b><br>
 * BHS-14: Batch Receiving Network Address (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 BHS extends Segment   
{
	


	protected Delimiter objDelimiter;

	/**
	 * Constructs the BHS segment.
	 */
	public BHS()
	{
		super(EnumSegments.HL7_SEG_BHS);
		objDelimiter = new Delimiter();
	}

	/**
	 * Retrieves the Delimiter.
	 * @return IDelimiter - delimiter.
	 */	
	public IDelimiter getDelimiter()
	{
		return objDelimiter;
	}

	/**
	 * Retrieves the Date Time Of Batch.
	 * This field contains the date/time that the sending system created the Batch.
	 * @return DTM - dateTimeOfBatch
	 */
	public DTM getBatchCreationDateTime() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(87);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Encoding Char.
	 * This field contains the four characters in the following order: the 
	 * component separator, repetition separator, escape character, and subcomponent separator.
	 * @return ST - encodingChar
	 */
	public ST getBatchEncodingChar() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(82);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Field Separator.
	 * This field contains the separator between the segment ID and the first real field.
	 * @return ST - fieldSeparator
	 */
	public ST getBatchFieldSeparator()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(81);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch. 
	 * @return ST - BatchControlID
	 */
	public ST getBatchControlID()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(91);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Reference Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch. 
	 * @return ST - referenceBatchControlID
	 */
	public ST getReferenceBatchControlID()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(92);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Receiving Application.
	 * This field uniquely identify the receiving application among all other applications within the network enterprise
	 * @return HD - receivingApplication
	 */
	public HD getBatchReceivingApplication()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(85);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Receiving Facility.
	 * This field identify the receiving application among multiple identical instances of 
	 * the application running on behalf of different organizations. 
	 * @return HD - receivingFacility
	 */
	public HD getBatchReceivingFacility()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(86);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Security.
	 * @return ST - security
	 */
	public ST getBatchSecurity()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(88);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Sending Application.
	 * This field uniquely identifies the sending application among all other applications within the network enterprise.
	 * @return HD - sendingApplication
	 */
	public HD getBatchSendingApplication() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(83);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Sending Facility.
	 * This field used as the HL7 identifier for the user-defined table of values for the first component.
	 * @return HD - sendingFacility
	 */
	public HD getBatchSendingFacility()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(84);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}



	/**
	 * Retrieves the Batch Type.
	 * This field contains the Batch type, trigger event, and the Batch structure ID for the Batch.
	 * @return ST - batchType
	 */
	public ST getBatchName_ID_Type()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(89);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Batch Comment.
	 * This field contains the Batch type
	 * @return ST - batchComment
	 */
	public ST getBatchComment()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(90);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Batch Sending Network Address.
	 * This identifies the network location the message was transmitted from.
	 * @return HD - batchSendingNetworkAddress
	 */
	public HD getBatchSendingNetworkAddressn() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2271);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Retrieves the Batch Receiving Network Address.
	 * This identifies the network location the message was transmitted to. Identified by an OID or text string. (e.g., URL).
	 * @return HD - batchReceivingNetworkAddress
	 */
	public HD getBatchReceivingNetworkAddressn() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2272);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (HD)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	
	/**
	 * Set the Field Separator.
	 * This field contains the separator between the segment ID and the first real field.
	 * @param cfieldSeparator Use as cfieldSeparator.
	 */
	public void setBatchFieldSeparator(char cfieldSeparator) 
	{
		String strFSSeparator = "" + cfieldSeparator;
		ST fieldSeparator = (ST)getDataElement(81);
		fieldSeparator.setValue(strFSSeparator);
		objDelimiter.cFieldSeparator = cfieldSeparator;
		setBatchFieldSeparator(fieldSeparator);
	}

	/**
	 * Set the Field Separator.
	 * This field contains the separator between the segment ID and the first real field.
	 * @param objfieldSeparator object of fieldSeparator.
	 */
	public void setBatchFieldSeparator(ST objfieldSeparator) 
	{ 
		String strFSSeparator;
		strFSSeparator =(String)objfieldSeparator.getValue();
		char cfieldSeparator =strFSSeparator.charAt(0);
		objDelimiter.cFieldSeparator = cfieldSeparator;
		setDataType(81,objfieldSeparator);
	}

	/**
	 * Set the Encoding Char.
	 * This field contains the four characters in the following order: the 
	 * component separator, repetition separator, escape character, and subcomponent separator.
	 * @param cComponentSeparator Delimiter Use as ComponentSeparator
	 * @param cSubComponentSeparator Delimiter Use as SubComponentSeparator
	 * @param cRepetitionSeparator Delimiter Use as RepetitionSeparator
	 * @param cEscapeCharacter Delimiter Use as EscapeCharacter
	 * @param cTruncationCharacter Delimiter use as TruncationCharacter
	 */
	public void setBatchEncodingChars(char cComponentSeparator, char cSubComponentSeparator, char cRepetitionSeparator, char cEscapeCharacter, char cTruncationCharacter) 
	{
		objDelimiter.cComponentSeparator = cComponentSeparator;
		objDelimiter.cSubComponentSeparator = cSubComponentSeparator;
		objDelimiter.cRepetitionSeparator = cRepetitionSeparator;
		objDelimiter.cEscapeCharacter = cEscapeCharacter;
		objDelimiter.cTruncationCharacter=cTruncationCharacter;
		String strEncodingChar = "";
		strEncodingChar =  strEncodingChar + cComponentSeparator +cRepetitionSeparator + cEscapeCharacter + cSubComponentSeparator + cTruncationCharacter; 
		ST encodingChar = (ST)getDataElement(82);
		encodingChar.setValue(strEncodingChar);
		setBatchEncodingChars(encodingChar);
	}

	/**
	 * Set the Encoding Char.
	 * This field contains the four characters in the following order: the
	 * component separator, repetition separator, escape character, and subcomponent separator. 
	 * @param objencodingChar object of Encoding Char.
	 */
	public void setBatchEncodingChars(ST objencodingChar) 
	{ 
		String strEncodingChar = (String)objencodingChar.getValue();
		objDelimiter.cComponentSeparator = strEncodingChar.charAt(0);
		objDelimiter.cRepetitionSeparator = strEncodingChar.charAt(1);
		objDelimiter.cEscapeCharacter = strEncodingChar.charAt(2);
		objDelimiter.cSubComponentSeparator = strEncodingChar.charAt(3);
		objDelimiter.cTruncationCharacter = strEncodingChar.charAt(4);
		setDataType(82,objencodingChar);
	}

	/** 
	 * Set the Date Time Of Batch.
	 * This field contains the date/time that the sending system created the Batch.
	 * @param strTime Specifies a point in time using a 24-hour clock notation. 
	 */
	public void setBatchCreationDateTime(String strTime) 
	{
		DTM dateTimeOfBatch  = (DTM)getDataElement(87);
		dateTimeOfBatch.setValue(strTime);		
		setBatchCreationDateTime(dateTimeOfBatch);
	}

	/**
	 * Set the Date Time Of Batch.
	 * This field contains the date/time that the sending system created the Batch.
	 * @param objDateTimeOfBatch Object of Date Time Of Batch.
	 */
	public void setBatchCreationDateTime(DTM objDateTimeOfBatch)
	{
		setDataType(87,objDateTimeOfBatch);
	}

	/** 
	 * Set the Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch. 
	 * @param strbatchControlID Specifies a number or other identifier that uniquely identifies the Batch. 
	 */
	public void setBatchControlID(String strbatchControlID) 
	{
		ST batchControlID  = (ST)getDataElement(91);
		batchControlID.setValue(strbatchControlID); 
		setBatchControlID(batchControlID);
	}

	/**
	 * Set the Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch.
	 * @param objBatchControlID Object of Batch Control ID.
	 */
	public void setBatchControlID(ST objBatchControlID)
	{
		setDataType(91,objBatchControlID);
	}

	/** 
	 * Set the Reference Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch. 
	 * @param strReferenceBatchControlID Specifies a number or other identifier that uniquely identifies the Batch. 
	 */
	public void setReferenceBatchControlID(String strReferenceBatchControlID) 
	{
		ST referenceBatchControlID  = (ST)getDataElement(92);
		referenceBatchControlID.setValue(strReferenceBatchControlID);
		setReferenceBatchControlID(referenceBatchControlID);
	}

	/**
	 * Set the Reference Batch Control ID.
	 * This field contains a number or other identifier that uniquely identifies the Batch.
	 * @param objReferenceBatchControlID Object of Reference Batch Control ID.
	 */
	public void setReferenceBatchControlID(ST objReferenceBatchControlID)
	{
		setDataType(92,objReferenceBatchControlID);
	}

	/** 
	 * Set the Batch Type.
	 * This field contains the Batch type  for the Batch.
	 * @param strBatchType Specifies the Batch type code.
	 */
	public void setBatchName_ID_Type(String strBatchType) 
	{
		ST batchType  = (ST)getDataElement(89);
		batchType.setValue(strBatchType);
		setBatchName_ID_Type(batchType);
	}

	/**
	 * Set the Batch Type.
	 * This field contains the Batch type  for the Batch.
	 * @param objBatchType Object of Batch Type.
	 */
	public void setBatchName_ID_Type(ST objBatchType)
	{
		setDataType(89,objBatchType);
	}

	/** 
	 * Set the Batch Comment.
	 * This field contains the Batch Comment  for the Batch.
	 * @param strBatchComment Specifies the Batch Comment.
	 */
	public void setBatchComment(String strBatchComment) 
	{
		ST batchComment  = (ST)getDataElement(90);
		batchComment.setValue(strBatchComment);
		setBatchComment(batchComment);
	}

	/**
	 * Set the Batch Comment.
	 * This field contains the Batch Comment  for the Batch.
	 * @param objBatchComment Object of Batch Comment.
	 */
	public void setBatchComment(ST objBatchComment)
	{
		setDataType(90,objBatchComment);
	}

	/** 
	 * Set the Receiving Application.
	 * This field uniquely identify the receiving application among all other applications within the network enterprise
	 * @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 setBatchReceivingApplication(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD receivingApplication  = (HD)getDataElement(85);
		receivingApplication.setNamespaceId(strNamespaceId);
		receivingApplication.setUniversalId(strUniversalId);
		receivingApplication.setUniversalIdType(strUniversalIdType);
		setBatchReceivingApplication(receivingApplication);
	}

	/**
	 * Set the Receiving Application.
	 * This field uniquely identify the receiving application among all other applications within the network enterprise.
	 * @param objReceivingApplication Object of Receiving Application.
	 */
	public void setBatchReceivingApplication(HD objReceivingApplication)
	{
		setDataType(85,objReceivingApplication);
	}

	/** 
	 * Set the Receiving Facility.
	 * This field identify the receiving application among multiple identical instances of 
	 * the application running on behalf of different organizations.
	 * @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 setBatchReceivingFacility(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD receivingFacility  = (HD)getDataElement(86);
		receivingFacility.setNamespaceId(strNamespaceId);
		receivingFacility.setUniversalId(strUniversalId);
		receivingFacility.setUniversalIdType(strUniversalIdType);
		setBatchReceivingFacility(receivingFacility);
	}

	/**
	 * Set the Receiving Facility.
	 * This field identify the receiving application among multiple identical instances of 
	 * @param objReceivingFacility Object of Receiving Facility.
	 */
	public void setBatchReceivingFacility(HD objReceivingFacility)
	{
		setDataType(86,objReceivingFacility);
	}

	/** 
	 * Set the Security.
	 * @param strSecurity Specifies a field ,that is used to implement security features. 
	 */
	public void setBatchSecurity(String strSecurity) 
	{
		ST security  = (ST)getDataElement(88);
		security.setValue(strSecurity);
		setBatchSecurity(security);
	}

	/**
	 * Set the Security.
	 * @param objSecurity Object of Security.
	 */
	public void setBatchSecurity(ST objSecurity)
	{
		setDataType(88,objSecurity);
	}

	/** 
	 * Set the Sending Application.
	 * This field uniquely identifies the sending application among all other applications within the network enterprise.
	 * @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 setBatchSendingApplication(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD sendingApplication  = (HD)getDataElement(83);
		sendingApplication.setNamespaceId(strNamespaceId);
		sendingApplication.setUniversalId(strUniversalId);
		sendingApplication.setUniversalIdType(strUniversalIdType);
		setBatchSendingApplication(sendingApplication);
	}

	/**
	 * Set the Sending Application.
	 * This field uniquely identifies the sending application among all other applications within the network enterprise.
	 * @param objSendingApplication object of Sending Application
	 */
	public void setBatchSendingApplication(HD objSendingApplication)
	{
		setDataType(83,objSendingApplication);
	}

	/** 
	 * Set the Sending Facility.
	 * This field used as the HL7 identifier for the user-defined table of values for the first component.
	 * @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 setBatchSendingFacility(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD sendingFacility  = (HD)getDataElement(84);
		sendingFacility.setNamespaceId(strNamespaceId);
		sendingFacility.setUniversalId(strUniversalId);
		sendingFacility.setUniversalIdType(strUniversalIdType);
		setBatchSendingFacility(sendingFacility);
	}

	/**
	 * Set the Sending Facility.
	 * This field used as the HL7 identifier for the user-defined table of values for the first component.
	 * @param objSendingFacility object of Sending Facility.
	 */
	public void setBatchSendingFacility(HD objSendingFacility)
	{
		setDataType(84,objSendingFacility);
	}
	
	/** 
	 * Set the Batch Sending Network Address.
	 * This field uniquely identifies the sending application among all other applications within the network enterprise.
	 * @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 setBatchSendingNetworkAddress(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD sendingApplication  = (HD)getDataElement(2271);
		sendingApplication.setNamespaceId(strNamespaceId);
		sendingApplication.setUniversalId(strUniversalId);
		sendingApplication.setUniversalIdType(strUniversalIdType);
		setBatchSendingNetworkAddress(sendingApplication);
	}

	/**
	 * Set the Batch Sending Network Address.
	 * This field uniquely identifies the sending application among all other applications within the network enterprise.
	 * @param objBatchSendingNetworkAddress object of Sending Application
	 */
	public void setBatchSendingNetworkAddress(HD objBatchSendingNetworkAddress)
	{
		setDataType(2271,objBatchSendingNetworkAddress);
	}
	
	/** 
	 * Set the Batch Receiving  Network Address.
	 * This field identifies the network location the message was transmitted to.  Identified by an OID or text string. (e.g., URL).
	 * @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 setBatchReceivingNetworkAddress(String strNamespaceId,String strUniversalId,String strUniversalIdType) 
	{
		HD sendingApplication  = (HD)getDataElement(2272);
		sendingApplication.setNamespaceId(strNamespaceId);
		sendingApplication.setUniversalId(strUniversalId);
		sendingApplication.setUniversalIdType(strUniversalIdType);
		setBatchReceivingNetworkAddress(sendingApplication);
	}

	/**
	 * Set the Batch Receiving  Network Address.
	 * This field identifies the network location the message was transmitted to.  Identified by an OID or text string. (e.g., URL).
	 * @param objBatchReceivingNetworkAddress object of Sending Application
	 */
	public void setBatchReceivingNetworkAddress(HD objBatchReceivingNetworkAddress)
	{
		setDataType(2272,objBatchReceivingNetworkAddress);
	}

	/**
	 * 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 Thrown when Any of required filed is missing.
	 */
	public boolean validate() throws InvalidSegmentException
	{
		try
		{
			super.validate();

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

	/**
	 * Serializes HL7 Message objects.
	 * Before serializaton it validates Message as per HL7 v2.5 standard.
	 * For successfull serialization , Message Object should follow order of segments as per its corresponding Message Structure. 
	 * Serialize method fails if given stream is null.
	 * It mandates presence of required segments and the number of occurences specified by the standard.
	 * This method also checks for presence of Mandatory Groups.It also verifies repeatability of Group.
	 * @param objIHL7Stream Object of IHL7Stream.
	 * @param objIDelimiter Object of class Delimiter.
	 * @return int - [failure or success].
	 * @throws SerializeException Thrown when serialization of Message fails. 
	 * @throws IOException  Signals that an I/O exception of some sort has occurred.
	 */
	public int serialize(IHL7Stream objIHL7Stream,IDelimiter objIDelimiter) throws SerializeException,IOException
	{
		try
		{
			ISingleCollection<Integer> objItemIDList = objSegmentMap.getItemIDList();
			// get the Character used as the repetition Seperator for the repeating field. 
			char cRSeparator = objIDelimiter.getRepetitionSeparator();
			if(cRSeparator == '\0')
				throw new DelimiterMissingException(ResourceBundleWrapper.getValue("exceptions", "RepetitionSeparatorMissing", new Locale(HL7Config.createInstance().getLocale())));			//get the Character used as the Field Seperator for Seperating the field. 
			char cFSeparator = objIDelimiter.getFieldSeparator();
			if(cFSeparator == '\0')
				throw new DelimiterMissingException(ResourceBundleWrapper.getValue("exceptions", "FieldSeparatorMissing", new Locale(HL7Config.createInstance().getLocale())));
			//write name of Segment.
			objIHL7Stream.writeString(EnumSegments.HL7_SEG_BHS.getValue());
			objIHL7Stream.writeChar(cFSeparator);
			//This write is called in plase of write on "encodingChar" field of BHS.
			objDelimiter.writeDelimiters(objIHL7Stream);
			objIHL7Stream.writeChar(cFSeparator);
			
			for(int seqno = 2; seqno < objItemIDList.size();seqno++)
			{
				int itemID = objItemIDList.elementAt(seqno);

				ISingleCollection<IDataType> objDataTypeList = objDataElementList.get(itemID);

				if(objDataTypeList != null)
				{
					int iSize = objDataTypeList.size();
					for(int index = 0; index < objDataTypeList.size(); index++)
					{
						IDataType objIDataType = objDataTypeList.elementAt(index);
						objIDataType.write(objIHL7Stream,objIDelimiter);

						if(index != iSize - 1)
							objIHL7Stream.writeChar(cRSeparator);
					}
				}
				if(seqno != objItemIDList.size() - 1)
				{
					//This Code checks next elements are present or not
					for(int i= seqno+1 ; i<objItemIDList.size();i++)
					{
						int itemID1 = objItemIDList.elementAt(i);
						ISingleCollection<IDataType> objDataTypeList1 = objDataElementList.get(itemID1);
						//If next element is present then it appends Field Separator
						if(objDataTypeList1 != null)
						{
							objIHL7Stream.writeChar(cFSeparator);
							break;
						}
					}
				}
			}

			//This character shows the end of the segment.
			objIHL7Stream.writeChar('\r');

			return HL7Constants.HL7_FUNCTION_SUCCESS;
		}
		catch(InvalidSegmentException ex)
		{
			throw new SerializeException(this.getClass().getSimpleName(),ex);
		}
		catch(DelimiterMissingException ex)
		{
			throw new SerializeException(this.getClass().getSimpleName(),ex);
		}
	}

	/**
	 * Parses HL7 Segment Strings from any Stream into HL7 Segment object.
	 * This method checks for the Repetition of the fields in the Segment.
	 * It also checks for the optionality of the fields as whether they are mandatory or optional.
	 * Successful parsing of the segment populates the object with the data present on the stream and provides
	 * easy accessor and mutator methods to navigate the message.
	 * It also leads to failure if version of given HL7 Message is not 2.8.2.
	 * This method raises exception if there is Segment which is not valid as per HL7 v 2.8.2 standard.
	 * @param strSegmentStream String of HL7Stream.
	 * @param objIDelimiter Object of class Delimiter.
	 * @return int - Success if segment is valid.
	 * 			   - Fail if segment in not valid
	 * @throws InvalidSegmentException Thrown when Field Validation Fails.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */	
	public int parse(String strSegmentStream,IDelimiter objIDelimiter) throws InvalidSegmentException,IOException
	{
		int iRetVal = HL7Constants.HL7_FUNCTION_FAIL;
		char cReadChar = '\0';
		try
		{
			int i = -1;
			do
			{
				String strTemp = "";
				String strField="";
				//After BHS the next character is field separator.
				//Read Field Seperator
				cReadChar =strSegmentStream.charAt(++i);
				//Read value of field seperator to Delimiter
				objDelimiter.cFieldSeparator = cReadChar;
				strTemp = "" + cReadChar;
				ST fieldSeparator = (ST)getDataElement(81);
				fieldSeparator.setValue(strTemp);
				setDataType(81, fieldSeparator);
				//Read encoding char
				String encodingChars="";
				char ch=strSegmentStream.charAt(i);
				do
				{
					ch=strSegmentStream.charAt(++i);
					encodingChars=encodingChars+ch;
						
				}while(ch!='|' && ch!='\r');
				iRetVal = objDelimiter.readDelimiters(encodingChars);
				if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					setUnRecognizedField("BHS", "Encoding Characters", encodingChars);
					return iRetVal;
				}
				strTemp = "";
				strTemp = strTemp + objDelimiter.cComponentSeparator + objDelimiter.cRepetitionSeparator; 
				if(objDelimiter.cEscapeCharacter != '\0')
					strTemp = strTemp + objDelimiter.cEscapeCharacter + objDelimiter.cSubComponentSeparator ;
				ST encodingChar = (ST)getDataElement(82);
				encodingChar.setValue(strTemp);
				setDataType(82, encodingChar);
				objIDelimiter = objDelimiter;
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;
				//Read Sending Application
				HD sendingApplication = (HD)getDataElement(83);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = sendingApplication.read(strField, objIDelimiter);
				if(iRetVal == 0)
					sendingApplication = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					sendingApplication = null;
					setUnRecognizedField("BHS", "Batch Sending Application",strField);
				}
				else
				{
					setDataType(83, sendingApplication);
					sendingApplication = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Sending Facility
				HD sendingFacility = (HD)getDataElement(84);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = sendingFacility.read(strField, objIDelimiter);
				if(iRetVal == 0)
					sendingFacility = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					sendingFacility = null;
					setUnRecognizedField("BHS", "Batch Sending Facility",strField);
				}
				else
				{
					setDataType(84, sendingFacility);
					sendingFacility = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Receiving Application
				HD receivingApplication = (HD)getDataElement(85);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = receivingApplication.read(strField, objIDelimiter);
				if(iRetVal == 0)
					receivingApplication = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					receivingApplication = null;
					setUnRecognizedField("BHS"," Batch Receiving Application",strField);
				}
				else
				{
					setDataType(85, receivingApplication);
					receivingApplication = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Receiving Facility
				HD receivingFacility = (HD)getDataElement(86);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = receivingFacility.read(strField, objIDelimiter);
				if(iRetVal == 0)
					receivingFacility = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					receivingFacility = null;
					setUnRecognizedField("BHS","Batch Receiving Facility",strField);
				}
				else
				{
					setDataType(86, receivingFacility);
					receivingFacility = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Date-Time Of Batch
				DTM dateTimeOfBatch = (DTM)getDataElement(87);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = dateTimeOfBatch.read(strField, objIDelimiter);
				if(iRetVal == 0)
					dateTimeOfBatch = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					dateTimeOfBatch = null;
					setUnRecognizedField("BHS","Batch Creation Date/Time",strField);
				}
				else
				{
					setDataType(87, dateTimeOfBatch);
					dateTimeOfBatch = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Security
				ST security = (ST)getDataElement(88);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = security.read(strField, objIDelimiter);
				if(iRetVal == 0)
					security = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					security = null;
					return iRetVal;
				}
				else
				{
					setDataType(88, security);
					setUnRecognizedField("BHS","Batch Security",strField);
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;
				//Read Batch Type
				ST batchType = (ST)getDataElement(89);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = batchType.read(strField, objIDelimiter);
				if(iRetVal == 0)
					batchType = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					batchType = null;
					setUnRecognizedField("BHS","Batch Name/ID/Type",strField);
				}
				else
				{
					setDataType(89, batchType);
					batchType = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				// Read Batch Comment
				ST batchComment = (ST)getDataElement(90);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = batchComment.read(strField, objIDelimiter);
				if(iRetVal == 0)
					batchComment = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					batchComment = null;
					setUnRecognizedField("BHS","Batch Comment",strField);
				}
				else
				{
					setDataType(90, batchComment);
					batchComment = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				//Read Batch Control ID
				ST batchControlID = (ST)getDataElement(91);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = batchControlID.read(strField, objIDelimiter);
				if(iRetVal == 0)
					batchControlID = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					batchControlID = null;
					setUnRecognizedField("BHS","Batch Control ID",strField);
				}
				else
				{
					setDataType(91, batchControlID);
					batchControlID = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;

				// Read Reference Batch Control ID
				ST referenceBatchControlID = (ST)getDataElement(92);
				do
				{
					strField=strField+strSegmentStream.charAt(++i);
				
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = referenceBatchControlID.read(strField, objIDelimiter);
				if(iRetVal == 0)
					referenceBatchControlID = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					referenceBatchControlID = null;
					setUnRecognizedField("BHS","Reference Batch Control ID",strField);
				}
				else
				{
					setDataType(92, referenceBatchControlID);
					referenceBatchControlID = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;
				
				//Batch Sending Network Address
				HD batchSendingNetworkAddress = (HD)getDataElement(2271);
				do
				{
					strField = strField + strSegmentStream.charAt(++i);
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = batchSendingNetworkAddress.read(strField, objIDelimiter);
				if(iRetVal == 0)
					batchSendingNetworkAddress = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					batchSendingNetworkAddress = null;
					setUnRecognizedField("BHS","Batch Sending Network Address",strField);
				}
				else
				{
					setDataType(2271 , batchSendingNetworkAddress);
					batchSendingNetworkAddress = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;
				
				//Batch Receiving Network Address
				HD batchReceivingNetworkAddress = (HD)getDataElement(2272);
				do
				{
					strField = strField + strSegmentStream.charAt(++i);
				}while(strSegmentStream.charAt(i)!='|' && strSegmentStream.charAt(i)!='\r');
				iRetVal = batchReceivingNetworkAddress.read(strField, objIDelimiter);
				if(iRetVal == 0)
					batchReceivingNetworkAddress = null;
				else if(iRetVal == HL7Constants.HL7_FUNCTION_FAIL)
				{
					batchReceivingNetworkAddress = null;
					setUnRecognizedField("BHS","Batch Receiving Network Address",strField);
				}
				else
				{
					setDataType(2271 , batchReceivingNetworkAddress);
					batchReceivingNetworkAddress = null;
				}
				strField = "";
				cReadChar = '\0';
				cReadChar = strSegmentStream.charAt(i);
				if(cReadChar != objDelimiter.cFieldSeparator)
					break;
				
			}while((strSegmentStream.charAt(i) != '\0') &&  (strSegmentStream.charAt(i) != '\r'));		

			if((cReadChar == '\r'))
			{
					return HL7Constants.HL7_FUNCTION_SUCCESS;

			}
			else
			{
				String strMessage = "Invalid segment teminator";
				throw new InvalidDelimiterException(strMessage);
			}
		}
		catch(InvalidDataTypeException ex)
		{
			throw new InvalidSegmentException(this.getClass().getSimpleName(), ex);
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(this.getClass().getSimpleName(),ex);
		}
		catch(InvalidFieldException ex)
		{
			throw new InvalidSegmentException(this.getClass().getSimpleName(),ex);
		}
		catch(InvalidDelimiterException ex)
		{
			throw new InvalidSegmentException(this.getClass().getSimpleName(),ex);
		}
	}
}
