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

#ifndef PITCH_H_
#define PITCH_H_

#include "component/Behavior.h"

class UniversalDataReader;

/**
 *  Contains the Pitch Behavior/Command. Can point towards a depth, and be
 *  satisifed when the depth is achieved.
 *
 *  Pitch.h should only be included by Pitch.cpp
 *  Other classes should include PitchIF.h
 *
 *  \ingroup modules_guidance
 */
class Pitch : public Behavior
{
public:

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

    virtual ~Pitch();

    /// Initialize function
    void initialize();

    // Reads in behavior settings
    void readSettings();

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

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

    /// 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();

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

protected:

    // Slate input setting variables

    /// Desired depth to direct the vehicle to.
    /// If specified with Pitch, only the absolute value of Pitch is used.
    SettingReader *depthSettingReader_;

    /// Desired depth rate for the vehicle.
    /// Can be specified alone, or with Depth.
    /// Overrides Pitch and PitchRate settings
    SettingReader *depthRateSettingReader_;

    /// Desired elevator angle for the vehicle.
    /// Overrides all other settings except massPosition
    SettingReader *elevatorAngleSettingReader_;

    /// Desired massPosition for the vehicle.
    /// Overrides all other settings except ElevatorAngle
    SettingReader *massPositionSettingReader_;

    /// Desired pitch of the vehicle.
    /// If specified with PitchRate only the absolute value of PitchRate is used.
    /// If specified with Depth, only the absolute value of Pitch is used.
    SettingReader *pitchSettingReader_;

    /// Desired pitch rate of the vehicle.
    /// Valid until the vehicle reaches its maximum pitch
    /// If specified with Pitch, only the absolute value of PitchRate is used.
    SettingReader *pitchRateSettingReader_;

    // Other slate inputs

    // Slate input measurements

    /// Current depth of the vehicle
    UniversalDataReader *depthReader_;

    // Slate output variables

    /// Sets the mode for Depth Control
    DataWriter *verticalModeWriter_;

    /// Sets the specified depth for Depth Control
    DataWriter *depthCmdWriter_;

    /// Sets the specified depth rate for Depth Control
    DataWriter *depthRateCmdWriter_;

    /// Sets the elevator angle for Depth Control
    DataWriter *elevatorAngleCmdWriter_;

    /// Sets the massPosition for Depth Control
    DataWriter *massPositionCmdWriter_;

    /// Sets the specified pitch for Depth Control
    DataWriter *pitchCmdWriter_;

    /// Sets the specified pitch for Depth Control
    DataWriter *pitchRateCmdWriter_;

    // Setting Variables

    /// Desired depth of the vehicle
    float depthSetting_;

    /// Desired depthRate of the vehicle
    float depthRateSetting_;

    /// Desired elevator angle of the vehicle
    float elevatorAngleSetting_;

    /// Desired massPosition of the vehicle
    float massPositionSetting_;

    /// Desired pitch of the vehicle
    float pitchSetting_;

    /// Desired pitch rate of the vehicle
    float pitchRateSetting_;

    // Initial Variables

    /// Initial depth of the vehicle
    float initialDepth_;

    // Current Variables

    /// Current depth of the vehicle
    float depth_;

    /// Have we learned all our initial settings?
    bool initialized_;

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

};

#endif /*PITCH_H_*/
