/**
 * \file cimdithal.h
 * \brief declaration of the CimditHAL class
 * \author GrumpyDeveloper (Sascha Nitsch)
 * \copyright 2022 Sascha Nitsch
 * Licensed under MIT license
 *
 */

#ifndef CIMDITHAL_H_
#define CIMDITHAL_H_

/// rollover time (when 32 bit millis rolls over)
#define ROLLOVER_INTERVAL 200

// external libraries
#include <Adafruit_MCP23X17.h>

// own libraries
#include "cimditrotary.h"

/**
 * \class CimditHAL
 * \brief basic hardware abstraction layer
 */
class CimditHAL {
 public:
  /// constructor
  CimditHAL();

  /// initialize
  void begin();

  /// \brief read current state from hardware
  /// \param interrupt true if called from an interrupt
  void readFromHardware(bool interrupt);

  /// \brief has a rotary input changed
  uint8_t rotaryChanged();

  /// \brief has an analog value changed
  uint16_t analogChanged();

  /// \brief has a button changed
  uint64_t buttonsChanged();

  /// \brief get single rotary value
  /// \param num number of encoder
  /// \retval delta value for the given encoder
  int8_t getEncoder(uint8_t num);

  /// \brief get analog value
  /// \param num number of analog values
  /// \retval analog values
  uint16_t getAnalog(uint8_t num) const;

  /// \brief get state of a single button
  /// \param num button number
  /// \retval buttons status
  bool getButton(uint8_t num) const;

  /// global millis value
  static uint32_t m_millis;

 private:
  CimditRotary m_rotaryEncoders[8];

  /// rotary encoder change flags
  uint8_t m_rotChanged;

  /// current button values
  uint8_t m_currentButtons[8];

  /// changed values since last hardware read
  uint8_t m_buttonsChanged[8];

  /// current analag values
  int16_t m_currentAnalogValues[16];

  /// changed analog values flags
  uint16_t m_analogChanged;

  /// our key matrix
  Adafruit_MCP23X17 m_keyMatrix;

  /// our rotary encoders
  Adafruit_MCP23X17 m_rotEncoders;

  /// next time we do an analog read
  uint32_t m_nextAnalogRead;

  /// next time we do an key row scan
  uint32_t m_nextKeyScan;

  /// current analog number
  uint8_t m_analogNum;

  /// current key matrix row
  uint8_t m_keyRow;
};

#endif  // CIMDITHAL_H_
