/*
   MicroMDAEPiano

   MicroMDAEPiano is a port of the MDA-EPiano sound engine
   (https://sourceforge.net/projects/mda-vst/) for the Teensy-3.5/3.6 with audio shield.

   (c)2019 H. Wirtz <wirtz@parasitstudio.de>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA

*/
//#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>
#include "limits.h"

#ifndef ENCODER4_H_INCLUDED
#define ENCODER4_H_INCLUDED

class Encoder4 : public Encoder
{
  public:

    //using Encoder::Encoder;

    Encoder4(uint8_t pin1, uint8_t pin2) : Encoder::Encoder(pin1, pin2)
    {
      _min = INT_MIN / 4;
      _max = INT_MAX / 4;
      _wrap_around = false;
    }

    int32_t read()
    {
      int32_t p = Encoder::read();

      if (p / 4 < _min && _wrap_around == false)
        Encoder::write(_min * 4);
      else if (p / 4 < _min && _wrap_around == true)
        Encoder::write(_max * 4);
      else if (p / 4 > _max && _wrap_around == false)
        Encoder::write(_max * 4);
      else if (p / 4 > _max && _wrap_around == true)
        Encoder::write(_min * 4);

      return (Encoder::read() / 4);
    }

    void write(int32_t p)
    {
      Encoder::write(p * 4);
    }
    
    void write(int32_t p, int32_t min, int32_t max, bool wrap_around=false)
    {
      _wrap_around=wrap_around;
      
      if (max < min)
      {
        _min = max;
        _max = min;
      }
      else
      {
        _min = min;
        _max = max;
      }

      if (p > _max)
        p = _max;
      else if (p < _min)
        p = _min;

      Encoder::write(p * 4);
    }

    int32_t read_min(void)
    {
      return (_min);
    }

    int32_t read_max(void)
    {
      return (_max);
    }

  private:
    int32_t _min;
    int32_t _max;
    bool _wrap_around;
};

#endif
