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

#ifndef FRONTTRACKING_H_
#define FRONTTRACKING_H_

#include "component/Behavior.h"
#include "data/Location.h"

class UniversalDataReader;

/**
 *  Contains the FrontTracking Behavior/Command.  This is a very
 *  simple routine that simply points the nose of the vehicle
 *  at the indicated waypoint, until the waypoint is reached.
 *  If a angle is specified, then the waypoiny is
 *  reached when the vehicle is within the specified radius
 *  of the waypoint.
 *
 *  /todo implement waypoint satisfaction by "passing" waypoint
 *
 *  FrontTracking.h should only be included by FrontTracking.cpp
 *  Other classes should include FrontTrackingIF.h
 *
 *  \ingroup modules_controller
 */
class FrontTracking : public Behavior
{
public:

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

    virtual ~FrontTracking();

    /// Read settings
    void readSettings();

    /// Initialize function
    void initialize( void );

    /// Returns true when vehicle has "arrived"
    /// within the angle of the waypoint
    bool isSatisfied();

    /// runs only if unsatisfied
    bool runIfUnsatisfied();

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

    /// Uninit function
    void uninitialize( void );

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

protected:

    /// Desired Bearing
    float northHdgSetting_, southHdgSetting_, eastHdgSetting_, westHdgSetting_, nEHdgSetting_, nWHdgSetting_, sEHdgSetting_, sWHdgSetting_, searchHdgSetting_, searchHdgSettingPrevious_, latNorthWallSetting_, latSouthWallSetting_, lonWestWallSetting_, lonEastWallSetting_, waitSecondsSetting_, pastFrontNewSearchHdg_;

    Timestamp frontDetectionTime_;

    /// Current Latitude
    double latitude_;

    /// Current Longitude
    double longitude_;

    /// Current heading
    double heading_;

    ///
    bool shapeZSetting_, shapeNSetting_, flagNorthSouthSweepSetting_, flagNorthwardSweepSetting_, flagEastwardSweepSetting_, initialized_, frontDetected_, hitWallEnable_, pastFrontNewHdgEnable_, hitWallURI_, hitEastWall_, hitWestWall_, hitNorthWall_, hitSouthWall_, validFrontDetectedURI_;

    /* debug
    bool flagtmp1_, flagtmp2_, flagtmp3_, flagtmp4_;
    */

    /// counts
    int cntFrontDetection_, cntIgnoreDetection_;

    Timestamp dataTimestamp_;

    // Slate input setting variables

    // Desired headings
    SettingReader *northHdgSettingReader_;
    SettingReader *southHdgSettingReader_;
    SettingReader *eastHdgSettingReader_;
    SettingReader *westHdgSettingReader_;
    SettingReader *nEHdgSettingReader_;
    SettingReader *nWHdgSettingReader_;
    SettingReader *sEHdgSettingReader_;
    SettingReader *sWHdgSettingReader_;
    SettingReader *searchHdgSettingReader_;
    SettingReader *latNorthWallSettingReader_;
    SettingReader *latSouthWallSettingReader_;
    SettingReader *lonWestWallSettingReader_;
    SettingReader *lonEastWallSettingReader_;
    SettingReader *shapeZSettingReader_, *shapeNSettingReader_;
    SettingReader *flagNorthSouthSweepSettingReader_, *flagNorthwardSweepSettingReader_, *flagEastwardSweepSettingReader_;
    SettingReader *waitSecondsSettingReader_;

    // Current platform latitude
    UniversalDataReader *latitudeReader_;

    // Current platform longitude
    UniversalDataReader *longitudeReader_;

    // Current platform heading
    UniversalDataReader *headingReader_;

    // Gets the horizontal mode for HorizontalControl
    DataReader *horizontalModeReader_;

    // Gets the stratification front detector output
    DataReader *frontReader_;

    // Slate output variables

    // Sets the horizontal mode for HorizontalControl
    DataWriter *horizontalModeWriter_;

    // Sets the heading for HorizontalControl
    DataWriter *headingCmdWriter_;

    // Sets the hit-wall flag
    DataWriter *hitWallWriter_;

    // Sets the front detection flag
    DataWriter *frontDetectionWriter_;

    // Sets the valid front detected flag
    DataWriter *validFrontDetectedWriter_;

    // Carries out behavior on parameters
    void doRun();

    // Determines if behavior is satisfied
    bool calcSatisfied();

    // Reads in parameters used by doRun and calcSatisfied
    bool readParams();

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


};

#endif /*FRONTTRACKING_H_*/
