

package gov.va.med.cds.hapi.extension.segment;


import org.apache.commons.logging.LogFactory;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.AbstractSegment;
import ca.uhn.hl7v2.model.Group;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.Type;
import ca.uhn.hl7v2.model.Varies;
import ca.uhn.hl7v2.model.v24.datatype.CE;
import ca.uhn.hl7v2.model.v24.datatype.CNE;
import ca.uhn.hl7v2.model.v24.datatype.EI;
import ca.uhn.hl7v2.model.v24.datatype.ID;
import ca.uhn.hl7v2.model.v24.datatype.IS;
import ca.uhn.hl7v2.model.v24.datatype.NM;
import ca.uhn.hl7v2.model.v24.datatype.SI;
import ca.uhn.hl7v2.model.v24.datatype.ST;
import ca.uhn.hl7v2.model.v24.datatype.TS;
import ca.uhn.hl7v2.model.v24.datatype.XAD;
import ca.uhn.hl7v2.model.v24.datatype.XCN;
import ca.uhn.hl7v2.parser.ModelClassFactory;


/**
 * <p>
 * Represents an HL7 OBX message segment. This segment has the following fields:
 * </p>
 * <p>
 * OBX-1: Set ID - OBX (SI)<br>
 * OBX-2: Value Type (ID)<br>
 * OBX-3: Observation Identifier (CNE)<br>
 * OBX-4: Observation Sub-Id (ST)<br>
 * OBX-5: Observation Value (varies)<br>
 * OBX-6: Units (CE)<br>
 * OBX-7: References Range (ST)<br>
 * OBX-8: Abnormal Flags (IS)<br>
 * OBX-9: Probability (NM)<br>
 * OBX-10: Nature of Abnormal Test (ID)<br>
 * OBX-11: Observation Result Status (ID)<br>
 * OBX-12: Date Last Observation Normal Value (TS)<br>
 * OBX-13: User Defined Access Checks (ST)<br>
 * OBX-14: Date/Time of the Observation (TS)<br>
 * OBX-15: Producer's ID (CE)<br>
 * OBX-16: Responsible Observer (XCN)<br>
 * OBX-17: Observation Method (CE)<br>
 * OBX-18: Equipment Instance Identifier (EI)<br>
 * OBX-19: Date/Time of the Analysis (TS)<br>
 * OBX-23: Performing Organization (XON)
 * OBX-24: Performing Organization Address (XAD)
 * </p>
 * <p>
 * The get...() methods return data from individual fields. These methods do not throw exceptions and may therefore have
 * to handle exceptions internally. If an exception is handled internally, it is logged and null is returned. This is
 * not expected to happen - if it does happen this indicates not so much an exceptional circumstance as a bug in the
 * code for this class.
 * </p>
 */
