// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-


/// @brief	Imposes limits on location (geofence), altitude and other parameters.
///         Each breach will trigger an action or set of actions to recover. Adapted from geofence.
/// @author Andrew Tridgell
///         Andreas Antonopoulos

#ifndef AP_LIMIT_MODULE_H_
#define AP_LIMIT_MODULE_H_

#include <AP_Common.h>

// The module IDs are defined as powers of 2, to make a bit-field
enum moduleid {
    AP_LIMITS_NULLMODULE    =       0,                          // not a module - used to set the "zero" value
    AP_LIMITS_GPSLOCK               =       (1 << 0),           // a GPS-lock-required limit
    AP_LIMITS_GEOFENCE              =       (1 << 1),           // fence within a set of coordinates
    AP_LIMITS_ALTITUDE              =       (1 << 2)            // altitude limits
};

extern const prog_char_t *      get_module_name(enum moduleid i);

// an integer type big enough to fit a bit field for all modules. We have 3 modules, so 8-bit int is enough.
typedef uint8_t LimitModuleBits;

class AP_Limit_Module {

public:
    AP_Limit_Module(enum moduleid id);     // initialize a new module


    bool        init();                                                                 // initialize self

    virtual moduleid                get_module_id();
    virtual bool                    enabled();
    virtual bool                    required();
    virtual AP_Limit_Module *       next();      // return next module in linked list

    virtual void                    link(AP_Limit_Module *m);             // link the next module in the linked list

    virtual bool                    triggered();             // trigger check function

    virtual void                    action();              // recovery action

protected:
    AP_Int8                         _enabled;     // often exposed as a MAVLink parameter
    AP_Int8                         _required;
    AP_Int8                         _triggered;

private:
    enum moduleid                   _id;
    AP_Limit_Module *               _next;
};


#endif /* AP_LIMIT_MODULE_H_ */
