#ifndef SMARTSAMPLER_SMARTSAMPLER_HH
#define SMARTSAMPLER_SMARTSAMPLER_HH

#include "PeriodicTask.h"
#include "SmartSamplerInterfaces.hh"
#include "SmartSamplerData.hh"
#include "SmartSamplerInput.hh"
#include "SmartSamplerOutput.hh"
#include "DecisionTool/DecisionTool.hh"
#include "SSTime.hh"

// #ifdef SELF_TEST
// // All times (including period) divided by 250 in test mode.
// #define SMARTSAMPLER_PERIOD 2
// #else
// #define SMARTSAMPLER_PERIOD 500
// #endif


#define SMARTSAMPLER_PERIOD 500

#define SmartSamplerName "smartSampler"

// Each time a gulper is triggered, we lock out all other gulpers for
// SYSTEM_LOCKOUT_MIN seconds, regardless of individual DT-specific
// lockouts.
#define SYSTEM_LOCKOUT_MIN 5

/****************************************************************************
 *
 * This class defines the periodic task which is the main body of the
 * smart sampler.  Loads configuration files, instantiates
 * DecisionTool's, keeps track of the current decision making state
 * and decides when to trigger the next gulper.  Uses a shared memory
 * interface to communicate with the SmartSamplerServer, which
 * implements the task interface for external queries and
 * manipulation.
 *
 ****************************************************************************/
class SmartSampler :public PeriodicTask {
public:
  typedef struct{
    char *name;  // Name of instance (not model)
    int id;      // Unique id (just index into the vector)
    DecisionTool *inst; // Pointer to the tool.
    DecisionTool::model_type model; // model identifier
    bool suspend; // Is this guy suspended?
    double lasttime; // time of last gulp for testing maxwait
    double minwait; // min time (lockout between gulps)
    double maxwait; // max time (force consecutive gulps)
  }dt_info_t;

  typedef struct{
    SmartSamplerIF::GulperState state;
    short dtid;  // DecisionTool instance assigned to this gulper.
    double time; // Time (in seconds) of entry into given state.
  }gulp_info_t;

  // Constructer
  SmartSampler(int millisec);
  // Destructer
  ~SmartSampler();

  
private:
  gulp_info_t         gulps[NGULPERS];
  std::vector<dt_info_t> dtinfo;
  typedef std::vector<dt_info_t>::iterator dti_t;

  SSTime sst;
  SmartSamplerInput cmd_queue_rd;
  SmartSamplerOutput shared_mem_wr;
  SmartSamplerInterfaces ssi;
  SmartSamplerData ssd;

  // Basic method called periodically to update state and take action.
  void callback();

  // Method to load configuration file
  void loadConfig();

  // Method to handle any command messages from the server.
  void checkMessages();

  // Method to dump the output for consumption by the server.
  void dumpOutput();

  // Diagnostic tool: dump a little state for the given DT.
  void dumpDTState(short dtid);
  // Some simple methods for managing the lists.
  int nextGulper(short dtid);
}; // SmartSampler

#endif // SMARTSAMPLER_SMARTSAMPLER_HH
