#ifndef Scheduler_h
#define Scheduler_h

#include <QTimer>
#include "UK1104.h"
#include "CommandSet.h"
#include <sys/time.h>

// High level class for running commands through the UK1104. Sequences of
// commands can be scheduled to run at certain times so the various relay
// firing and wot-not will occur in the desired sequence.
//
// It also adds some smarts to the process, verifying (when possible) that
// the command did work, or re-running the command if it is safe to do so
// on a timeout.
//
class Scheduler : public UK1104 {

   Q_OBJECT

public:

   Scheduler(const QString & devname);

   virtual
   ~Scheduler();

      // Schedule the given CommandSet to run through the UK1104 at
      // the time of day (in gettimeofday format) requested and using
      // timeoout_ms as the timeout value for each individual command.
      //
      // Note that the Scheduler now owns the CommandSet and will delete
      // it after it emits the completedSet() signal, so if you want
      // anything out of it, make a copy.
      //
   void
   RunAt(struct timeval & tv,
         CommandSet *     cs,
         int              timeout_ms);

   bool
   IsIdle();

signals:

      // This signal is emitted when the CommandSet cs is completed
      // (either by finishing, or by getting an error). The status
      // from the commands is recorded in the CommandSet.
      //
   void
   completedSet(CommandSet * cs);

private slots:

      // Scan the queue of ordered CommandSet object to see which ones
      // were scheduled to run at or prior to now and run them or
      // schedule next timeout for the time in the future when the
      // next CommandSet is supposed to run.
      //
   void
   scanQueue();

      // Each time an individual command finishes running, we get notified
      // here and can "turn the crank" to advance through the command set
      // we are currently trying to get executed.
      //
   void
   turnCrank(UK1104Errors status, QString result);

private:

   void
   RunCommandSet();

   void
   AnalyzeCommand();

   QString
   AnalyzeParens(QString s);

   CommandSet * cur_cs;
   CommandSet * old_cs;

   QString running_command;

   bool rerun_on_timeout;
   int  timeout_count;

   bool invalid_command;

   bool relay_state_known;
   bool relay_state[4];
   bool expecting_relay_state;
   bool expected_relay[4];
   QString checked_relay_command;

   QTimer sched_timer;

   CommandSet * q;

   bool in_scanQueue;
};

#endif // Scheduler_h
