#ifndef PLUNGER_H
#define PLUNGER_H

#include <Streaming.h>
#include <Controllino.h>

#include "config.h"
#include "Addon.h"
#include "common/macros.h"
#include "config.h"
#include "types.h"
#include "./components/CurrentSensor.h"

#define STEPS 300
class Plunger : public Addon
{
public:
  class LimitSwitch
  {
  public:
    LimitSwitch(short _pin) : pin(_pin),
                              ts(0){};
    bool value;
    byte pin;
    millis_t ts;
    void loop()
    {
      if (millis() - ts > LIMIT_SWITCH_INTERVAL)
      {
        value = digitalRead(pin);
        ts = millis();
      }
    }
    void setup()
    {
      pinMode(pin, INPUT);
    }
  };

  enum E_PLUNGER_STATE
  {
    NONE = 0,
    PLUNGING = 100,
    STOPPED = 200,
    HOMING = 300,
    RETRACT = 350,
    MANUAL = 360,
    ERROR = 400
  };

  enum P_FLAGS
  {
    INITIATED = 1,
    MOVING = 2,
    RETRACTING = 3,
    RETRACTED = 4,
    FREEING = 5,
    DONE = 6,
    PAUSED = 7
  };

  Plunger(Addon *owner, AddonFnPtr _cb) : Addon(PLUNGER_STR, PLUNGER),
                                          _state(NONE),
                                          _last_state(NONE),
                                          owner(owner),
                                          check(_cb),
                                          u1(LimitSwitch(PLUNGER_LIMIT_UP_1)),
                                          l1(LimitSwitch(PLUNGER_LIMIT_DOWN_1))
  {
    // setFlag(DEBUG);
    // setFlag(LOOP);
  }
#ifdef HAS_STATES
  String state();
#endif
  void debug(Stream *stream);
  void info(Stream *stream)
  {
    //*stream << this->name;
  }

  short setup();
  short loop();

  short plunge(short val = 0);
  short home(short val = 0);
  short test(short val = 0);
  short retract();
  void zero();
  short reset(short val = 0);
  short stop(short val = 0);
  bool pause();
  bool resume();
  short goToPos(long pos, long speed);
  short moveMotor1(short val = 0);
  short moveMotor2(short val = 0);
  short moveMotors(short val = 0);
  short setSpeed(short val = 0);
  short move(short dir);
  short moveFast(short dir);

private:
  short _last_state;
  bool change(short newState);
  long positions[2];

  LimitSwitch u1;
  LimitSwitch l1;
  AddonFnPtr check;
  Addon *owner;
  short pFlags;
  bool retracting;
  short _state;
  float speed;

protected:
};

#endif
