/*******************************************************************************
 *  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.CQ;
import cdac.medinfo.sdk.hl7282.baselibs.CWE;
import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.FT;
import cdac.medinfo.sdk.hl7282.baselibs.ID;
import cdac.medinfo.sdk.hl7282.baselibs.NM;
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;
import cdac.medinfo.sdk.hl7282.utils.SingleCollection;

/**
 * PSH - Product Summary Header Segment.<p>
 * <p>Represents an HL7 PSH message segment. 
 * This segment has the following fields:</p><p>
 * PSH-1: Report Type (ST)<b>Required</b><br> 
 * PSH-2: Report Form Identifier (ST)<b>Optional</b><br> 
 * PSH-3: Report Date (DTM)<b>Required</b><br> 
 * PSH-4: Report Interval Start Date (DTM)<b>Optional</b><br> 
 * PSH-5: Report Interval End Date (DTM)<b>Optional</b><br> 
 * PSH-6: Quantity Manufactured (CQ)<b>Optional</b><br> 
 * PSH-7: Quantity Distributed (CQ)<b>Optional</b><br> 
 * PSH-8: Quantity Distributed Method (ID)<b>Optional</b><br> 
 * PSH-9: Quantity Distributed Comment (FT)<b>Optional</b><br> 
 * PSH-10: Quantity in Use (CQ)<b>Optional</b><br> 
 * PSH-11: Quantity in Use Method (ID)<b>Optional</b><br> 
 * PSH-12: Quantity in Use Comment (FT)<b>Optional</b><br> 
 * PSH-13: Number of Product Experience Reports Filed by Facility (NM)<b>Optional</b><br> 
 * PSH-14: Number of Product Experience Reports Filed by Distributor (NM)<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 PSH extends Segment    
{
	

	/**
	 * Constructs the PSH segment.
	 */
	public PSH()
	{super(EnumSegments.HL7_SEG_PSH);
	}

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

	/**
	 * Retrieves the No Of Product Exp Report Filed By Distributor.
	 * This field contains the number of product experience reports filed by distributor.
	 * @return ISingleCollection<NM> - noOfProductExpReportFiledByDistributor
	 */
	public ISingleCollection<NM> getNoOfProductExpReportFiledByDistributor() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1246);
		ISingleCollection<NM> objDataList = new SingleCollection<NM>(); 
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				NM objNM = (NM)objDataType;
				objDataList.add(objNM);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the No Of Product Exp Report Filed By Facility.
	 * This field contains the number of product experience reports filed by facility.
	 * @return ISingleCollection<NM> - noOfProductExpReportFiledByFacility
	 */
	public ISingleCollection<NM> getNoOfProductExpReportFiledByFacility() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1245);
		ISingleCollection<NM> objDataList = new SingleCollection<NM>(); 
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				NM objNM = (NM)objDataType;
				objDataList.add(objNM);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the Quantity Distributed.
	 * This field is used to send the number of units of the product which is distribute during the reporting interval.  
	 * @return CQ - quantityDistributed
	 */
	public CQ getQuantityDistributed() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1239);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CQ)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity Distributed Comment.
	 * This field is use for any explanatory text needed but in particular should provide a description of the estimation method used. 
	 * @return FT - quantityDistributedComment
	 */
	public FT getQuantityDistributedComment() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1241);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (FT)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity Distributed Method.
	 * @return ID - quantityDistributedMethod
	 */
	public ID getQuantityDistributedMethod() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1240);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity in Use.
	 * This field is used to send the number of units of the product which were in use during the reporting interval.  
	 * @return CQ - quantityinUse
	 */
	public CQ getQuantityinUse() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1242);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CQ)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity in Use Comment.
	 * @return FT - quantityinUseComment
	 */
	public FT getQuantityinUseComment() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1244);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (FT)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity in Use Method.
	 * This field contains the method use for measuring the quantity in use.  
	 * @return ID - quantityinUseMethod
	 */
	public ID getQuantityinUseMethod() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1243);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ID)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Quantity Manufactured.
	 *  during the reporting interval.
	 * @return CQ - quantityManufactured
	 */
	public CQ getQuantityManufactured() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1238);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (CQ)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Report Date.
	 * This field contains the date as assigned by the sender.
	 * @return DTM - reportDate
	 */
	public DTM getReportDate() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1235);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Report Form Identifier.
	 * This field contains the form descriptor which describes the report.  
	 * @return ST - reportFormIdentifier
	 */
	public ST getReportFormIdentifier() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1297);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Report Interval End Date.
	 * This field contains the date which marks the inclusive end of the time interval covered by the current report.
	 * @return DTM - reportIntervalEndDate
	 */
	public DTM getReportIntervalEndDate() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1237);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Report Interval Start Date.
	 * This field contains the date that marks the beginning of the time interval covere by the current report.
	 * @return DTM - reportIntervalStartDate
	 */
	public DTM getReportIntervalStartDate() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1236);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (DTM)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Retrieves the Report Type.
	 * This field contains the name, title, or other description of the report. 
	 * @return ST - reportType
	 */
	public ST getReportType() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1233);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}

	/**
	 * Add the No Of Product Exp Report Filed By Distributor.
	 * This field contains the number of product experience reports filed by distributor.
	 * @param strNoOfProductExpReportFiledByDistributor This field contains the String Value of Number 
	 * 													Of Product Experiance Report Filed By Distributor
	 */ 
	public void addNoOfProductExpReportFiledByDistributor (String strNoOfProductExpReportFiledByDistributor) 
	{
		NM noOfProductExpReportFiledByDistributor  = (NM)getDataElement(1246);
		noOfProductExpReportFiledByDistributor.setValue(strNoOfProductExpReportFiledByDistributor); 
		addNoOfProductExpReportFiledByDistributor(noOfProductExpReportFiledByDistributor);

	} 

	/** 
	 * Add the No Of Product Exp Report Filed By Distributor.
	 * This field contains the number of product experience reports filed by distributor.
	 * @param objnoOfProductExpReportFiledByDistributor Object of No Of Product Exp Report Filed By Distributor.
	 */ 
	public void addNoOfProductExpReportFiledByDistributor(NM objnoOfProductExpReportFiledByDistributor)
	{
		addDataType(1246,objnoOfProductExpReportFiledByDistributor);

	} 

	/** 
	 * Set the No Of Product Exp Report Filed By Distributor.
	 * This field contains the number of product experience reports filed by distributor.
	 * @param objnoOfProductExpReportFiledByDistributorList List of No Of Product Exp Report Filed By Distributor.
	 */ 
	@SuppressWarnings("unchecked")
	public void setNoOfProductExpReportFiledByDistributor(ISingleCollection<NM> objnoOfProductExpReportFiledByDistributorList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objnoOfProductExpReportFiledByDistributorList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1246,objCollection);
	}

	/**
	 * Add the No Of Product Exp Report Filed By Facility.
	 * This field contains the number of product experience reports filed by facility.
	 * @param strNoOfProductExpReportFiledByFacility This field contains the String Value of Number 
	 * 													Of Product Experiance Report Filed By Facility
	 */ 
	public void addNoOfProductExpReportFiledByFacility (String strNoOfProductExpReportFiledByFacility) 
	{
		NM noOfProductExpReportFiledByFacility  = (NM)getDataElement(1245);
		noOfProductExpReportFiledByFacility.setValue(strNoOfProductExpReportFiledByFacility); 
		addNoOfProductExpReportFiledByFacility(noOfProductExpReportFiledByFacility);

	} 

	/** 
	 * Add the No Of Product Exp Report Filed By Facility.
	 * This field contains the number of product experience reports filed by facility.
	 * @param objnoOfProductExpReportFiledByFacility Object of No Of Product Exp Report Filed By Facility.
	 */ 
	public void addNoOfProductExpReportFiledByFacility(NM objnoOfProductExpReportFiledByFacility)
	{
		addDataType(1245,objnoOfProductExpReportFiledByFacility);

	} 

	/** 
	 * Set the No Of Product Exp Report Filed By Facility.
	 * This field contains the number of product experience reports filed by facility.
	 * @param objnoOfProductExpReportFiledByFacilityList List of No Of Product Exp Report Filed By Facility.
	 */ 
	@SuppressWarnings("unchecked")
	public void setNoOfProductExpReportFiledByFacility(ISingleCollection<NM> objnoOfProductExpReportFiledByFacilityList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objnoOfProductExpReportFiledByFacilityList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1245,objCollection);
	}

	/**
	 * Set the Quantity Distributed.
	 * This field is used to send the number of units of the product which is distribute during the reporting interval.  
	 * @param strQuantity Specifies the numeric quantity or amount of an entity.
	 * @param objUnits Specifies the units in which the quantity is expressed. 
	 */ 
	public void setQuantityDistributed (String strQuantity,CWE objUnits) 
	{
		CQ quantityDistributed  = (CQ)getDataElement(1239);
		quantityDistributed.setQuantity(strQuantity);
		quantityDistributed.setUnits(objUnits); 
		setQuantityDistributed(quantityDistributed);

	} 

	/** 
	 * Set the Quantity Distributed.
	 * This field is used to send the number of units of the product which is distribute during the reporting interval.  
	 * @param objquantityDistributed Object of  Quantity Distributed.
	 */ 
	public void setQuantityDistributed(CQ objquantityDistributed)
	{
		setDataType(1239,objquantityDistributed);

	}

	/**
	 * Set the Quantity Distributed Comment.
	 * This field is use for any explanatory text needed but in particular should provide a description of the estimation method used. 
	 * @param strQuantityDistributedComment This field contains the String Value of Quantity Distributed Comment 
	 */ 
	public void setQuantityDistributedComment (String strQuantityDistributedComment) 
	{
		FT quantityDistributedComment  = (FT)getDataElement(1241);
		quantityDistributedComment.setValue(strQuantityDistributedComment); 
		setQuantityDistributedComment(quantityDistributedComment);

	} 

	/** 
	 * Set the Quantity Distributed Comment.
	 * This field is use for any explanatory text needed but in particular should provide a description of the estimation method used. 
	 * @param objquantityDistributedComment Object of Quantity Distributed Comment. 
	 */ 
	public void setQuantityDistributedComment(FT objquantityDistributedComment)
	{
		setDataType(1241,objquantityDistributedComment);

	}

	/**
	 * Set the Quantity Distributed Method.
	 * @param strQuantityDistributedMethod This field contains the String Value of Quantity Distributed Method 
	 */ 
	public void setQuantityDistributedMethod (String strQuantityDistributedMethod) 
	{
		ID quantityDistributedMethod  = (ID)getDataElement(1240);
		quantityDistributedMethod.setValue(strQuantityDistributedMethod); 
		setQuantityDistributedMethod(quantityDistributedMethod);

	} 

	/** 
	 * Set the Quantity Distributed Method.
	 * @param objquantityDistributedMethod Object of  Quantity Distributed Method.
	 */ 
	public void setQuantityDistributedMethod(ID objquantityDistributedMethod)
	{
		setDataType(1240,objquantityDistributedMethod);

	}
	/**
	 * Set the Quantity in Use.
	 * This field is used to send the number of units of the product which were in use during the reporting interval.  
	 * @param strQuantity Specifies the numeric quantity or amount of an entity.
	 * @param objUnits Specifies the units in which the quantity is expressed. 
	 */ 
	public void setQuantityinUse (String strQuantity,CWE objUnits) 
	{
		CQ quantityinUse  = (CQ)getDataElement(1242);
		quantityinUse.setQuantity(strQuantity);
		quantityinUse.setUnits(objUnits); 
		setQuantityinUse(quantityinUse);

	} 

	/** Set the Quantity in Use.
	 * This field is used to send the number of units of the product which were in use during the reporting interval.  
	 * @param strQuantity Specifies the numeric quantity or amount of an entity.
	 * @param objUnits Specifies the units in which the quantity is expressed. 
	 */ 
	public void setQuantityinUse(CQ objquantityinUse)
	{
		setDataType(1242,objquantityinUse);

	}

	/**
	 * Set the Quantity in Use Comment. 
	 * @param strQuantityinUseComment Object of Quantity in Use Comment.  
	 */ 
	public void setQuantityinUseComment (String strQuantityinUseComment) 
	{
		FT quantityinUseComment  = (FT)getDataElement(1244);
		quantityinUseComment.setValue(strQuantityinUseComment); 
		setQuantityinUseComment(quantityinUseComment);

	} 

	/** 
	 * Set the Quantity in Use Comment. 
	 * @param objquantityinUseComment Object of  Quantity in Use Comment.
	 */ 
	public void setQuantityinUseComment(FT objquantityinUseComment)
	{
		setDataType(1244,objquantityinUseComment);

	}

	/**
	 * Set the Quantity in Use Method.
	 * This field contains the method use for measuring the quantity in use.  
	 * @param strQuantityinUseMethod This field contains the String Value of Quantityin Use Method 
	 */ 
	public void setQuantityinUseMethod (String strQuantityinUseMethod) 
	{
		ID quantityinUseMethod  = (ID)getDataElement(1243);
		quantityinUseMethod.setValue(strQuantityinUseMethod); 
		setQuantityinUseMethod(quantityinUseMethod);

	} 

	/** 
	 * Set the Quantity in Use Method.
	 * This field contains the method use for measuring the quantity in use.  
	 * @param objquantityinUseMethod Object of Quantity in Use Method. 
	 */ 
	public void setQuantityinUseMethod(ID objquantityinUseMethod)
	{
		setDataType(1243,objquantityinUseMethod);

	}

	/**
	 * Set the Quantity Manufactured.
	 * @param strQuantity Specifies the numeric quantity or amount of an entity.
	 * @param objUnits Specifies the units in which the quantity is expressed. 
	 */ 
	public void setQuantityManufactured (String strQuantity,CWE objUnits) 
	{
		CQ quantityManufactured  = (CQ)getDataElement(1238);
		quantityManufactured.setQuantity(strQuantity);
		quantityManufactured.setUnits(objUnits); 
		setQuantityManufactured(quantityManufactured);

	} 

	/** 
	 * Set the Quantity Manufactured.
	 * @param objquantityManufactured OBject of Quantity Manufactured. 
	 */ 
	public void setQuantityManufactured(CQ objquantityManufactured)
	{
		setDataType(1238,objquantityManufactured);

	}

	/**
	 * Set the Report Date.
	 * This field contains the date as assigned by the sender.
	 * @param strTime Specifies a point in time using a 24-hour clock notation. 
	 */ 
	public void setReportDate (String strTime) 
	{
		DTM reportDate  = (DTM)getDataElement(1235);
		reportDate.setValue(strTime);		 
		setReportDate(reportDate);
	} 

	/** Set the Report Date.
	 * This field contains the date as assigned by the sender.
	 * @param objreportDate Object of Report Date.
	 */ 
	public void setReportDate(DTM objreportDate)
	{
		setDataType(1235,objreportDate);

	}

	/**
	 * Set the Report Form Identifier.
	 * This field contains the form descriptor which describes the report.  
	 * @param strReportFormIdentifier This field contains the String Value of Report Form Identifier 
	 */ 
	public void setReportFormIdentifier (String strReportFormIdentifier) 
	{
		ST reportFormIdentifier  = (ST)getDataElement(1297);
		reportFormIdentifier.setValue(strReportFormIdentifier); 
		setReportFormIdentifier(reportFormIdentifier);

	} 

	/** 
	 * Set the Report Form Identifier.
	 * This field contains the form descriptor which describes the report.  
	 * @param objreportFormIdentifier Object of Report Form Identifier. 
	 */ 
	public void setReportFormIdentifier(ST objreportFormIdentifier)
	{
		setDataType(1297,objreportFormIdentifier);

	}

	/**
	 * Set the Report Interval End Date.
	 * This field contains the date which marks the inclusive end of the time interval covered by the current report.
	 * @param strTime Specifies a point in time using a 24-hour clock notation. 
	 */ 
	public void setReportIntervalEndDate (String strTime)  
	{
		DTM reportIntervalEndDate  = (DTM)getDataElement(1237);
		reportIntervalEndDate.setValue(strTime);		
		setReportIntervalEndDate(reportIntervalEndDate);
	} 

	/** 
	 * Set the Report Interval End Date.
	 * This field contains the date which marks the inclusive end of the time interval covered by the current report.
	 * @param objreportIntervalEndDate Object of Report Interval End Date.
	 */ 
	public void setReportIntervalEndDate(DTM objreportIntervalEndDate)
	{
		setDataType(1237,objreportIntervalEndDate);

	}

	/**
	 * Set the Report Interval Start Date.
	 * This field contains the date that marks the beginning of the time interval covere by the current report.
	 * @param strTime Specifies a point in time using a 24-hour clock notation. 
	 */ 
	public void setReportIntervalStartDate (String strTime) 
	{
		DTM reportIntervalStartDate  = (DTM)getDataElement(1236);
		reportIntervalStartDate.setValue(strTime);		 
		setReportIntervalStartDate(reportIntervalStartDate);

	} 

	/** 
	 * Set the Report Interval Start Date.
	 * This field contains the date that marks the beginning of the time interval covere by the current report.
	 * @param objreportIntervalStartDate Object of Report Interval Start Date.
	 */ 
	public void setReportIntervalStartDate(DTM objreportIntervalStartDate)
	{
		setDataType(1236,objreportIntervalStartDate);

	}

	/**
	 * Set the Report Type.
	 * This field contains the name, title, or other description of the report.
	 * @param strReportType This field contains the String Value of Report Type 
	 */ 
	public void setReportType (String strReportType)  
	{
		ST reportType  = (ST)getDataElement(1233);
		reportType.setValue(strReportType); 
		setReportType(reportType);

	} 

	/** 
	 * Set the Report Type.
	 * This field contains the name, title, or other description of the report.
	 * @param objreportType Object of Report Type.
	 */ 
	public void setReportType(ST objreportType)
	{
		setDataType(1233,objreportType);

	}

	/**
	 * Validates HL7 Message objects .
	 * Validate method checks for validation each and every segments in side the Message object against specified message Structure. 
	 * Validation checks include optionality of segment or group.
	 * It also verifies the number of times segment or group is repeated in message.
	 * e.g 
	 * {PSH} while parsing PSH segment validate method will check for its mandatory presence.
	 * [PSH] in this case validate will throw exception if one tries to enter more than one PSH segment.
	 * @return boolean - true or false.
	 * @throws InvalidSegmentException Throws when Segment Validation fails.
	 */
	public boolean validate() throws InvalidSegmentException
	{
		/*
		 * Report Type,Report Date are required fields.
		 */
		try
		{
			super.validate();

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