#include <LiquidCrystal_I2C.h>
#include <squareWave.h>
#include <mapper.h>
#include <autoPOT.h>


#define PULSE_MS  70
#define REST_MS   100
#define BEATS_MIN 67
#define BEATS_MAX 127


class heartBeat : public squareWave {

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

          void  begin();
          void  setBPM(float inBPM);
          float beats2Ms(float beatsPerMin);
  virtual void  pulseOn(void);
	virtual void  idle(void);

          int                 pin;
          int                 beatCount;
          float               BPM;
          LiquidCrystal_I2C*  lcd;
          timeObj             highTimer;
          timeObj             lowTimer;
          timeObj             highTimerII;
};


heartBeat::heartBeat(int inPin)
  :squareWave() {
    
    pin       = inPin;
    beatCount = 0;
    highTimer.setTime(PULSE_MS,false);
    lowTimer.setTime(REST_MS,false);
    highTimerII.setTime(PULSE_MS,false);
}


heartBeat::~heartBeat(void) {  }


void heartBeat::begin() {
  
  lcd = new LiquidCrystal_I2C(0x27,16,2); // Create the LCD object.
  lcd->init();                             // initialize the lcd
  lcd->backlight();                        // Do the backlight thing.
  lcd->setCursor(0,0);                     // Move cursor position.
  lcd->print("Count : ");                  // Spit out message at cursor position.
  lcd->setCursor(0,1);                     // Move cursor position.
  lcd->print("BPM   : ");                  // Spit out message at cursor position.
  pinMode(pin,OUTPUT);
  setOnOff(true);
}


void heartBeat::setBPM(float inBPM) {
  
  float period;

  BPM = inBPM;
  period = beats2Ms(BPM);
  setPeriod(period);
  setPercent(80);
}


float heartBeat::beats2Ms(float beatsPerMin) {

  return 60000.0/beatsPerMin;
}


void heartBeat::pulseOn(void) {

  digitalWrite(pin,HIGH);
  highTimer.start();
  beatCount++;
  lcd->setCursor(8,0);
  lcd->print(beatCount);
  lcd->setCursor(8,1);
  lcd->print(BPM,2);
}


void heartBeat::idle(void) {

  squareWave::idle();
  if (highTimer.ding()) {
    digitalWrite(pin,LOW);
    highTimer.reset();
    lowTimer.start();
  }
  if (lowTimer.ding()) {
    digitalWrite(pin,HIGH);
    highTimerII.start();
    lowTimer.reset();
  }
  if (highTimerII.ding()) {
    digitalWrite(pin,LOW);
    highTimerII.reset();
  }
}



// *************** Progrm starts here *************** 


heartBeat theHeart(13);
autoPOT   theSlider(A0);
mapper    potToBPM(0,1023,BEATS_MIN,BEATS_MAX);

void setup() {
  
  theHeart.begin();
  theSlider.setCallback(newValue);
}


void newValue(int newValue) {
  
  float bpm;

  bpm = potToBPM.map(newValue);
  theHeart.setBPM(bpm);
}


void loop() { idle(); }