

package gov.va.med.cds.testharness.vhim400.builders;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.logging.log4j.Logger;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


public class VitalsBuilder
    extends
        AbstractEntryPointBuilder
{
    protected static Log logger = null;
    public static final String LOGGER_CONFIG_PATH = "log4j.properties";
    private static final int RECORD_VERSION = 12345;

    private int IDX;

    public static final String[] OBSERVATION_METHODS = { "Method 1", "Method 2", "Method 3", "Method 4" };
    public static final String[] QUALIFIERS = { "Qualifier 1", "Qualifier 2", "Qualifier 3", "Qualifier 4" };
    public static final String[] OBSERVED_CHARACTERITICS = { "Characteristic 1", "Characteristic 2", "Characteristic 3", "Characteristic 4" };

   
    public VitalsBuilder( )
    {
        super();
    }


    public VitalsBuilder( Random random )
    {
        super( random );
    }


    public Element makeVital( )
    {
        return makeVital( "vitalSignObservationEvents", null );
    }


    public List<Element> makeVitals( int number )
    {
        return makeVitals( number, null );
    }


    public List<Element> makeVitals( int number, Element patient )
    {
        List<Element> vitals = new ArrayList<Element>( number );
        for ( int i = 0; i < number; i++ )
        {
            vitals.add( makeVital( "vitalSignObservationEvents", patient ) );
        }
        return vitals;

    }


    public Element createEntryPointRecord( Element personIdentifier )
    {
        return makeVital( "vitalSignObservationEvents", personIdentifier );
    }


    /*
  <xsd:complexType name="VitalSignObservationEvent">
    <xsd:sequence>
      <xsd:element name="recordIdentifier" type="basedatatypes:HL72EntityIdentifier"/>
      <xsd:element name="patient" type="common:PatientLite"/>
      <xsd:element minOccurs="0" name="observationTime" type="basedatatypes:PointInTime"/>
      <xsd:element minOccurs="0" name="observationMethod" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element minOccurs="0" name="observedCharacteristic" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element minOccurs="0" name="collectionSessionTime" type="basedatatypes:PointInTime"/>
      <xsd:element minOccurs="0" name="status" type="xsd:string"/>
      <xsd:element minOccurs="0" name="supplementalOxygen" type="vitalsigns:OxygenAdministration"/>
      <xsd:element minOccurs="0" name="author" type="common:PractitionerParticipationLite"/>
      <xsd:element minOccurs="0" name="homeTelehealthMonitor" type="vitalsigns:HomeTelehealthMonitor"/>
      <xsd:element minOccurs="0" name="hospitalLocationIdentifier" type="basedatatypes:HL72LocationIdentifier"/>
      <xsd:element minOccurs="0" name="division" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element minOccurs="0" name="orderingFacilityIdentifier" type="basedatatypes:HL72OrganizationIdentifier"/>
      <xsd:element minOccurs="0" name="stopCode" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element minOccurs="0" name="vitalSignObservation" type="vitalsigns:VitalSignObservation"/>
      <xsd:element minOccurs="0" name="errorEnterer" type="common:PractitionerParticipationLite"/>
      <xsd:element maxOccurs="unbounded" minOccurs="0" name="errorReason" type="vitalsigns:ErrorReason"/>
      <xsd:element minOccurs="0" name="recordSource" type="basedatatypes:HL72FacilityIdentifier"/>
      <xsd:element name="recordVersion" type="xsd:int"/>
      <xsd:element name="recordUpdateTime" type="basedatatypes:PointInTime"/>
    </xsd:sequence>
  </xsd:complexType>
     */
    public Element makeVital( String elementName, Element patient )
    {
        IDX++ ;
        
        Element newVitalSignObservationEvent = DocumentHelper.createElement(elementName );

        Element newRecordIdentifier = createHL72EntityIdentifier( "recordIdentifier", IDX );
        newVitalSignObservationEvent.add( newRecordIdentifier );

        Element newPatient = createPatientLite("patient");
        if ( patient != null )
        {
            newPatient.element( "identifier" ).element( "identity" ).setText( patient.elementText( "identity" ) );
            newPatient.element( "identifier" ).element( "assigningFacility" ).setText( patient.elementText( "assigningFacility" ) );
            newPatient.element( "identifier" ).element( "assigningAuthority" ).setText( patient.elementText( "assigningAuthority" ) );            
        }
        newVitalSignObservationEvent.add( newPatient );

        Element newObservationTime = createPointInTime("observationTime");
        newVitalSignObservationEvent.add( newObservationTime );

        Element newObservationMethod = createHL72CodedElementLite( "observationMethod","ObservationMethod", OBSERVATION_METHODS );
        newVitalSignObservationEvent.add( newObservationMethod );

        Element newObservedCharacteristic = createHL72CodedElementLite( "observedCharacteristic", "ObservedCharacteristic", OBSERVED_CHARACTERITICS );
        newVitalSignObservationEvent.add( newObservedCharacteristic );

        Element newCollectionSessionTime = createFixedPointInTime("collectionSessionTime");
        newVitalSignObservationEvent.add( newCollectionSessionTime );

        newVitalSignObservationEvent.addElement("status").addText( "Status" );

        Element newSupplementalOxygen = makeOxygenAdministration("supplementalOxygen");
        newVitalSignObservationEvent.add( newSupplementalOxygen );

        Element author = createPractitionerParticipationLite( "author", "Author Comment", AUTHOR_IDS );
        newVitalSignObservationEvent.add( author );

        Element newHomeTelehealthMonitor = makeHomeTelehealthMonitor("homeTelehealthMonitor");
        newVitalSignObservationEvent.add( newHomeTelehealthMonitor );

        Element newHospitalLocationIdentifier = createHL72LocationIdentifier("hospitalLocationIdentifier");
        newVitalSignObservationEvent.add( newHospitalLocationIdentifier );

        Element newDivision = createHL72CodedElementLite( "division", "Division" );
        newVitalSignObservationEvent.add( newDivision );

        Element newOrderingFacilityIdentifier = createHL72OrganizationIdentifier("orderingFacilityIdentifier");
        newVitalSignObservationEvent.add( newOrderingFacilityIdentifier );

        Element newStopCode = createHL72CodedElementLite( "stopCode", "StopCode", "StopCode" );
        newVitalSignObservationEvent.add( newStopCode );

        Element newVitalSignObservation = makeVitalSignObservation("vitalSignObservation");
        newVitalSignObservationEvent.add( newVitalSignObservation );

        Element newErrorEnterer = createPractitionerParticipationLite( "errorEnterer", "ErrorEnterer Comment", AUTHOR_IDS );
        newVitalSignObservationEvent.add( newErrorEnterer );

        Element newErrorReason1 = makeErrorReason( "errorReason", "Reason 1" );
        newVitalSignObservationEvent.add( newErrorReason1 );

        Element newErrorReason2 = makeErrorReason( "errorReason", "Reason 2" );
        newVitalSignObservationEvent.add( newErrorReason2 );

        Element newRecordSource = createHL72FacilityIdentifier("recordSource");
        newVitalSignObservationEvent.add( newRecordSource );

        newVitalSignObservationEvent.addElement("recordVersion").addText( RECORD_VERSION +"");

        Element newRecordUpdateTime = createPointInTime("recordUpdateTime");
        newVitalSignObservationEvent.add( newRecordUpdateTime );

        return newVitalSignObservationEvent;
    }


    public void printVitals( List<Element> listOfResults )
    {
        printDomainRecords( listOfResults );
    }


    public void printVitals( List<Element> listOfResults, Logger aLogger )
    {
        printDomainRecords( listOfResults, aLogger );
    }


    protected void printVital( Element vital )
    {
        printDomainRecord( vital );
    }


    protected void printVital( Element vital, Logger aLogger )
    {
        printDomainRecord( vital, aLogger );
    }


    public String fillPrintBuffer( Object object )
    {
        String returnString = "";

        if ( ( object != null ) && ( object instanceof Element ) )
        {
            returnString = ((Element)object).asXML();
        }

        return returnString;
    }


    /*
  <xsd:complexType name="HomeTelehealthMonitor">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="vendor" type="xsd:string"/>
      <xsd:element minOccurs="0" name="homeAppliance" type="xsd:string"/>
      <xsd:element minOccurs="0" name="measurementDevice" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
     */
    private Element makeHomeTelehealthMonitor(String elementName )
    {
        Element newHomeTelehealthMonitor = DocumentHelper.createElement(elementName );
                
        newHomeTelehealthMonitor.addElement("vendor").addText( "Vendor" );
        newHomeTelehealthMonitor.addElement("homeAppliance").addText( "HomeAppliance" );
        newHomeTelehealthMonitor.addElement("measurementDevice").addText( "MeasurementDevice" );
        
        return newHomeTelehealthMonitor;
    }


    /*
  <xsd:complexType name="OxygenAdministration">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="flowRateValue" type="xsd:string"/>
      <xsd:element minOccurs="0" name="flowRateUnit" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element minOccurs="0" name="concentrationValue" type="xsd:string"/>
      <xsd:element minOccurs="0" name="concentrationUnit" type="basedatatypes:HL72CodedElementLite"/>
    </xsd:sequence>
  </xsd:complexType>
     */
    private Element makeOxygenAdministration( String elementName)
    {
        Element newOxygenAdministration = DocumentHelper.createElement(elementName );

        newOxygenAdministration.addElement("flowRateValue").addText( "FlowRateValue" );

        Element newFlowRateUnit = createHL72CodedElementLite( "flowRateUnit", "VistaFlowRateUnit", "FlowRateUnit 1" );
        newOxygenAdministration.add( newFlowRateUnit );

        newOxygenAdministration.addElement("concentrationValue" ).addText( "ConcentrationValue" );
        
        Element newConcentrationUnit = createHL72CodedElementLite( "concentrationUnit", "VistaConcentrationUnit", "ConcentrationUnit 1" );
        newOxygenAdministration.add( newConcentrationUnit );

        return newOxygenAdministration;
    }


    /*
  <xsd:complexType name="VitalSignObservation">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="value" type="xsd:string"/>
      <xsd:element minOccurs="0" name="unit" type="basedatatypes:HL72CodedElementLite"/>
      <xsd:element maxOccurs="unbounded" minOccurs="0" name="qualifier" type="vitalsigns:VitalSignQualifier"/>
    </xsd:sequence>
  </xsd:complexType>
     */
    /*sample xml ...
     * <vitalSignObservation>
        <value>value</value>
        <unit>
          <code>code</code>
          <displayText>displayText</displayText>
          <codingSystem>codingSystem</codingSystem>
        </unit>
        <qualifier>
          <value>
            <code>code</code>
            <displayText>displayText</displayText>
            <codingSystem>codingSystem</codingSystem>
          </value>
        </qualifier>
      </vitalSignObservation>
     */
    private Element makeVitalSignObservation( String elementName )
    {
        Element newVitalSignObservation = DocumentHelper.createElement(elementName );

        newVitalSignObservation.addElement("value").addText( "Value" );

        Element newUnit = createHL72CodedElementLite( "unit", "Unit" );
        newVitalSignObservation.add( newUnit );

        Element vitalSignQualifier1 = DocumentHelper.createElement("qualifier");
        Element newVitalSignQualifierValue1 = createHL72CodedElementLite( "value", "Qualifier1", QUALIFIERS );
        vitalSignQualifier1.add( newVitalSignQualifierValue1 );
        newVitalSignObservation.add( vitalSignQualifier1 );

        Element vitalSignQualifier2 = DocumentHelper.createElement("qualifier");
        Element newVitalSignQualifierValue2 = createHL72CodedElementLite( "value", "Qualifier2", QUALIFIERS );
        vitalSignQualifier2.add( newVitalSignQualifierValue2 );
        newVitalSignObservation.add( vitalSignQualifier2 );

        return newVitalSignObservation;
    }


    /*
  <xsd:complexType name="ErrorReason">
    <xsd:sequence>
      <xsd:element minOccurs="0" name="reason" type="basedatatypes:HL72CodedElementLite"/>
    </xsd:sequence>
  </xsd:complexType>
     */
    private Element makeErrorReason( String elementName, String reason )
    {
        Element newErrorReason = DocumentHelper.createElement(elementName );

        Element newReason = createHL72CodedElementLite( "reason", reason );
        newErrorReason.add( newReason );

        return newErrorReason;
    }

}
