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

#ifndef VALUEDETECT_H_
#define VALUEDETECT_H_

#include "component/Behavior.h"

class UniversalDataReader;

/**
 *  Contains the ValueDetect Behavior/Command
 *
 *  Detects values within a delta of a specified value or if no delta is
 *  specified, detects crossing over (or equaling) the specified value.
 *  Upon detection reports depth, latitude, longitude, pitch, and heading.
 *
 *  ValueDetect.h should only be included by ValueDetect.cpp
 *  Other classes should include ValueDetectIF.h
 *
 *  \ingroup modules_trigger
**/

class ValueDetect : public Behavior
{
public:

    ValueDetect( const Str& prefix, const Module* module );

    virtual ~ValueDetect();

    /// Initialize function
    void initialize( void );

    /// Read in the parameters for satisfied or runIfUnsatisfied: return true if OK.
    bool readParams( float& param );

    /// Perform the satisfied: return true if envelope "satisfied"
    bool calcSatisfied( const float param );

    /// Just do the run: ignore the results of the satisfied
    void run();

    /// Just do the satisfied: return true if envelope "satisfied"
    bool isSatisfied();

    /// Do the run, and return true if envelope "satisfied"
    bool runIfUnsatisfied();

    /// Uninit function
    void uninitialize( void );

    /// Mission Component factory interface
    static Behavior* CreateBehavior( const Str& prefix, const Module* module );

protected:

    /// if no "numProfilesThreshold" setting is provided, what to use
    static const int DEFAULT_NUM_PROFILES_THRESHOLD;

    // Slate input setting variables

    /// Surrogate variable to use instead of depth
    SettingReader *detectSettingReader_;

    /// Variable to output at time of detect
    SettingReader *outputSettingReader_;

    /// Desired value
    SettingReader *valueSettingReader_;

    /// Desired delta around the value (optional)
    SettingReader *deltaSettingReader_;

    /// Upper threshold
    SettingReader *upperThresholdSettingReader_;

    /// Lower threshold
    SettingReader *lowerThresholdSettingReader_;

    /// number of consecutive profiles threshold
    SettingReader *numProfilesThresholdSettingReader_;

    // Actual values from settings

    /// Desired value to read
    float valueSetting_;

    /// Optional delta
    float deltaSetting_;

    /// Upper threshold
    float upperThresholdSetting_;

    /// Lower threshold
    float lowerThresholdSetting_;

    /// number of consecutive profiles threshold
    int numProfilesThresholdSetting_;

    int countProfiles_;

    /// Previous reading
    float lastValue_;

    const Unit* baseUnit_;

    // Slate input measurements
    DataReader* outputReader_;

    /// Inputs from slate used for outputs
    UniversalDataReader* depthReader_;
    UniversalDataReader* latitudeReader_;
    UniversalDataReader* longitudeReader_;
    UniversalDataReader* pitchReader_;
    UniversalDataReader* headingReader_;

    // Argument output variables
    DataWriter* depthWriter_;
    DataWriter* latitudeWriter_;
    DataWriter* longitudeWriter_;
    DataWriter* pitchWriter_;
    DataWriter* headingWriter_;
    DataWriter* outputValueWriter_;

private:
    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    ValueDetect( const ValueDetect& old ); // disallow copy constructor

};

#endif /*VALUEDETECT_H_*/
