/** \file
 *
 *  Contains the IBIT class definition.
 *
 *  IBIT.h should only be included by IBIT.cpp
 *  Other classes should include IBITIF.h
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef IBIT_H_
#define IBIT_H_

#include "component/ComponentRegistry.h"
#include "component/SyncComponent.h"

class UniversalDataReader;
class UniversalDataWriter;

/**
 *  The IBIT built-in-test component provides monitoring of
 *  vehicle health on demand. If it sees a fault, it will write to
 *  a fault flag.
 *
 *  IBIT.h should only be included by IBIT.cpp
 *  Other classes should include IBITIF.h
 *
 *  \ingroup modules_builtintest
 */
class IBIT : public SyncTestComponent
{
public:

    IBIT( const Module* module );

    virtual ~IBIT();

    /// Initialize function
    void initialize( void );

    /// The actual "payload" of the component
    void run();

    /// Uninit function
    void uninitialize( void );

protected:



private:

    // read vehicle config variables
    bool readConfig( void );

    // Checks actual vs. expected positions of the control surfaces
    bool ctrlSurfaceCheckPos( float elevExpect, float ruddExpect );

    // indicates whether things are ok to run
    bool ok_;

    bool ibitPass_;

    // slate entry to let others know that IBIT is running
    DataWriter* ibitRunningStateWriter_;

    DataWriter* elevatorAngleCmdWriter_;
    DataWriter* verticalModeWriter_;
    DataWriter* horizontalModeWriter_;
    DataWriter* rudderAngleCmdWriter_;

    DataReader *elevatorAngleReader_;
    DataReader *rudderAngleReader_;
    DataReader *sBITRunningReader_;
    DataReader *sigQualityReader_;
    DataReader *goodFixReader_;

    DataReader *timeFixReader_;
    DataReader *latitudeFixReader_;
    DataReader *longitudeFixReader_;

    DataReader* batteryChargeReader_;
    DataReader* batteryVoltageReader_;

    DataReader* pressureReader_;
    DataReader* humidityReader_;

    // AHRS specific parameters:
    UniversalDataReader* headingReader_;
    UniversalDataReader* pitchReader_;
    UniversalDataReader* rollReader_;

    /// Configuration Readers
    // IBIT
    ConfigReader* batteryCapacityThresholdCfgReader_; // Amount of charge left at which we return to the surface
    ConfigReader* batteryVoltageThresholdCfgReader_;  // Amount of voltage left at which we return to the surface

    // CBIT
    ConfigReader* abortDepthCfgReader_;        // Depth at which we drop the weight. Should be greater than all depth envelopes
    ConfigReader* stopDepthCfgReader_;         // Depth at which we stop the mission. Should be greater than all depth envelopes and less than abort depth
    ConfigReader* humidityThresholdCfgReader_; // relative humidity
    ConfigReader* pressureThresholdCfgReader_; // Onboard pressure must measure greater than this offset from 1 ATM

    // Control
    ConfigReader* buoyancyNeutralCfgReader_;
    ConfigReader* elevatorLimitCfgReader_;
    ConfigReader* rudderLimitCfgReader_;
    ConfigReader* surfaceThresholdCfgReader_;
    ConfigReader* massDefaultCfgReader_;

    // Servo
    ConfigReader* ruddDeviationCfgReader_;
    ConfigReader* elevDeviationCfgReader_;

    ///*------------------- vehicle parameters --------------------------*/

    float surfaceThreshold_;
    float batteryCapacityThreshold_;
    float batteryVoltageThreshold_;
    float abortDepth_;
    float stopDepth_;
    float bitHumidityThreshold_;
    float bitPressureThreshold_;
    float buoyancyNeutral_;
    float massDefault_;
    float elevatorLimit_;
    float rudderLimit_;
    float ruddDeviation_;
    float elevDeviation_;


    ///////////////////////////////////

    Timespan ctrlTimeout_;
    Timespan commsTimeout_;
    Timestamp startTime_;

    int sigQuality_;
    bool goodFix_;

    // Used to save state since there are long potential waiting periods for this device to respond
    enum IBITState
    {
        START,
        CTRLHI,
        CTRLLO,
        CTRLCTR,
        COMMS,
        BATT,
        ENV,
        ORIENTATION,
        DONE,
        IDLE
    };

    // To hold our state
    IBITState ibitState_;

};

#endif /*IBIT_H_*/
