#ifndef MOTOR_OVERLOAD_H
#define MOTOR_OVERLOAD_H

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

#include "../enums.h"
#include "../config.h"

// test MotorLoad::info <<210;2;64;210:info:1:0>>

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

  MotorLoad(Component *_owner,
            short _pin,
            short _id,
            int _addr) : dt(0),
                         pin(_pin),
                         value(0),
                         lastIdle(0),
                         lastLoad(0),
                         lastOverload(0),
                         currentState(NONE),
                         lastState(NONE),
                         ModbusValue<int>(_addr, MB_FC::MB_FC_READ_REGISTERS),
                         Component("MotorLoad", _id, Component::COMPONENT_DEFAULT, _owner)
  {
    //this->setFlag(OBJECT_RUN_FLAGS::E_OF_DEBUG);
    SBI(nFlags, OBJECT_NET_CAPS::E_NCAPS_MODBUS);
    setRegisterMode(MB_REGISTER_MODE::E_MB_REGISTER_MODE_READ);
  }

  short overload()
  {
    return RANGE(abs(value), MOTOR_OVERLOAD_RANGE_MIN, MOTOR_OVERLOAD_RANGE_MAX);
  }

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

  short working()
  {
    return RANGE(value, MOTOR_LOAD_RANGE_MIN, MOTOR_LOAD_RANGE_MAX);
  }

  short setup()
  {
    return E_OK;
  }

  short loop()
  {
    if (now - last > MOTOR_LOAD_READ_INTERVAL)
    {
      value = analogRead(pin);
      last = now;
      uchar newState = NONE;
      if (idle())
      {
        lastIdle = now;
        newState = IDLE;
      }
      else if (overload())
      {
        Log.errorln("MotorLoad::loop - Overload detected : %d", value);
        lastOverload = now;
        newState = OVERLOAD;
      }
      else if (working())
      {
        lastLoad = now;
        newState = LOAD;
      }

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

  short debug()
  {
    return E_OK;
    // return info();
  }

  short info()
  {
    // Log.verboseln("MotorLoad::info - Pin=%d | Key=%d | Addr=%d | Val=%d | NetVal=%d ", pin, id, addr, value, netVal());
    return E_OK;
  }

  millis_t dt;
  short lastState;
  short currentState;
  millis_t lastIdle;
  millis_t lastLoad;
  millis_t lastOverload;
  /*
    short onRegisterMethods(Bridge *bridge)
    {
     // bridge->registerMemberFunction(id, this, C_STR("setFlag"), (ComponentFnPtr)&MotorLoad::setFlag);
  //    bridge->registerMemberFunction(id, this, C_STR("clearFlag"), (ComponentFnPtr)&MotorLoad::clearFlag);
      // bridge->registerMemberFunction(id, this, C_STR("info"), (ComponentFnPtr)&MotorLoad::info);
      return E_OK;
    }
    */
  short value;
  short pin;
};
#endif