#pragma once

#include <Automaton.h>
#include <Encoder.h>

class Atm_encoderInt : public Machine {
 public:
  enum { IDLE, UP, DOWN };          // STATES
  enum { EVT_UP, EVT_DOWN, ELSE };  // EVENTS

  Atm_encoderInt( void ) : Machine(){};
  Atm_encoderInt& begin( int pin1, int pin2, int divider = 1 );
  Atm_encoderInt& trace( Stream& stream );
  Atm_encoderInt& onChange( Machine& machine, int event = 0 );
  Atm_encoderInt& onChange( atm_cb_push_t callback, int idx = 0 );
  Atm_encoderInt& onChange( bool status, Machine& machine, int event = 0 );
  Atm_encoderInt& onChange( bool status, atm_cb_push_t callback, int idx = 0 );
  int state( void );
  Atm_encoderInt& range( int min, int max, bool wrap = false );
  Atm_encoderInt& set( int value );

 private:
  enum { LP_IDLE, ENT_UP, ENT_DOWN };  // ACTIONS
  Encoder *encoder;
  short pin1, pin2;
  const static char enc_states[];
  uint8_t enc_bits;
  int8_t enc_counter;
  int8_t enc_direction;
  int divider;
  int value, min, max;
  bool wrap, range_invert;
  atm_connector onup, ondown;
  // atm_timer_millis sendTimer;
  int send_rate = 20;
  int send_last = 0;


  bool count( int direction );
  int event( int id );
  void action( int id );
};