#include <Wire.h>
#include "RTClib.h"
#include <ezButton.h>

#define SWITCH_OFF 0
#define SWITCH_ON  1

RTC_DS1307 rtc;

ezButton button(7);
int switch_state = SWITCH_ON;

int ledPinsSec[] = {22, 23, 24, 25, 26, 27};
int ledPinsMin[] = {34, 35, 36, 37, 38, 39};
int ledPinsHr[] = {46, 47, 48, 49, 50};

byte countSec;
byte countMin;
byte countHr;
#define nBitsSec sizeof(ledPinsSec)/sizeof(ledPinsSec[0])
#define nBitsMin sizeof(ledPinsMin)/sizeof(ledPinsMin[0])
#define nBitsHr sizeof(ledPinsHr)/sizeof(ledPinsHr[0])


void setup () {
 while (!Serial); // for Leonardo/Micro/Zero
 //Serial.begin(9600);
 if (! rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
 }
 if (! rtc.isrunning()) {
   Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 }

 button.setDebounceTime(50); //sets button debounce down

 for (byte i = 0; i < nBitsSec; i++) {
    pinMode(ledPinsSec[i], OUTPUT);
  }

  for (byte i = 0; i < nBitsMin; i++) {
    pinMode(ledPinsMin[i], OUTPUT);
  }

  for (byte i = 0; i < nBitsHr; i++) {
    pinMode(ledPinsHr[i], OUTPUT);
  }
}

byte se = 0;
byte mi = 0;
byte hr = 0;


void loop () {
 button.loop();
 if (button.isPressed()) {
    // change state of button
    if (switch_state == SWITCH_OFF)
      switch_state = SWITCH_ON;
    else
      switch_state = SWITCH_OFF;
    //Serial.print("switch's state -> ");
    //Serial.println(switch_state);
 }
 // if the state is on, then we want to show the time on the clock
 if (switch_state == SWITCH_ON) {
  DateTime now = (rtc.now() + TimeSpan(0, 12, 0, 31));
  se = now.second();
  mi = now.minute();
  hr = now.hour();
  dispBinarySec(se);
  dispBinaryMin(mi);
  dispBinaryHr(hr);
 }
 else {              //if the button is off, we want to turn all the LEDs off
  turnOff();
 }
}

// turns off all LEDs by writing a LOW (0) value to all of the pins that are defined above
void turnOff()
{
  for (byte i = 0; i < nBitsSec; i++) {
    digitalWrite(ledPinsSec[i], 0);
    digitalWrite(ledPinsMin[i], 0);
  }
  for (byte i = 0; i < nBitsHr; i++) {
    digitalWrite(ledPinsHr[i], 0);
  }
}

// these three corresponding functions set the LEDs on or off based on the byte of the value
// for example, if the byte was 8 secs (00001000), and you AND it with 1, then you would get 0
// so for every loop, the number is divided by two which essentially gets rid of the right most bit
// so in this case the 4th bit would be set to high, which is the fourth value in the list with the pins for the seconds
void dispBinarySec(byte nSec)
{
  for (byte i = 0; i < nBitsSec; i++) {
    digitalWrite(ledPinsSec[i], nSec & 1);
    nSec /= 2;
  }
}

void dispBinaryMin(byte nMin)
{
  for (byte i = 0; i < nBitsMin; i++) {
    digitalWrite(ledPinsMin[i], nMin & 1);
    nMin /= 2;
  }
}

void dispBinaryHr(byte nHr)
{
  for (byte i = 0; i < nBitsHr; i++) {
    digitalWrite(ledPinsHr[i], nHr & 1);
    nHr /= 2;
  }
}
