// мини-класс для работы с энкодером, версия 1.0 мод

class encMinim
{
  public:
    encMinim(uint8_t clk, uint8_t dt, uint8_t sw, boolean dir);
    void tick();
    boolean isSingle();
    boolean isTurn();
    boolean isRight();
    boolean isLeft();
    boolean isHolded();
    boolean isDouble();
    boolean isHold();

  private:
    byte _clk, _dt, _sw;
    boolean _state, _lastState, _turnFlag, _swState, _swFlag, clickFlag, flagsTurn ;
    byte _encState, countClick;
    uint32_t _debTimer, encDeb;
    // 0 - ничего, 1 - лево, 2 - право, 5 - одиночный клик , 6 - двойной клик, 7 - удержание
};

encMinim::encMinim(uint8_t clk, uint8_t dt, uint8_t sw, boolean dir) {
  if (dir) {
    _clk = clk;
    _dt = dt;
  } else {
    _clk = dt;
    _dt = clk;
  }
  _sw = sw;
  pinMode (_clk, INPUT_PULLUP);
  pinMode (_dt, INPUT_PULLUP);
  pinMode (_sw, INPUT_PULLUP);
  _lastState = digitalRead(_clk);
}

void encMinim::tick() {
  _encState = 0;
  _state = digitalRead(_clk);
  _swState = digitalRead(_sw);
  if (_state != _lastState && millis() - encDeb > 2) {
    encDeb = millis();
    _turnFlag = !_turnFlag;
    if (_turnFlag ) {
      if (digitalRead(_dt) != _lastState) {
        _encState = 1;
      } else {
        _encState = 2;
      }
    }
    _lastState = _state;
  }

  if (!_swState && !_swFlag && millis() - _debTimer > 50 ) {
    _debTimer = millis();
    _swFlag = true;
    clickFlag  = true;
    countClick++;
  }
  if (_swState && _swFlag && millis() - _debTimer > 50 ) {
    _debTimer = millis();
    _swFlag = false;
  }

  if (clickFlag && !_swFlag && millis() -  _debTimer > 200  ) { // время двойного и последующих кликов
    clickFlag  = false;
    if (countClick < 2) {
      _encState = 5;
    } else {
      _encState = 7;
    }
    countClick = 0;
  }

  if (clickFlag  &&  _swFlag && millis() - _debTimer > 1000 ) {  // время удержания
    clickFlag  = false;
    _encState = 6;
    countClick = 0;
  }
  if (_encState > 0 && _encState < 5) {
    flagsTurn = true;
  }
}

boolean encMinim::isTurn() {
  if (flagsTurn) {
    flagsTurn = false;
    return true;
  } else return false;
}
boolean encMinim::isRight() {
  if (_encState == 1) {
    _encState = 0;
    return true;
  } else return false;
}
boolean encMinim::isLeft() {
  if (_encState == 2) {
    _encState = 0;
    return true;
  } else return false;
}

boolean encMinim::isSingle() {
  if (_encState == 5) {
    _encState = 0;
    return true;
  } else return false;
}

boolean encMinim::isHolded() {
  if (_encState == 6) {
    _encState = 0;
    return true;
  } else return false;
}

boolean encMinim::isHold() {
  return (!_swState);
}


boolean encMinim::isDouble() {
  if (_encState == 7) {
    _encState = 0;
    return true;
  } else return false;
}
