// simulated jButton struct object.
// next - constructors and initialisation

struct jButton {

private:
  unsigned char iPress, iRelease;
  unsigned char state = 0;      // normally high button all interpretations  

  unsigned char thePin;
  unsigned long lastTime;

public:
  void begin(byte onPin)
  {
    thePin = onPin;
    pinMode(thePin, INPUT_PULLUP);  // odd on ESP32 sim?
  }

  unsigned char uolPress()
  {
    unsigned char rc = iPress;

    iPress = 0;
    return rc;
  }
  
  unsigned char uolRelease()
  {
    unsigned char rc = iRelease;

    iRelease = 0;
    return rc;
  }

//  void update(unsigned long now)
//  { 
     
    
  void update()
  {
    unsigned long now = millis();

# define DEBOUNCE 50    // resample interval
    if (now - lastTime < DEBOUNCE) return;
  
    unsigned char raw = !digitalRead(thePin);   // 1 = pressed, button pulled up.

    if (state != raw) {
      if (raw) iPress = 1;
      else iRelease = 1;

      state = raw;
      lastTime = now;
    }
  }


}; // jButton;

jButton aJButton;

jButton add, stop;

//jButton test();

void setup() {
  Serial.begin(112500);
  Serial.println("test jButton world!/n");

  aJButton.begin(3);
  add.begin(5);
  stop.begin(4);

  setupPumps();
}

void loop() {

  aJButton.update();
  add.update();
  stop.update();

  if (aJButton.uolPress())
    Serial.println("I saw that pressed!");

  if (aJButton.uolRelease())
    Serial.println("I saw that released!");

  if (add.uolPress()) {
    Serial.print("I see that add... ");
    if (addAPump()) Serial.println("and cannot");
    else Serial.println("and did.");


  }

  if (stop.uolPress()) {
    Serial.println("I saw that stop!");
    stopAll();


  }
}

# define NPUMPS 4
const unsigned char pumpPin[] = {A0, A1, A2, A3};

# define mincr(x, z)  do { ++x; while (x >= z) x -= z; } while (0)

unsigned char nOn;

void setupPumps()
{
  for (unsigned char tt = 0; tt < NPUMPS; tt++)
    pinMode(pumpPin[tt], OUTPUT);

  nOn = 0;
  stopAll();
}

void stopAll()
{
  nOn = 0;

  for (unsigned char tt = 0; tt < NPUMPS; tt++)
    digitalWrite(pumpPin[tt], LOW);
}

unsigned char addAPump()
{
/* load sharing */
  static unsigned char nFirst;
  static unsigned char myNext;

  if (nOn == 0) {
    myNext = nFirst;
    mincr(nFirst, NPUMPS);  // ++; if (nFirst >= NPUMPS) nFirst = 0;
  }

  if (nOn == NPUMPS) return 1;    // FAIL

  nOn++;

/* here is where a pump might really be turned on, or the process for doing initiated
  Serial.print("pump ");
  Serial.print(nOn);    // number in the work force 1, 2 &c.
  Serial.print(" is ");
  Serial.print(myNext); // pump ID number
  Serial.println("");
*/
  digitalWrite(pumpPin[myNext], HIGH);

  mincr(myNext, NPUMPS);  // ++; if (myNext >= NPUMPS) myNext = 0;

  return 0;   // DID

/* non load sharing first
  if (nOn < NPUMPS) nOn++;
  else return 1;

  return 0;
*/
}

/*


    if (raw == 1) {
      if (state == 0)
        iPress = 1;

      state = 1;
    }
    else {
      if (state == 1)
        iRelease = 1;

      state = 0;
    }

*/