public class OBX
    extends
        AbstractSegment
{

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;


	/**
     * Creates a OBX (Observation/Result) segment object that belongs to the given message.
     * The OBX.3 segment is customized to provide CNE
     */
    public OBX( Group parent, ModelClassFactory factory )
    {
        super( parent, factory );
        Message message = getMessage();
        try
        {
            this.add( SI.class, false, 1, 4, new Object[] { message }, null );
            this.add( ID.class, false, 1, 2, new Object[] { message, new Integer( 125 ) }, null );
            this.add( CNE.class, true, 1, 250, new Object[] { message }, null );
            this.add( ST.class, false, 1, 20, new Object[] { message }, null );
            this.add( Varies.class, false, 0, 65536, new Object[] { message }, null );
            this.add( CE.class, false, 1, 250, new Object[] { message }, null );
            this.add( ST.class, false, 1, 60, new Object[] { message }, null );
            this.add( IS.class, false, 1, 5, new Object[] { message, new Integer( 78 ) }, null );
            this.add( NM.class, false, 5, 5, new Object[] { message }, null );
            this.add( ID.class, false, 1, 2, new Object[] { message, new Integer( 80 ) }, null );
            this.add( ID.class, true, 1, 1, new Object[] { message, new Integer( 85 ) }, null );
            this.add( TS.class, false, 1, 26, new Object[] { message }, null );
            this.add( ST.class, false, 1, 20, new Object[] { message }, null );
            this.add( TS.class, false, 1, 26, new Object[] { message }, null );
            this.add( CE.class, false, 1, 250, new Object[] { message }, null );
            this.add( XCN.class, false, 1, 250, new Object[] { message }, null );
            this.add( CE.class, false, 0, 250, new Object[] { message }, null );
            this.add( EI.class, false, 0, 22, new Object[] { message }, null );
            this.add( TS.class, false, 1, 26, new Object[] { message }, null );
            this.add( ST.class, false, 1, 20, new Object[] { message }, null );
            this.add( ST.class, false, 1, 20, new Object[] { message }, null );
            this.add( ST.class, false, 1, 20, new Object[] { message }, null );
            this.add( gov.va.med.cds.hapi.extension.type.XON.class, false, 1, 566, new Object[] { message }, null );
            this.add( XAD.class, false, 1, 500, new Object[] { message }, null );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Can't instantiate " + this.getClass().getName(), he );
        }
    }


    /**
     * Returns Set ID - OBX (OBX-1).
     */
    public SI getSetIDOBX( )
    {
        SI ret = null;
        try
        {
            Type t = this.getField( 1, 0 );
            ret = ( SI )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Value Type (OBX-2).
     */
    public ID getValueType( )
    {
        ID ret = null;
        try
        {
            Type t = this.getField( 2, 0 );
            ret = ( ID )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Observation Identifier (OBX-3).
     */
    public CNE getObservationIdentifier( )
    {
        CNE ret = null;
        try
        {
            Type t = this.getField( 3, 0 );
            ret = ( CNE )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Observation Sub-Id (OBX-4).
     */
    public ST getObservationSubId( )
    {
        ST ret = null;
        try
        {
            Type t = this.getField( 4, 0 );
            ret = ( ST )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns a single repetition of Observation Value (OBX-5).
     *
     * @param rep the repetition number (this is a repeating field)
     * @throws HL7Exception if the repetition number is invalid.
     */
    public Varies getObservationValue( int rep )
        throws HL7Exception
    {
        Varies ret = null;
        try
        {
            Type t = this.getField( 5, rep );
            ret = ( Varies )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        return ret;
    }


    /**
     * Returns all repetitions of Observation Value (OBX-5).
     */
    public Varies[] getObservationValue( )
    {
        Varies[] ret = null;
        try
        {
            Type[] t = this.getField( 5 );
            ret = new Varies[t.length];
            for ( int i = 0; i < ret.length; i++ )
            {
                ret[i] = ( Varies )t[i];
            }
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Units (OBX-6).
     */
    public CE getUnits( )
    {
        CE ret = null;
        try
        {
            Type t = this.getField( 6, 0 );
            ret = ( CE )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns References Range (OBX-7).
     */
    public ST getReferencesRange( )
    {
        ST ret = null;
        try
        {
            Type t = this.getField( 7, 0 );
            ret = ( ST )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Abnormal Flags (OBX-8).
     */
    public IS getAbnormalFlags( )
    {
        IS ret = null;
        try
        {
            Type t = this.getField( 8, 0 );
            ret = ( IS )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns a single repetition of Probability (OBX-9).
     *
     * @param rep the repetition number (this is a repeating field)
     * @throws HL7Exception if the repetition number is invalid.
     */
    public NM getProbability( int rep )
        throws HL7Exception
    {
        NM ret = null;
        try
        {
            Type t = this.getField( 9, rep );
            ret = ( NM )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        return ret;
    }


    /**
     * Returns all repetitions of Probability (OBX-9).
     */
    public NM[] getProbability( )
    {
        NM[] ret = null;
        try
        {
            Type[] t = this.getField( 9 );
            ret = new NM[t.length];
            for ( int i = 0; i < ret.length; i++ )
            {
                ret[i] = ( NM )t[i];
            }
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Nature of Abnormal Test (OBX-10).
     */
    public ID getNatureOfAbnormalTest( )
    {
        ID ret = null;
        try
        {
            Type t = this.getField( 10, 0 );
            ret = ( ID )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Observation Result Status (OBX-11).
     */
    public ID getObservationResultStatus( )
    {
        ID ret = null;
        try
        {
            Type t = this.getField( 11, 0 );
            ret = ( ID )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Date Last Observation Normal Value (OBX-12).
     */
    public TS getDateLastObservationNormalValue( )
    {
        TS ret = null;
        try
        {
            Type t = this.getField( 12, 0 );
            ret = ( TS )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns User Defined Access Checks (OBX-13).
     */
    public ST getUserDefinedAccessChecks( )
    {
        ST ret = null;
        try
        {
            Type t = this.getField( 13, 0 );
            ret = ( ST )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Date/Time of the Observation (OBX-14).
     */
    public TS getDateTimeOfTheObservation( )
    {
        TS ret = null;
        try
        {
            Type t = this.getField( 14, 0 );
            ret = ( TS )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Producer's ID (OBX-15).
     */
    public CE getProducerSID( )
    {
        CE ret = null;
        try
        {
            Type t = this.getField( 15, 0 );
            ret = ( CE )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Responsible Observer (OBX-16).
     */
    public XCN getResponsibleObserver( )
    {
        XCN ret = null;
        try
        {
            Type t = this.getField( 16, 0 );
            ret = ( XCN )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns a single repetition of Observation Method (OBX-17).
     *
     * @param rep the repetition number (this is a repeating field)
     * @throws HL7Exception if the repetition number is invalid.
     */
    public CE getObservationMethod( int rep )
        throws HL7Exception
    {
        CE ret = null;
        try
        {
            Type t = this.getField( 17, rep );
            ret = ( CE )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        return ret;
    }


    /**
     * Returns all repetitions of Observation Method (OBX-17).
     */
    public CE[] getObservationMethod( )
    {
        CE[] ret = null;
        try
        {
            Type[] t = this.getField( 17 );
            ret = new CE[t.length];
            for ( int i = 0; i < ret.length; i++ )
            {
                ret[i] = ( CE )t[i];
            }
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns a single repetition of Equipment Instance Identifier (OBX-18).
     *
     * @param rep the repetition number (this is a repeating field)
     * @throws HL7Exception if the repetition number is invalid.
     */
    public EI getEquipmentInstanceIdentifier( int rep )
        throws HL7Exception
    {
        EI ret = null;
        try
        {
            Type t = this.getField( 18, rep );
            ret = ( EI )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        return ret;
    }


    /**
     * Returns all repetitions of Equipment Instance Identifier (OBX-18).
     */
    public EI[] getEquipmentInstanceIdentifier( )
    {
        EI[] ret = null;
        try
        {
            Type[] t = this.getField( 18 );
            ret = new EI[t.length];
            for ( int i = 0; i < ret.length; i++ )
            {
                ret[i] = ( EI )t[i];
            }
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }


    /**
     * Returns Date/Time of the Analysis (OBX-19).
     */
    public TS getDateTimeOfTheAnalysis( )
    {
        TS ret = null;
        try
        {
            Type t = this.getField( 19, 0 );
            ret = ( TS )t;
        }
        catch ( ClassCastException cce )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", cce );
            throw new RuntimeException( cce );
        }
        catch ( HL7Exception he )
        {
            LogFactory.getLog( this.getClass() ).error( "Unexpected problem obtaining field value.  This is a bug.", he );
            throw new RuntimeException( he );
        }
        return ret;
    }

}
