/*******************************************************************************
 *  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.util.Locale;

import cdac.medinfo.sdk.hl7282.baselibs.CNE;
import cdac.medinfo.sdk.hl7282.baselibs.CQ;
import cdac.medinfo.sdk.hl7282.baselibs.CWE;
import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.ID;
import cdac.medinfo.sdk.hl7282.baselibs.SRT;
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.InvalidFieldException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidSegmentException;
import cdac.medinfo.sdk.hl7282.utils.EnumSegments;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.ResourceBundleWrapper;
import cdac.medinfo.sdk.hl7282.utils.SingleCollection;

/**
 * RCP - Response Control Parameter Segment.<p>
 * The RCP segment is used to restrict the amount of data that should be returned in response to query.
 * <p>Represents an HL7 RCP message segment. 
 * This segment has the following fields:</p><p>
 * RCP-1: Query Priority (ID)<b>Optional</b><br> 
 * RCP-2: Quantity Limited Request (CQ)<b>Optional</b><br> 
 * RCP-3: Response Modality (CWE)<b>Optional</b><br> 
 * RCP-4: Execution and Delivery Time (DTM)<b>Conditional</b><br> 
 * RCP-5: Modify Indicator (ID)<b>Optional</b><br> 
 * RCP-6: Sort-by Field (SRT)<b>Optional</b><br> 
 * RCP-7: Segment group inclusion (ID)<b></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 RCP extends Segment    
{
	

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


	/**
	 * Retrieves the Execution Delivery Time.
	 * @return DTM - executionDeliveryTime
	 */
	public DTM getExecutionDeliveryTime() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1441);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Modify Indicator.
	 * This field specify whether the subscription is new or is being modified.  
	 * @return String - modifyIndicator
	 */
	public ID getModifyIndicator()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1443);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity Limited Request.
	 * This field contains the maximum length of the response that is to be accept by the requesting system. 
	 * @return CQ - quantityLimitedRequest
	 */
	public CQ getQuantityLimitedRequest()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(31);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CQ)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Query Priority.
	 * @return String - queryPriority
	 */
	public ID getQueryPriority() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(27);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Response Modality.
	 * This field specify the timing and grouping of the response message(s).  
	 * @return CWE - responseModality
	 */
	public CNE getResponseModality()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1440);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CNE)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Segment group inclusion.
	 * This field specify those optional segment groups which are to be included in the response. 
	 * @return ISingleCollection<ID> - segmentgroupinclusion
	 */
	public ISingleCollection<ID> getSegmentgroupinclusion() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1594);
		ISingleCollection<ID> objDataList = new SingleCollection<ID>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				ID objID = (ID)objDataType;
				objDataList.add(objID);
			}
		}

		return objDataList;
	}

	/**
	 * Retrieves the Sort Field.
	 * This field specify by which fields the response and the order(s) is to be sorted.
	 * @return ISingleCollection<SRT> - sortField
	 */
	public ISingleCollection<SRT> getSortField() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1624);
		ISingleCollection<SRT> objDataList = new SingleCollection<SRT>();
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				SRT objSRT = (SRT)objDataType;
				objDataList.add(objSRT);
			}
		}

		return objDataList;
	}

	/**
	 * Set the Execution Delivery Time.
	 * @param strTime The point in time.
	 */ 
	public void setExecutionDeliveryTime (String strTime) 
	{
		DTM executionDeliveryTime  = (DTM)getDataElement(1441);
		executionDeliveryTime.setValue(strTime);
		setExecutionDeliveryTime(executionDeliveryTime);

	} 

	/** Set the Execution Delivery Time.
	 * @param objexecutionDeliveryTime object of Execution Delivery Time. 
	 */ 
	public void setExecutionDeliveryTime(DTM objexecutionDeliveryTime)
	{
		setDataType(1441,objexecutionDeliveryTime);

	}
	/**
	 * Set the Modify Indicator.
	 * This field specify whether the subscription is new or is being modified.  
	 * @param strModifyIndicator Use as ModifyIndicator.
	 */ 
	public void setModifyIndicator (String strModifyIndicator)  
	{
		ID modifyIndicator  = (ID)getDataElement(1443);
		modifyIndicator.setValue(strModifyIndicator); 
		setModifyIndicator(modifyIndicator);
	} 

	/** Set the Modify Indicator.
	 * This field specify whether the subscription is new or is being modified.  
	 * @param objmodifyIndicator object of  ModifyIndicator.
	 */ 
	public void setModifyIndicator(ID objmodifyIndicator)
	{
		setDataType(1443,objmodifyIndicator);

	}
	/**
	 * Set the Quantity Limited Request.
	 * This field contains the maximum length of the response that is to be accept by the requesting system.
	 * @param strQuantity Specifies the numeric quantity or amount of an entity.
	 * @param objUnits Specifies the units in which the quantity is expressed. 
	 */ 
	public void setQuantityLimitedRequest (String strQuantity,CWE objUnits) 
	{
		CQ quantityLimitedRequest  = (CQ)getDataElement(31);
		quantityLimitedRequest.setQuantity(strQuantity);
		quantityLimitedRequest.setUnits(objUnits); 
		setQuantityLimitedRequest(quantityLimitedRequest);

	} 

	/** Set the Quantity Limited Request.
	 * This field contains the maximum length of the response that is to be accept by the requesting system.
	 * @param objquantityLimitedRequest object of Quantity Limited Request. 
	 */ 
	public void setQuantityLimitedRequest(CQ objquantityLimitedRequest)
	{
		setDataType(31,objquantityLimitedRequest);

	}
	/**
	 * Set the Query Priority.
	 * @param strQueryPriority Use as QueryPriority.
	 */ 
	public void setQueryPriority (String strQueryPriority)  
	{
		ID queryPriority  = (ID)getDataElement(27);
		queryPriority.setValue(strQueryPriority); 
		setQueryPriority(queryPriority);

	} 

	/** Set the Query Priority.
	 * @param objqueryPriority object of QueryPriority.
	 */ 
	public void setQueryPriority(ID objqueryPriority)
	{
		setDataType(27,objqueryPriority);

	}
	/**
	 * Set the field which specifies the timing and grouping of the response message(s).  
	 * @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 setResponseModality(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)
	{
		CNE objCNE  = (CNE)getDataElement(1440);
		objCNE.setIdentifier(strIdentifier);
		objCNE.setText(strText);
		objCNE.setNameOfCodingSystem(strNameOfCodingSystem);
		objCNE.setAlternateIdentifier(strAlternateIdentifier);
		objCNE.setAlternateText(strAlternateText);
		objCNE.setNameOfAlternateCodingSystem(strNameOfAlternateCodingSystem); 
		objCNE.setCodingSystemVersionID(strCodingSystemVersionID);
		objCNE.setAlternateCodingSystemVersionID(strAlternateCodingSystemVersionId);
		objCNE.setOriginalText(strOriginalText);
		objCNE.setSecondAlternateIdentifier(strSecondAlternateIdentifier);
		objCNE.setSecondAlternateText(strSecondAlternateText);
		objCNE.setNameofSecondAlternateCodingSystem(strNameofSecondAlternateCodingSystem);
		objCNE.setSecondAlternateCodingSystemVersionID(strSecondAlternateCodingSystemVersionID);
		objCNE.setCodingSystemOID(strCodingSystemOID);
		objCNE.setValueSetOID(strValueSetOID);
		objCNE.setValueSetVersionID(strValueSetVersionID);
		objCNE.setAlternateCodingSystemOID(strAlternateCodingSystemOID);
		objCNE.setAlternateValueSetOID(strAlternateValueSetOID);
		objCNE.setAlternateValueSetVersionID(strAlternateValueSetVersionID);
		objCNE.setSecondAlternateCodingSystemOID(strSecondAlternateCodingSystemOID);
		objCNE.setSecondAlternateValueSetOID(strSecondAlternateValueSetOID);
		objCNE.setSecondAlternateValueSetVersionID(strSecondAlternateValueSetVersionID); 
		setResponseModality(objCNE);

	} 

	/** Set the field which specifies the timing and grouping of the response message(s).  
	 * @param objresponseModality object of ResponseModality
	 */ 
	public void setResponseModality(CNE objresponseModality)
	{
		setDataType(1440,objresponseModality);

	}
	/**
	 * Set the Segment group inclusion.
	 * This field specify those optional segment groups which are to be included in the response. 
	 * @param strSegmentgroupinclusion Use as Segmentgroupinclusion.
	 */ 
	public void addSegmentgroupinclusion (String strSegmentgroupinclusion) 
	{
		ID tempSegmentgroupinclusion  = (ID)getDataElement(1594);
		tempSegmentgroupinclusion.setValue(strSegmentgroupinclusion); 
		addSegmentgroupinclusion(tempSegmentgroupinclusion);
	} 

	/** Set the Segment group inclusion.
	 * This field specify those optional segment groups which are to be included in the response. 
	 * @param objtempSegmentgroupinclusion object of  Segmentgroupinclusion.
	 */ 
	public void addSegmentgroupinclusion(ID objtempSegmentgroupinclusion)
	{
		addDataType(1594,objtempSegmentgroupinclusion);
	}	
	/**
	 * Set the Segment group inclusion.
	 * @param objSegmentgroupinclusionList List of Segment group inclusion..
	 */	
	@SuppressWarnings("unchecked")
	public void setSegmentgroupinclusion(ISingleCollection<ID> objSegmentgroupinclusionList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objSegmentgroupinclusionList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1594,objCollection);
	}
	/**
	 * Set the Sort Field.
	 * This field specify by which fields the response and the order(s) is to be sorted.
	 * @param strSortbyField Identifies the field by which the response will be sorted. 
	 * @param strSequencing Identifies how the field or parameter will be sorted;
	 * and, if sorted, whether the sort will be case sensitive (the default) or not. 
	 */ 
	public void addSortField (String strSortbyField,String strSequencing)  
	{
		SRT tempSortField  = (SRT)getDataElement(1624);
		tempSortField.setSortbyField(strSortbyField);
		tempSortField.setSequencing(strSequencing);
		addSortField(tempSortField);

	} 

	/** Set the Sort Field.
	 * This field specify by which fields the response and the order(s) is to be sorted.
	 * @param objtempSortField object of SortField 
	 */ 
	public void addSortField(SRT objtempSortField)
	{
		addDataType(1624,objtempSortField);

	}	
	/**
	 * Set the Sort Field list.
	 * @param objSortFieldList List of Sort Field.
	 */	
	@SuppressWarnings("unchecked")
	public void setSortField(ISingleCollection<SRT> objSortFieldList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objSortFieldList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1624,objCollection);
	}

	/**
	 * 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
	{
		/*
		 * The field "executionDeliveryTime" is required only when field "queryPriority" contains value "D"
		 */
		try
		{
			super.validate();
			ISingleCollection<IDataType> objDatatype =getDataType(27);
			ID objID =(ID)objDatatype.elementAt(0);
			if(objID!= null && objID.getValue().equals("D"))
			{
				if(getDataType(1441)==null)
				{
					String str = ResourceBundleWrapper.getValue("exceptions", "InvalidField", new Locale(HL7Config.createInstance().getLocale())) + ":" + objSegmentMap.getFieldName(1441);
					
						throw new InvalidFieldException(str);
				}
			}
			return true;
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(enumSegments.getValue(),ex);
		}
	}
}