/*******************************************************************************
 *  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.CWE;
import cdac.medinfo.sdk.hl7282.baselibs.DR;
import cdac.medinfo.sdk.hl7282.baselibs.DTM;
import cdac.medinfo.sdk.hl7282.baselibs.EI;
import cdac.medinfo.sdk.hl7282.baselibs.HD;
import cdac.medinfo.sdk.hl7282.baselibs.SAD;
import cdac.medinfo.sdk.hl7282.baselibs.SI;
import cdac.medinfo.sdk.hl7282.baselibs.ST;
import cdac.medinfo.sdk.hl7282.baselibs.XAD;
import cdac.medinfo.sdk.hl7282.baselibs.XON;
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;

/**
 * AFF - Professional Affiliation Segment<p>
 * The AFF segment adds detailed information regarding professional affiliations with which
 * the staff member identified by the STF segment is/was associated.
 * <p>Represents an HL7 AFF message segment. 
 * This segment has the following fields:</p><p>
 * AFF-1: Set ID _ AFF (SI)<b>Required</b><br> 
 * AFF-2: Professional Organization (XON)<b>Required</b><br> 
 * AFF-3: Professional Organization Address (XAD)<b>Optional</b><br> 
 * AFF-4: Professional Organization Affiliation Date Range (DR)<b>Optional</b><br> 
 * AFF-5: Professional Affiliation Additional Information (ST)<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 AFF extends Segment   
{
	

	/**
	 *  Constructs the AFF segment.
	 */
	public AFF()
	{super(EnumSegments.HL7_SEG_AFF);	
	}

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

	/**
	 * Retrieves the Professional Affiliation Additional Information.
	 * This field specify the descriptive name of the staff member's occupation.
	 * @return String - professionalAffiliationAdditionalInformation
	 */
	public ST getProfessionalAffiliationAdditionalInformation() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1447);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (ST)objDataCollection.elementAt(0);
		else
			return null;
	}
	/**
	 * Retrieves the Professional Organization.
	 * This field specify the official name of the association promoting specific 
	 * professional interests with which the staff member is affiliated.
	 * @return XON - professionalOrganization
	 */
	public XON getProfessionalOrganization() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1444);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (XON)objDataCollection.elementAt(0);
		else
			return null;
	}
	/**
	 * Retrieves the Professional Organization Address.
	 * This field specify the postal address of the professional organization with which the Staff
	 * Member is associated.
	 * @return XAD - professionalOrganizationAddress
	 */
	public XAD getProfessionalOrganizationAddress() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1445);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (XAD)objDataCollection.elementAt(0);
		else
			return null;
	}
	/**
	 * Retrieves the Professional Organization Affiliation Date Range.
	 * This field specify the miscellaneous additional information related to the staff member's
	 * membership in the professional organization.
	 * @return ISingleCollection<DR> - professionalOrganizationAffiliationDateRange
	 */
	public ISingleCollection<DR> getProfessionalOrganizationAffiliationDateRange() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1446);
		ISingleCollection<DR> objDataList = new SingleCollection<DR>(); 
		if(objDataCollection != null && objDataCollection.size() != 0)
		{
			for(IDataType objDataType : objDataCollection)
			{
				DR objDR = (DR)objDataType;
				objDataList.add(objDR);
			}
		}
		return objDataList;
	}

	/**
	 * Retrieves the Set ID AFF.
	 * this field specify the number that identifies this transaction.
	 * @return String - setID_AFF
	 */
	public SI getSetID_AFF() 
	{
		ISingleCollection<IDataType> objDataCollection =getDataType(1427);
		if(objDataCollection != null && objDataCollection.size() != 0) 
			return (SI)objDataCollection.elementAt(0);
		else
			return null;
	}
	/**
	 * Set the Set ID AFF.
	 * this field specify the number that identifies this transaction.
	 * @param strSetID_AFF This field contains the number that identifies AFF transaction. 
	 */	
	public void setSetID_AFF(String strSetID_AFF)
	{
		SI setID_AFF  = (SI)getDataElement(1427);
		setID_AFF.setValue(strSetID_AFF); 
		setSetID_AFF(setID_AFF);
	}

	/**
	 * Set the Set ID AFF.
	 * this field specify the number that identifies this transaction.
	 * @param objSetID_AFF Object of Set ID AFF.
	 */
	public void setSetID_AFF(SI objSetID_AFF)
	{
		setDataType(1427,objSetID_AFF);
	}

	/**
	 * Set the Professional Organization.
	 * This field specify the official name of the association promoting specific 
	 * professional interests with which the staff member is affiliated.
	 * @param strOrganizationName Specifies name of the specified organization.
	 * @param objOrganizationNameTypeCode Specifies a code that represents the type of name i.e., legal name, display name.
	 * 										Suggested Values A,L,D,SL.[Refer to table No.0204]  
	 * @param objAssigningAuthority Specifies The assigning authority is a unique identifier of the system 
	 * 									(or organization or agency or department) that creates the data. 
	 * @param strIdentifierTypeCode Specifies a code corresponding to the type of identifier. 
	 * @param objAssigningFacility Specifies The place or location identifier where the identifier was first assigned to the person. 
	 * @param strNameRepresentationCode Specifies representations of the same name/address Suggested values are I,A,P [Refer table 0465] 
	 * @param strOrganizationIdentifier This component contains the sequence of characters (the code) that uniquely 
	 * 									  identifies the item being referenced by XON.1 Organization Name. 
	 * 									  This component replaces XON.3 ID Number as of v 2.5.
	 */
	public void setProfessionalOrganization(String strOrganizationName, CWE objOrganizationNameTypeCode,
			 HD objAssigningAuthority,
			String strIdentifierTypeCode, HD objAssigningFacility, String strNameRepresentationCode,
			String strOrganizationIdentifier)
	{
		XON xon  = (XON)getDataElement(1444);
		xon.setOrganizationName(strOrganizationName);
		xon.setOrganizationNameTypeCode(objOrganizationNameTypeCode);
		xon.setAssigningAuthority(objAssigningAuthority);
		xon.setIdentifierTypeCode(strIdentifierTypeCode);
		xon.setAssigningFacility(objAssigningFacility);
		xon.setNameRepresentationCode(strNameRepresentationCode);
		xon.setOrganizationIdentifier(strOrganizationIdentifier); 
		setProfessionalOrganization(xon);
	}

	/**
	 * Set the Professional Organization.
	 * This field specify the official name of the association promoting specific 
	 * professional interests with which the staff member is affiliated.
	 * @param objProfessionalOrganization Object of Professional Organization.
	 */
	public void setProfessionalOrganization(XON objProfessionalOrganization)
	{
		setDataType(1444,objProfessionalOrganization);
	}

	/**
	 * Set the Professional Organization Address.
	 * This field specify the postal address of the professional organization with which the Staff
	 * Member is associated.
	 * @param objStreetAddress Specifies the street address.
	 * @param strOtherDesignation Specifies the Second line of address. 
	 * @param strCity The city, or district or place where the addressee is located. 
	 * @param strStateOrProvince Specifies the state or province where the addressee is located.
	 * @param strZipOrPostalCode Specifies the zip or postal code where the addressee is located. 
	 * @param strCountry Specifies the country where the addressee is located.
	 * @param strAddressType Specifies the kind or type of address.
	 * @param strOtherGeographicDesignation Specifies any other geographic designation. 
	 * @param objCountyParishCode Specifies a code that represents the county in which the specified address resides. 
	 * @param objCensusTract Specifies a code that represents the census tract in which the specified address resides. 
	 * @param strAddressRepresentationCode Specifies representations of the same name/address Suggested values are I,A,P [Refer table 0465]
	 * @param objEffectiveDate It is The first date, if known, on which the address is valid and active.
	 * @param objExpirationDate It is The last date, if known, on which the address is valid and active.
	 * @param objExpirationReason indicates why this address was marked as ended.
	 * @param strTemporaryIndicator indicates whether address is considered temporary .
	 * @param strBadAddressIndicator indicates whether it is possible to contact the owning entity.
	 * @param strAddressUsage indicates how the address is intended to be used.
	 * @param strAddressee indicates the name of the person whose address is intended to be used.
	 * @param strComment indicated descriptive information
	 * @param strPreferenceOrder preference order
	 * @param objProtectionCode indicates that an address need to be protected
	 * @param objAddressIdentifier indicates a unique identifier for address
	 */ 	
	public void setProfessionalOrganizationAddress (SAD objStreetAddress,String strOtherDesignation,String strCity,
			String strStateOrProvince,String strZipOrPostalCode,String strCountry,String strAddressType,
			String strOtherGeographicDesignation,CWE objCountyParishCode,CWE objCensusTract,
			String strAddressRepresentationCode,DTM objEffectiveDate,
			DTM objExpirationDate, CWE objEXpirationReason, String strTemporaryIndicator,
			String strBadAddressIndicator, String strAddressUsage, String strAddressee, String strComment,
			String strPreferenceOrder, CWE objProtectionCode, EI objAddressIdentifier)
	{
		XAD xad = (XAD)getDataElement(1445);
		xad.setStreetAddress(objStreetAddress);
		xad.setOtherDesignation(strOtherDesignation);
		xad.setCity(strCity);
		xad.setStateOrProvince(strStateOrProvince);
		xad.setZipOrPostalCode(strZipOrPostalCode);
		xad.setCountry(strCountry);
		xad.setAddressType(strAddressType);
		xad.setOtherGeographicDesignation(strOtherGeographicDesignation);
		xad.setCountyParishCode(objCountyParishCode);
		xad.setCensusTract(objCensusTract);
		xad.setAddressRepresentationCode(strAddressRepresentationCode);
 
		xad.setEffectiveDate(objEffectiveDate);
		xad.setExpirationDate(objExpirationDate); 
		xad.setExpirationReason(objEXpirationReason);
		xad.setTemporaryIndicator(strTemporaryIndicator);
		xad.setBadAddressIndicator(strBadAddressIndicator);
		xad.setAddressUsage(strAddressUsage);
		xad.setAddressee(strAddressee);
		xad.setComment(strComment);
		xad.setPreferenceOrder(strPreferenceOrder);
		xad.setProtectionCode(objProtectionCode);
		xad.setAddressIdentifier(objAddressIdentifier);
		setProfessionalOrganizationAddress(xad);
	}

	/**
	 * Set the Professional Organization Address.
	 * This field specify the postal address of the professional organization with which the Staff
	 * Member is associated.
	 * @param objProfessionalOrganizationAddress Object of Professional Organization Address.
	 */
	public void setProfessionalOrganizationAddress(XAD objProfessionalOrganizationAddress)
	{
		setDataType(1445,objProfessionalOrganizationAddress);
	}

	/**
	 * Add the Professional Organization Affiliation Date Range.
	 * This field specify the miscellaneous additional information related to the staff member's
	 * membership in the professional organization. 
	 * @param objRangeStartDateTime Specifies the earliest date/time (time stamp) in the specified range.
	 * @param objRangeEndDateTime Specifies the latest date/time in the specified range.
	 */	
	public void addProfessionalOrganizationAffiliationDateRange(DTM objRangeStartDateTime, DTM objRangeEndDateTime) 
	{
		DR professionalOrganizationAffiliationDateRange = (DR)getDataElement(1446);
		professionalOrganizationAffiliationDateRange.setRangeStartDateTime(objRangeStartDateTime);
		professionalOrganizationAffiliationDateRange.setRangeEndDateTime(objRangeStartDateTime);

		addProfessionalOrganizationAffiliationDateRange(professionalOrganizationAffiliationDateRange);
	}

	/**
	 * Add the Professional Organization Affiliation Date Range.
	 * This field specify the miscellaneous additional information related to the staff member's
	 * membership in the professional organization.
	 * @param objProfessionalOrganizationAffiliationDateRange Object of Professional Organization Affiliation Date Range.
	 */
	public void addProfessionalOrganizationAffiliationDateRange(DR objProfessionalOrganizationAffiliationDateRange)
	{
		addDataType(1446,objProfessionalOrganizationAffiliationDateRange);
	}

	/**
	 * Set the Professional Organization Affiliation Date Range.
	 * This field specify the miscellaneous additional information related to the staff member's
	 * membership in the professional organization.
	 * @param objProfessionalOrganizationAffiliationDateRangeList List of Professional Organization Affiliation Date Range.
	 */
	@SuppressWarnings("unchecked")
	public void setProfessionalOrganizationAffiliationDateRange(ISingleCollection<DR> objProfessionalOrganizationAffiliationDateRangeList)
	{
		ISingleCollection<IDataType> objCollection = null;
		ISingleCollection<?> objUnknownCollection = (ISingleCollection<?>)objProfessionalOrganizationAffiliationDateRangeList;
		objCollection = (ISingleCollection<IDataType>)objUnknownCollection;
		setDataType(1446,objCollection);
	}

	/**
	 * Set the Professional Affiliation Additional Information.
	 * This field specify the descriptive name of the staff member's occupation.
	 * @param strProfessionalAffiliationAdditionalInformation String value of PriorityARQ
	 */
	public void setProfessionalAffiliationAdditionalInformation(String strProfessionalAffiliationAdditionalInformation) 
	{
		ST professionalAffiliationAdditionalInformation  = (ST)getDataElement(1447);			
		professionalAffiliationAdditionalInformation.setValue(strProfessionalAffiliationAdditionalInformation);
		setProfessionalAffiliationAdditionalInformation(professionalAffiliationAdditionalInformation);
	}


	public void setProfessionalAffiliationAdditionalInformation(ST objProfessionalAffiliationAdditionalInformation)


	{


		setDataType(1447,objProfessionalAffiliationAdditionalInformation);
	}

	/**
	 * 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 If Segment Validation fails. 
	 */
	@Override
	public boolean validate() throws InvalidSegmentException 
	{
		try
		{	
			/*
			 * SetID_AFF and ProfessionalOrganization are required fields of this segment.
			 */
			super.validate();

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