#include <Wire.h>
#include <Arduino.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);

#define Start 15 // start stop button
int hours = 0;
int minutes = 0;
int seconds = 0;
boolean timeState = false;
#define encoderPinA 2 // right
#define encoderPinB 4 // left
#define encoderButton 5 // switch
int HMS = 1;
int encoderPos = 0; // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
boolean A_set = false;
boolean B_set = false;


void setup() {

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

pinMode(Start, INPUT_PULLUP);
pinMode(encoderPinA, INPUT_PULLUP); //enabling pullups
pinMode(encoderPinB, INPUT_PULLUP);
pinMode(encoderButton, INPUT_PULLUP);

attachInterrupt(digitalPinToInterrupt(encoderPinA), doEncoderA, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPinB), doEncoderB, CHANGE);

//attachInterrupt(0, doEncoderA, CHANGE); //pin 2
//attachInterrupt(1, doEncoderB, CHANGE); //pin 3

Serial.begin(115200); // output

//  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // initialize with the I2C addr 0x3c
//    Serial.println(F("SSD1306 allocation failed"));
//    for(;;); // Don't proceed, loop forever
//  }

display.clearDisplay();
display.display();

display.setTextSize(1);
display.setCursor(28, 0);
display.setTextColor(WHITE, BLACK);
display.print("The Lunchbox!");
display.setTextSize(2);
display.setCursor(20, 15);
display.print ("00:00:00");
display.display();
}

void loop() {

  +
display.print(hours);
if (digitalRead(encoderButton) == LOW)
{
HMS = HMS + 1;
if (HMS == 4)
{
HMS = 1;
}
delay(1000);
}
rotating = true; // reset the debouncer
encoderPos = constrain(encoderPos, -1, 1);
if (lastReportedPos != encoderPos) {

if (HMS == 1) {
hours = hours + encoderPos;
hours = constrain(hours, 0, 48);
}
else if (HMS == 2) {
minutes = minutes + encoderPos;
minutes = constrain(minutes, 0, 60);
}
else if (HMS == 3) {
seconds = seconds + encoderPos;
seconds = constrain(seconds, 0, 60);
}
 //Serial.println(encoderPos); // for testing
 // Serial.print("hours ");
 Serial.println(hours);
 //Serial.print("minutes ");
 //Serial.println(minutes);
 //Serial.print("seconds ");
 //Serial.println(seconds);
 //Serial.println(" ");
display.setCursor(20, 15);
display.setTextColor(WHITE, BLACK);
display.print(hours);
display.display();
if (hours <= 9)
{
display.print("0");
}
display.setCursor(20, 15);
display.print(hours);
display.print(":");
if (minutes <= 9)
{
display.print("0");
}
display.print(minutes);
display.print(":");
if (seconds <= 9)
{
display.print("0");
}
display.print(seconds);
encoderPos = 0;
lastReportedPos = encoderPos;

}
if (digitalRead(Start) == LOW) { //start count down timer
timeState = true;
//delay(1000);
while (timeState == true) {
if (minutes == 0 && hours >= 1) {
minutes = 60;
hours = hours - 1;
}
if (seconds == 0 && minutes >= 1) {
seconds = 60;
minutes = minutes - 1;
}
else if (minutes == 0 && hours == 0 && seconds == 0) { //count down alarm
while (timeState == true) {
tone(11, 600, 250);
delay(250);
tone(11, 800, 250);
delay(250);
if (digitalRead(Start) == LOW) { // turn alarm off
timeState = false;
seconds = 1; 
display.clearDisplay();
display.setCursor(50, 0);
display.print("The Lunchbox!");
display.setCursor(4, 1);
display.print("00:00:00");

break;
}
}
}
delay(992); // delay for keping time master setting!
seconds = seconds - 1;
//Serial.print("hours "); // for testing
//Serial.println(hours);
//Serial.print("minutes ");
//Serial.println(minutes);
//Serial.print("seconds ");
//Serial.println(seconds);
//Serial.println(" ");

display.setCursor(4, 1);
display.print(hours);
if (hours <= 9)
{
display.print("0");
}
display.print(hours);
display.print(":");
if (minutes <= 9)
{
display.print("0");
}
display.print(minutes);
display.print(":");
if (seconds <= 9)
{
display.print("0");
}
display.print(seconds);

if (digitalRead(Start) == LOW) {
delay(1000);
timeState = false;
break;
}
}
}
}

// Interrupt on A changing state
void doEncoderA() {
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done

// Test transition, did things really change?
if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;

// adjust counter + if A leads B
if ( A_set && !B_set )
encoderPos = 1;

rotating = false; // no more debouncing until loop() hits again
}
}

// Interrupt on B changing state
void doEncoderB() {
if ( rotating ) delay (1);
if ( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if ( B_set && !A_set )
encoderPos = -1;

rotating = false;
}
}