#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include "TimerOne.h"

#include "Time.h"

#define SCREEN_WIDTH        128 // OLED display width, in pixels
#define SCREEN_HEIGHT        64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET            -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

Time currentTime;
Time alarmTime;
bool alarmActive = false;

const int swOnOff=3;
const int led=12;

unsigned long cm;             //current millis

void setup() {
  Serial.begin(9600);
  // initialize and clear display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

  pinMode(led, OUTPUT);

  display.clearDisplay();

  currentTime.setTime(15,56,50);
  alarmTime.setTime(15,57,0);

  Timer1.initialize(1000000); // Interrupt every 1 second
  Timer1.attachInterrupt(updateTime);

}

void loop() {
  cm=millis();
  display.clearDisplay();
  displayTime();
  displayAlarm();
  checkAlarm();
  display.display();
  delay(100);
}

void displayTime() {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("TIME:");
  display.setCursor(15, 20);
  display.print(currentTime.hours < 10 ? "0" : "");
  display.print(currentTime.hours);
  display.print(":");
  display.print(currentTime.minutes < 10 ? "0" : "");
  display.print(currentTime.minutes);
  display.print(":");
  display.print(currentTime.seconds < 10 ? "0" : "");
  display.print(currentTime.seconds);
}


void displayAlarm() {

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 40);
  display.print("ALARM:");
  display.setCursor(20, 52);
  display.print(alarmTime.hours < 10 ? "0" : "");
  display.print(alarmTime.hours);
  display.print(":");
  display.print(alarmTime.minutes < 10 ? "0" : "");
  display.print(alarmTime.minutes);
  display.print(":");
  display.print(alarmTime.seconds < 10 ? "0" : "");
  display.print(alarmTime.seconds);

  display.setTextSize(2);
  display.setCursor(80, 48);

  if(digitalRead(swOnOff)) display.print("ON");
  else display.print("OFF");
}


//ISR: Interrupt Service Routine:
void updateTime() {
  currentTime.incrementSeconds();
}

void checkAlarm() {
  if (currentTime.hours == alarmTime.hours &&
      currentTime.minutes == alarmTime.minutes) {
    alarmActive = true;
  }
  else alarmActive = false;

  if(alarmActive) blinkLed();

}

void blinkLed()
{
  static unsigned long pm=cm;    //pm=previous millis
  static bool state=LOW;
  if(digitalRead(swOnOff))
  {
    if((cm-pm)>=200)
    {
      pm=cm;
      state=!state;
      digitalWrite(led,state);
    }
  }
  else digitalWrite(led,LOW);
}