#ifndef MOTOR_OVERLOAD_H
#define MOTOR_OVERLOAD_H

#include <Arduino.h>
#include <Streaming.h>
#include "../config.h"

#include <macros.h>
#include <xmath.h>
#include <Component.h>

class MotorLoad : public Component
{
public:
  enum MSTATE
  {
    NONE = 0,
    IDLE = 1,
    LOAD = 2,
    OVERLOAD = 2,
    ERROR = 3
  };

  MotorLoad(short _pin) : dt(0),
                          pin(_pin),
                          load(0),
                          lastIdle(0),
                          lastLoad(0),
                          lastOverload(0),
                          currentState(MSTATE::NONE),
                          lastState(MSTATE::NONE),
                          Component("MotorLoad", 0, Component::COMPONENT_DEFAULT, NULL )
  {
    this->setFlag(OBJECT_RUN_FLAGS::E_OF_DEBUG);
  }

  short jammed()
  {
    return RANGE(load, MOTOR_OVERLOAD_RANGE_MIN, MOTOR_OVERLOAD_RANGE_MAX);
  }

  short idle()
  {
    return RANGE(load, MOTOR_IDLE_LOAD_RANGE_MIN, MOTOR_IDLE_LOAD_RANGE_MAX);
  }

  short shredding()
  {
    return RANGE(load, MOTOR_SHREDDING_LOAD_RANGE_MIN, MOTOR_SHREDDING_LOAD_RANGE_MAX);
  }

  short setup()
  {
    loop();
    return E_OK;
  }

  short loop()
  {
    if (now - last > MOTOR_LOAD_READ_INTERVAL)
    {
      load = analogRead(pin);
      last = now;
      uchar newState = NONE;
      if (idle())
      {
        lastIdle = now;
        newState = IDLE;
      }
      else if (jammed())
      {
        lastOverload = now;
        newState = OVERLOAD;
      }
      else if (shredding())
      {
        lastLoad = now;
        newState = LOAD;
      }

      if (newState != currentState)
      {
        dt = now;
        lastState = currentState;
        currentState = newState;
      }
    }
    return E_OK;
  }

  short ok()
  {
    /*
    if (currentState == IDLE &&
        (now - dt) > MAX_IDLE_TIME)
    {
      return E_MOTOR_DT_IDLE;
    }

    if (currentState == LOAD &&
        (now - dt) > MAX_SHRED_TIME)
    {
      return E_MOTOR_DT_OVERLOAD;
    }
    */

    return E_OK;
  }

  millis_t dt;
  uchar lastState;
  uchar currentState;
  millis_t lastIdle;
  millis_t lastLoad;
  millis_t lastOverload;

protected:
  short pin;
  short load;
};
#endif