/*******************************************************************************
 *  Copyright 2017 Center 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.EI;
import cdac.medinfo.sdk.hl7282.baselibs.ID;
import cdac.medinfo.sdk.hl7282.baselibs.MO;
import cdac.medinfo.sdk.hl7282.baselibs.SI;
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;

/**
 * PSG - Product/Service Group Segment
 * The Product/Service Group segment is used to form a logical grouping of Product/Service Line Items, Patients and Response Summaries for a particular Invoice.  
 * <p>Represents an HL7 PSG message segment.
 * This segment has the following fields:</p><p>
 * PSG-1 :  Provider Product/Service Group Number   (EI) <b>Required</b><br>
 * PSG-2 :  Payer Product/Service Group Number   (EI) <b>Optional</b><br>
 * PSG-3 :  Product/Service Group Sequence Number   (SI) <b>Required</b><br>
 * PSG-4 :  Adjudicate as Group   (ID) <b>Required</b><br>
 * PSG-5 :  Product/Service Group Billed Amount   (CP) <b>Required</b><br>
 * PSG-6 :  Product/Service Group Description   (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 PSG extends Segment{

	/**
	 * Constructs the PSG segment.
	 */
	public PSG()
	{
		super(EnumSegments.HL7_SEG_PSG);
	}
	
	/**
	 * Retrieve PSG-1   Provider Product/Service Group Number  (EI)   
	 * This field is used to Unique Product/Service Group Number assigned by the Provider Application.
	 * @return EI - object of Provider product or service group number.
	 */
	public EI getProviderProductOrServiceGroupNumber()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1950);
		if(objDataCollection != null) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set PSG-1   Provider Product/Service Group Number  (EI)   
	 * This field is used to Unique Product/Service Group Number assigned by the Provider 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 setProviderProductOrServiceGroupNumber(String strEntityIdentifier,String strNamespaceID,String strUniversalID,String strUniversalIDType)
	{
		EI objProviderProductOrServiceGroupNumber = (EI)getDataElement(1950);
		objProviderProductOrServiceGroupNumber.setEntityIdentifier(strEntityIdentifier);
		objProviderProductOrServiceGroupNumber.setNamespaceId(strNamespaceID);
		objProviderProductOrServiceGroupNumber.setUniversalId(strUniversalID);
		objProviderProductOrServiceGroupNumber.setUniversalIdType(strUniversalIDType);
		setProviderProductOrServiceGroupNumber(objProviderProductOrServiceGroupNumber);
	}
	
	/**
	 * Set PSG-1   Provider Product/Service Group Number  (EI)   
	 * This field is used to Unique Product/Service Group Number assigned by the Provider Application.
	 * @param EI - object of Provider product or service group number.
	 */ 
	public void setProviderProductOrServiceGroupNumber(EI objProviderProductOrServiceGroupNumber)
	{
		setDataType(1950, objProviderProductOrServiceGroupNumber);
	}
	
	/**
	 * Retrieve Payer Product/Service Group Number   (EI)      
	 * This field is used to define  Unique Product/Service Group Number assigned by the Payer Application
	 * @return EI - object of Payer product or service group number.
	 */
	public EI getPayerProductOrServiceGroupNumber()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1951);
		if(objDataCollection != null) 
			return (EI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set Payer Product/Service Group Number   (EI)      
	 * This field is used to defineUnique Product/Service Group 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 setPayerProductOrServiceGroupNumber(String strEntityIdentifier,String strNamespaceID,String strUniversalID,String strUniversalIDType)
	{
		EI objPayerProductOrServiceGroupNumber = (EI)getDataElement(1951);
		objPayerProductOrServiceGroupNumber.setEntityIdentifier(strEntityIdentifier);
		objPayerProductOrServiceGroupNumber.setNamespaceId(strNamespaceID);
		objPayerProductOrServiceGroupNumber.setUniversalId(strUniversalID);
		objPayerProductOrServiceGroupNumber.setUniversalIdType(strUniversalIDType);
		setPayerProductOrServiceGroupNumber(objPayerProductOrServiceGroupNumber);
	}
	
	/**
	 * Set Payer Product/Service Group Number   (EI)     
	 * This field is used to define Unique Product/Service Group Number assigned by the Payer Application.
	 * @param EI - object of Payer product or service group number.
	 */ 
	public void setPayerProductOrServiceGroupNumber(EI objPayerProductOrServiceGroupNumber)
	{
		setDataType(1951, objPayerProductOrServiceGroupNumber);
	}
	
	/**
	 * Retrieve Product/Service Group Sequence Number   (SI)   
	 * This field tell about : Unique sequence number for the Product/Service Group (3) – starts with 1, then 2, etc. for each unique Product/Service Group in this Invoice.
	 * @return SI - object of Product or service group sequence number.
	 */
	public SI getProductOrServiceGroupSequenceNumber()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1952);
		if(objDataCollection != null) 
			return (SI)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Retrieve Product/Service Group Sequence Number   (SI)   
	 * This field tell about : Unique sequence number for the Product/Service Group (3) – starts with 1, then 2, etc. for each unique Product/Service Group in this Invoice.
	 * @param strProductOrServiceGroupSequenceNumber - string of provide or service group sequence number.
	 */ 
	public void setProductOrServiceGroupSequenceNumber(String strProductOrServiceGroupSequenceNumber)
	{
		SI objProductOrServiceGroupSequenceNumber = (SI)getDataElement(1952);
		objProductOrServiceGroupSequenceNumber.setValue(strProductOrServiceGroupSequenceNumber);
		setProductOrServiceGroupSequenceNumber(objProductOrServiceGroupSequenceNumber);
	}
	
	/**
	 * Retrieve Product/Service Group Sequence Number   (SI)   
	 * This field tell about : Unique sequence number for the Product/Service Group (3) – starts with 1, then 2, etc. for each unique Product/Service Group in this Invoice.
	 * @param SI - object of provide or service group sequence number. 
	 */ 
	public void setProductOrServiceGroupSequenceNumber(SI objProductOrServiceGroupSequenceNumber)
	{
		setDataType(1952, objProductOrServiceGroupSequenceNumber);
	}
	
	/**
	 * Retrieve Adjudicate as Group   (ID)     
	 * Adjudicate all Product/Service Line Items together as a group (IPRs will be reported against the Product/Service Group).  
	 * @return ID - object of Adjudicate as Group.
	 */
	public ID getAdjudicateAsGroup()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1953);
		if(objDataCollection != null) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Retrieve Adjudicate as Group   (ID)      
	 * Adjudicate all Product/Service Line Items together as a group (IPRs will be reported against the Product/Service Group).  
	 * @param strAdjudicateAsGroup - string of Adjudicate as Group.
	 */ 
	public void setAdjudicateAsGroup(String strAdjudicateAsGroup)
	{
		ID objAdjudicateAsGroup = (ID)getDataElement(1953);
		objAdjudicateAsGroup.setValue(strAdjudicateAsGroup);
		setAdjudicateAsGroup(objAdjudicateAsGroup);
	}
	
	/**
	 * Retrieve Adjudicate as Group   (ID)      
	 * Adjudicate all Product/Service Line Items together as a group (IPRs will be reported against the Product/Service Group).  
	 * @param ID - object of Adjudicate as Group. 
	 */ 
	public void setAdjudicateAsGroup(ID objAdjudicateAsGroup)
	{
		setDataType(1953, objAdjudicateAsGroup);
	}
	
	/**
	 * Retrieve Product/Service Group Billed Amount   (CP)   
	 * This field is about Sum of all Product/Service Billed Amounts for all Product/Service Line Items for this Product/Service Group.
	 * @return CP - object of Product or service group billed amount
	 */
	public CP getProductOrServiceGroupBilledAmount()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1954);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CP)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Set Product/Service Group Billed Amount   (CP)   
	 * This field is about Sum of all Product/Service Billed Amounts for all Product/Service Line Items for this Product/Service Group.
	 * @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 obut the Type of range.
	 */ 
	public void setProductOrServiceGroupBilledAmount(MO objPrice,String strPriceType,String strFormValue,String strToValue,CWE objRangeUnits,String strRangeType)
	{
		CP objProductOrServiceGroupBilledAmount = (CP)getDataElement(1921);
		objProductOrServiceGroupBilledAmount.setPrice(objPrice);
		objProductOrServiceGroupBilledAmount.setPriceType(strPriceType);
		objProductOrServiceGroupBilledAmount.setFromValue(strFormValue);
		objProductOrServiceGroupBilledAmount.setToValue(strToValue);
		objProductOrServiceGroupBilledAmount.setRangeType(strRangeType);
		objProductOrServiceGroupBilledAmount.setRangeUnits(objRangeUnits);
		objProductOrServiceGroupBilledAmount.setRangeType(strRangeType);
		setProductOrServiceGroupBilledAmount(objProductOrServiceGroupBilledAmount);
	}
	/**
	 * Set Product/Service Group Billed Amount   (CP)   
	 * This field is about Sum of all Product/Service Billed Amounts for all Product/Service Line Items for this Product/Service Group.
	 * @param CP - object of Product Or Service Group Billed Number.
	 */ 
	public void setProductOrServiceGroupBilledAmount(CP objProductOrServiceGroupBilledAmount)
	{
		setDataType(1954, objProductOrServiceGroupBilledAmount);
	}
	
	/**
	 * Retrieve Product/Service Group Description   (ST)   
	 * This field is about Product/Service Group description or heading.
	 * @return ST - return object of Product or Service Group description  
	 */
	public ST getProductOrServiceGroupDescription()
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(2044);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}
	
	/**
	 * Retrieve Product/Service Group Description   (ST)   
	 * This field is about Product/Service Group description or heading.
	 * @param String - string of Product or service group description.
	 */ 
	public void setProductOrServiceGroupDescription(String strProductOrServiceGrouoDescription )
	{
		ST objProductOrServiceGroupDescription = (ST)getDataElement(2044);
		objProductOrServiceGroupDescription.setValue(strProductOrServiceGrouoDescription);
		setProductOrServiceGroupDescription(objProductOrServiceGroupDescription);
	}
	
	/**
	 * Retrieve Product/Service Group Description   (ST)   
	 * This field is about Product/Service Group description or heading.
	 * @param objProductOrServiceGroupDescription- object of Product or service group description.
	 */ 
	public void setProductOrServiceGroupDescription(ST objProductOrServiceGroupDescription)
	{
		setDataType(2044, objProductOrServiceGroupDescription);
	}
	
	/**
	 * 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 
	 * {PSG} while parsing PSG segment validate method will check for its mandatory presence.
	 * [PSG] in this case validate will throw exception if one tries to enter more than one PSG   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);
		}
	}
}
