/*******************************************************************************
 *  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.CP;
import cdac.medinfo.sdk.hl7282.baselibs.CWE;
import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.EI;
import cdac.medinfo.sdk.hl7282.baselibs.MO;
import cdac.medinfo.sdk.hl7282.baselibs.ST;
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;

/**
 * IPR - Invoice Processing Results Segment
 * The Invoice Processing Results (IPR) segment provides summary information about an adjudicated Product/Service Group or Product/Service Line Item
 * <p>Represents an HL7 IPR message segment.
 * This segment has the following fields:</p><p>
 * IPR-1 :  IPR Identifier   (EI)<b>Required</b><br>
 * IPR-2 :  Provider Cross Reference Identifier    (EI)<b>Required</b><br>
 * IPR-3 :  Payer Cross Reference Identifier   (EI)<b>Required</b><br>
 * IPR-4 :  IPR Status   (CWE)<b>Required</b><br>
 * IPR-5 :  IPR Date/Time   (DTM)<b>Required</b><br>
 * IPR-6 :  Adjudicated/Paid Amount   (CP)<b>Optional</b><br>
 * IPR-7 :  Expected Payment Date/Time   (DTM)<b>Optional</b><br>
 * IPR-8 :  IPR Checksum   (ST)<b>Required</b><br>
 * 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 IPR extends Segment{

	/**
	 * Constructs the IPR segment.
	 */
	public IPR()
	{
		super(EnumSegments.HL7_SEG_IPR);
	}
	
	/**
	 * Retrieve IPR Identifier (EI) 
	 * This field is Unique IPR Number assigned by the Payer Application.
	 * @return EI - object of IPR Identifier.
	 */
	public EI getIPRIdentifier()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2030);
		if(objDataCollection != null) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set  Retrieve IPR Identifier (EI) 
	 * This field is Unique IPR Number assigned by the Payer Application.
	 * @param strEntityIdentifier - string of character use to identify the entity.
	 * @param strNamespaceID - Use to identify the name space id..
	 * @param strUniversalID - Use to identify the name space identity.
	 * @param strUniversalIDType - String of characters describe Universal Id Type. 
	 */ 
	public void setIPRIdentifier(String strEntityIdentifier,String strNamespaceID,String strUniversalID,String strUniversalIDType)
	{
		EI objIPRIdentifier = (EI)getDataElement(2030);
		objIPRIdentifier.setEntityIdentifier(strEntityIdentifier);
		objIPRIdentifier.setNamespaceId(strNamespaceID);
		objIPRIdentifier.setUniversalId(strUniversalID);
		objIPRIdentifier.setUniversalIdType(strUniversalIDType);
		setIPRIdentifier(objIPRIdentifier);
	}
	
	/**
	 * Set  Retrieve IPR Identifier (EI) 
	 * This field is Unique IPR Number assigned by the Payer Application.
	 * @param objIPRIdentifier - object of IPR Identifier.
	 */ 
	public void setIPRIdentifier(EI objIPRIdentifier)
	{
		setDataType(2030, objIPRIdentifier);
	}
	
	/**
	 * Retrieve Provider Cross Reference Identifier (EI) 
	 * This field is Cross reference to Provider Product/Service Group Number or Provider Product/Service Line Item Number from original Invoice.
	 * @return EI - object of Provider Cross Reference Identifier.
	 */
	public EI getProviderCrossReferenceIdentifier()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2031);
		if(objDataCollection != null) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set  Retrieve Provider Cross Reference Identifier (EI) 
	 * This field is Cross reference to Provider Product/Service Group Number or Provider Product/Service Line Item Number from original Invoice.
	 * @param strEntityIdentifier - string of character use to identify the entity.
	 * @param strNamespaceID - Use to identify the name space id..
	 * @param strUniversalID - Use to identify the name space identity.
	 * @param strUniversalIDType - String of characters describe Universal Id Type. 
	 */ 
	public void setProviderCrossReferenceIdentifier(String strEntityIdentifier,String strNamespaceID,String strUniversalID,String strUniversalIDType)
	{
		EI objProviderCrossReferenceIdentifier = (EI)getDataElement(2031);
		objProviderCrossReferenceIdentifier.setEntityIdentifier(strEntityIdentifier);
		objProviderCrossReferenceIdentifier.setNamespaceId(strNamespaceID);
		objProviderCrossReferenceIdentifier.setUniversalId(strUniversalID);
		objProviderCrossReferenceIdentifier.setUniversalIdType(strUniversalIDType);
		setProviderCrossReferenceIdentifier(objProviderCrossReferenceIdentifier);
	}
	
	/**
	 * Set  Retrieve Provider Cross Reference Identifier (EI) 
	 * This field is Cross reference to Provider Product/Service Group Number or Provider Product/Service Line Item Number from original Invoice.
	 * @param objProviderCrossReferenceIdentifier - object of Provider Cross Reference Identifier.
	 */ 
	public void setProviderCrossReferenceIdentifier(EI objProviderCrossReferenceIdentifier)
	{
		setDataType(2031, objProviderCrossReferenceIdentifier);
	}
	
	/**
	 * Retrieve Payer Cross Reference Identifier (EI) 
	 * This field is Cross reference to Payer Product/Service Group Number or Payer Product/Service Line Item Number from original Invoice.
	 * @return EI - object of Payer Cross Reference Identifier.
	 */
	public EI getPayerCrossReferenceIdentifier()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2032);
		if(objDataCollection != null) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set  Retrieve Payer Cross Reference Identifier (EI) 
	 * This field is Cross reference to Payer Product/Service Group Number or Payer Product/Service Line Item Number from original Invoice.
	 * @param strEntityIdentifier - string of character use to identify the entity.
	 * @param strNamespaceID - Use to identify the name space id..
	 * @param strUniversalID - Use to identify the name space identity.
	 * @param strUniversalIDType - String of characters describe Universal Id Type. 
	 */ 
	public void setPayerCrossReferenceIdentifier(String strEntityIdentifier,String strNamespaceID,String strUniversalID,String strUniversalIDType)
	{
		EI objPayerCrossReferenceIdentifier = (EI)getDataElement(2032);
		objPayerCrossReferenceIdentifier.setEntityIdentifier(strEntityIdentifier);
		objPayerCrossReferenceIdentifier.setNamespaceId(strNamespaceID);
		objPayerCrossReferenceIdentifier.setUniversalId(strUniversalID);
		objPayerCrossReferenceIdentifier.setUniversalIdType(strUniversalIDType);
		setPayerCrossReferenceIdentifier(objPayerCrossReferenceIdentifier);
	}
	
	/**
	 * Set  Retrieve Payer Cross Reference Identifier (EI) 
	 * This field is Cross reference to Payer Product/Service Group Number or Payer Product/Service Line Item Number from original Invoice.
	 * @param objPayerCrossReferenceIdentifier - object of Payer Cross Reference Identifier.
	 */ 
	public void setPayerCrossReferenceIdentifier(EI objPayerCrossReferenceIdentifier)
	{
		setDataType(2032, objPayerCrossReferenceIdentifier);
	}
	
	/**
	 * retrieve IPR Status   (CWE)   
	 * This field is about Processing status for the Product/Service Group (if Adjudicate as Group = "Y") or Product/Service Line Item. 
	 * @return CWE - object of IPR Status.
	 */
	public CWE getIPRStatus()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2033);
		if(objDataCollection != null) 
			return (CWE)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set IPR Status   (CWE)   
	 * This field is about Processing status for the Product/Service Group (if Adjudicate as Group = "Y") or Product/Service Line Item. 
	 * @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 infection. 
	 * @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 setIPRStatus(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 objIPRStatus  = (CWE)getDataElement(2033);
		objIPRStatus.setIdentifier(strIdentifier);
		objIPRStatus.setText(strText);
		objIPRStatus.setNameOfCodingSystem(strNameOfCodingSystem);
		objIPRStatus.setAlternateIdentifier(strAlternateIdentifier);
		objIPRStatus.setAlternateText(strAlternateText);
		objIPRStatus.setNameOfAlternateCodingSystem(strNameOfAlternateCodingSystem); 
		objIPRStatus.setCodingSystemVersionID(strCodingSystemVersionID);
		objIPRStatus.setAlternateCodingSystemVersionId(strAlternateCodingSystemVersionId);
		objIPRStatus.setOriginalText(strOriginalText);
		objIPRStatus.setSecondAlternateIdentifier(strSecondAlternateIdentifier);
		objIPRStatus.setSecondAlternateText(strSecondAlternateText);
		objIPRStatus.setNameofSecondAlternateCodingSystem(strNameofSecondAlternateCodingSystem);
		objIPRStatus.setSecondAlternateCodingSystemVersionID(strSecondAlternateCodingSystemVersionID);
		objIPRStatus.setCodingSystemOID(strCodingSystemOID);
		objIPRStatus.setValueSetOID(strValueSetOID);
		objIPRStatus.setValueSetVersionID(strValueSetVersionID);
		objIPRStatus.setAlternateCodingSystemOID(strAlternateCodingSystemOID);
		objIPRStatus.setAlternateValueSetOID(strAlternateValueSetOID);
		objIPRStatus.setAlternateValueSetVersionID(strAlternateValueSetVersionID);
		objIPRStatus.setSecondAlternateCodingSystemOID(strSecondAlternateCodingSystemOID);
		objIPRStatus.setSecondAlternateValueSetOID(strSecondAlternateValueSetOID);
		objIPRStatus.setSecondAlternateValueSetVersionID(strSecondAlternateValueSetVersionID); 
		setIPRStatus(objIPRStatus);
	}
	
	/**
	 * Set IPR Status   (CWE)   
	 * This field is about Processing status for the Product/Service Group (if Adjudicate as Group = "Y") or Product/Service Line Item. 
	 * @param objIPRStatus - object of IPR Status.
	 */
	public void setIPRStatus(CWE objIPRStatus)
	{
		setDataType(2033, objIPRStatus);
	}
	
	/**
	 * Retrieve IPR Date/Time   (DTM)   
	 * This field is about Date/Time IPR was created.
	 * @return DTM - object of IPR Date/Time.
	 */
	public DTM getIPRDateOrTime()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2034);
		if(objDataCollection != null) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set IPR Date/Time   (DTM)   
	 * This field is about Date/Time IPR was created.
	 * @param strIPRDateOrTime - string of IPR Date/Time.
	 */
	public void setIPRDateOrTime(String strIPRDateOrTime)
	{
		DTM objIPRDateOrTime = (DTM)getDataElement(2034);
		objIPRDateOrTime.setValue(strIPRDateOrTime);
		setIPRDateOrTime(objIPRDateOrTime);
	}
	
	/**
	 * Set IPR Date/Time   (DTM)   
	 * This field is about Date/Time IPR was created.
	 * @param objIPRDateOrTime - object of IPR Date/Time.
	 */
	public void setIPRDateOrTime(DTM objIPRDateOrTime)
	{
		setDataType(2034, objIPRDateOrTime);
	}
	
	/**
	 * Retrieve Adjudicated/Paid Amount  (CP)   
	 * This field is about Adjudicated Amount for the Product/Service Group or Product/Service Line Item, which could be 0 = sum of all Payer adjustments (Adjustment Amount on ADJ).
	 * @return CP - object of Adjudicated/Paid Amount.
	 */
	public CP getAdjudicatedOrPaidAmount()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2035);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CP)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set Adjudicated/Paid Amount  (CP)   
	 * This field is about Adjudicated Amount for the Product/Service Group or Product/Service Line Item, which could be 0 = sum of all Payer adjustments (Adjustment Amount on ADJ).
	 * @param objPrice - Gives information about the Price.
	 * @param strPriceType - Gives information about Type of Price.
	 * @param strFormValue - Gives information about Form Value.
	 * @param strToValue - Tell about the To value.
	 * @param objRangeUnits - Specifies about the range of the units.
	 * @param strRangeType - Specifies about the Type of range.
	 */ 
	public void setAdjudicatedOrPaidAmount(MO objPrice,String strPriceType,String strFormValue,String strToValue,CWE objRangeUnits,String strRangeType)
	{
		CP objAdjudicatedOrPaidAmount = (CP)getDataElement(2035);
		objAdjudicatedOrPaidAmount.setPrice(objPrice);
		objAdjudicatedOrPaidAmount.setPriceType(strPriceType);
		objAdjudicatedOrPaidAmount.setFromValue(strFormValue);
		objAdjudicatedOrPaidAmount.setToValue(strToValue);
		objAdjudicatedOrPaidAmount.setRangeType(strRangeType);
		objAdjudicatedOrPaidAmount.setRangeUnits(objRangeUnits);
		objAdjudicatedOrPaidAmount.setRangeType(strRangeType);
		setAdjudicatedOrPaidAmount(objAdjudicatedOrPaidAmount);
	}
	/**
	 * Set Adjudicated/Paid Amount  (CP)   
	 * This field is about Adjudicated Amount for the Product/Service Group or Product/Service Line Item, which could be 0 = sum of all Payer adjustments (Adjustment Amount on ADJ).
	 * @param objAdjudicatedOrPaidAmount - object of Adjudicated/Paid Amount.
	 */ 
	public void setAdjudicatedOrPaidAmount(CP objAdjudicatedOrPaidAmount)
	{
		setDataType(2035, objAdjudicatedOrPaidAmount);
	}
	
	/**
	 * Retrieve Expected Payment Date/Time   (DTM)   
	 * This field is about Date payment is expected for this IPR.
	 * @return DTM - object of Expected Payment Date/Time.
	 */
	public DTM getExpectedPaymentDateOrTime()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2036);
		if(objDataCollection != null) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set Expected Payment Date/Time   (DTM)   
	 * This field is about Date payment is expected for this IPR.
	 * @param strExpectedPaymentDateOrTime - string of Expected Payment Date/Time.
	 */
	public void setExpectedPaymentDateOrTime(String strExpectedPaymentDateOrTime)
	{
		DTM objExpectedPaymentDateOrTime = (DTM)getDataElement(2036);
		objExpectedPaymentDateOrTime.setValue(strExpectedPaymentDateOrTime);
		setExpectedPaymentDateOrTime(objExpectedPaymentDateOrTime);
	}
	
	/**
	 * Set Expected Payment Date/Time   (DTM)   
	 * This field is about Date payment is expected for this IPR.
	 * @param objExpectedPaymentDateOrTime - object of Expected Payment Date/Time.
	 */
	public void setExpectedPaymentDateOrTime(DTM objExpectedPaymentDateOrTime)
	{
		setDataType(2036, objExpectedPaymentDateOrTime);
	}
	
	/**
	 * Retrieve IPR Checksum (ST)
	 * This field is about Conditional, if Status = "Accepted", then Required, else Not Permitted.
	 * @return ST - object of IPR Checksum.
	 */
	public ST getIPRChecksum()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2037);
		if(objDataCollection != null) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Retrieve IPR Checksum (ST)
	 * This field is about Conditional, if Status = "Accepted", then Required, else Not Permitted.
	 * @param strIPRChecksum - object of IPR Checksum.
	 */
	public void setIPRChecksum(String strIPRChecksum)
	{
		ST objIPRChecksum = (ST)getDataElement(2037);
		objIPRChecksum.setValue(strIPRChecksum);
		setIPRChecksum(objIPRChecksum);
	}
	
	/**
	 * Retrieve IPR Checksum (ST)
	 * This field is about Conditional, if Status = "Accepted", then Required, else Not Permitted.
	 * @param objIPRChecksum - object of IPR Checksum.
	 */
	public void setIPRChecksum(ST objIPRChecksum)
	{
		setDataType(2037, objIPRChecksum);
	}
	
	/**
	 * 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 
	 * {IPR} while parsing IPR segment validate method will check for its mandatory presence.
	 * [IPR] in this case validate will throw exception if one tries to enter more than one IPR segment.
	 * @return boolean - true or false.
	 * @throws InvalidSegmentException Throws when Segment Validation fails.
	 */
	public boolean validate() throws InvalidSegmentException
	{
		try
		{
			super.validate();
			return true;
		}
		catch(FieldMissingException ex)
		{
			throw new InvalidSegmentException(enumSegments.getValue(),ex);
		}
	}
}
