#include <autoPOT.h>
#include <timeObj.h>
#include <mapper.h>
#include <mechButton.h>



// *************************************************************
// **********  testPOT class to do the heavy lifting. **********
// *************************************************************


mapper  percentMap(0,1023,100,0);

class testPOT : public autoPOT {

  public:
          testPOT(int inPin);
  virtual ~testPOT(void);

          void    begin(int inNum);
          void    gotoMidpoint(void);
          void    gotoQuarterPoint(void);
          bool    isMidpoint(void);
          bool    isQuarterPoint(void);
          int     getRawReading(void);
          int     getOurNum(void);
  virtual void    idle(void);

          enum    states { preInit, waiting, midpoint, quarterpoint };
          timeObj stillTimer;
          states  ourState;
          int     ourNum;
};


testPOT::testPOT(int inPin)
  : autoPOT(inPin) {
    
  stillTimer.setTime(15000,false);
  ourState = preInit;
}


testPOT::~testPOT(void) {  }


void testPOT::begin(int inNum) {

  ourNum = inNum;
  pinMode(13,INPUT);
  hookup();
  ourState = waiting;
}


void testPOT::gotoMidpoint(void) {
  
  if (ourState!=preInit) {
    ourState = midpoint;
    stillTimer.start();
    pinMode(13,OUTPUT);
    Serial.print("Set POT# ");
    Serial.print(ourNum);
    Serial.println(" to mid-mark, watch LED 13.");
  }
}


void testPOT::gotoQuarterPoint(void) {

  if (ourState!=preInit) {
    ourState = quarterpoint;
    stillTimer.start();
    pinMode(13,OUTPUT);
    Serial.print("Set POT# ");
    Serial.print(ourNum);
    Serial.println(" to 25% mark, watch LED 13.");
  }
}


bool testPOT::isMidpoint(void) {
   
   int percent;

  if (ourState!=preInit) {
    percent = round(percentMap.map(value));
    return (percent>=49 && percent<=51);
  }
  return false;
}


bool testPOT::isQuarterPoint(void) {

  int percent;

  if (ourState!=preInit) {
    percent = round(percentMap.map(value));
    return (percent>=24 && percent<=26);
  }
  return false;
}


int testPOT::getRawReading(void) { return value; }

// What we do in the background.
void testPOT::idle(void) {

  int   newVal;
  bool  atTarget;
  
  if (callback) {
    newVal = analogRead(pinNum);
    if (newVal!=value) {
      value = newVal;
      callback(value);					// Call our callback with the buffer.
    }
  } else {
    newVal = analogRead(pinNum);
    if (newVal!=value) {
      value = newVal;
      switch(ourState) {
        case midpoint :
          atTarget = isMidpoint();
          digitalWrite(13,atTarget);
          if (!atTarget) {
            stillTimer.start();
          } else {
            if (stillTimer.ding()) {
              stillTimer.reset();
              pinMode(13,INPUT);
              Serial.print("POT #");
              Serial.print(ourNum);
              Serial.println(" set to midpoint.");
              ourState = waiting;
            }
          }
        break;
        case quarterpoint :
          atTarget = isQuarterPoint();
          digitalWrite(13,atTarget);
          if (!atTarget) {
            stillTimer.start();
          } else {
            if (stillTimer.ding()) {
              stillTimer.reset();
              pinMode(13,INPUT);
              Serial.print("POT #");
              Serial.print(ourNum);
              Serial.println(" set to 25%.");
              ourState = waiting;
            }
          }
        break;
        default : break;
      }
    }
  }
}



// *************************************************************
// *********************  .ino starts here *********************
// *************************************************************



testPOT     POTs[5] {A0, A1, A2, A3, A4 };
int         results [6][5];
int         potReads;
mechButton  readBtn(2);


void setup(void) {

  Serial.begin(9600);
  potReads = 0;
  for (int i=0;i<5;i++) {
    POTs[i].begin(i);
  }
  readBtn.setCallback(seePOTs);
  for (int i=0;i<5;i++) {
    POTs[i].gotoMidpoint();
    while(!POTs[i].isMidpoint()) sleep(10);
  }
  readPots();
  for (int i=0;i<5;i++) {
    POTs[i].gotoQuarterPoint();
    while(!POTs[i].isQuarterPoint()) sleep(10);
    readPots();
    POTs[i].gotoMidpoint();
    while(!POTs[i].isMidpoint()) sleep(10);
  }
  showResultes();
}


void seePOTs(void) {

  if (!readBtn.getState()) {
    Serial.println();
    Serial.print("Readings : \t");
    for(int i=0;i<5;i++) {
      Serial.print(POTs[i].getRawReading());
      Serial.print('\t');
    }
    Serial.println();
  }
}


void readPots(void) {
  for(int i=0;i<5;i++) {
    results[potReads][i] = POTs[i].getRawReading();
  }
  potReads++;
}


void showResultes(){

  Serial.println();
  Serial.println("                        ******* Our Results *******");
  for(int j=0;j<6;j++) {
    if (!j) {
      Serial.print("Baseline all mid.");
    } else {
      Serial.print("POT# ");
      Serial.print(j-1);
      Serial.print(" set to 25%");
    }
    Serial.print('\t');
    for (int i=0;i<5;i++) {
      Serial.print(results[j][i]);
      Serial.print('\t');
    }
    Serial.println();
  }
}


void loop(void) { idle(); }