#include <DS3231M.h>  
#include "LowPower.h"

DS3231M_Class DS3231M; 

const int button_pin = 2;

const int anode[] = {0, 1, 17, 3, 4, 5, 6, 7, 8};
const int cathode[] = {9, 10, 11, 12, 13, 14, 15, 16};

//dinamically calculate number of elements in a array
const int rows = sizeof(anode) / sizeof(anode[0]);
const int cols = sizeof(cathode) / sizeof(cathode[0]);

const int totalLEDs = 60;

int minute;
int second;
int hour;

int sec_row;
int sec_col;
int min_row;
int min_col;

volatile bool wakeUp = false;
unsigned long buttonPressTime = 0;

void wake_up()
{
  wakeUp = true; 
}

void setup() {
  //DateTime(F(__DATE__), F(__TIME__))
  for(int i=0; i<18; i++){
    pinMode(i, OUTPUT);
  }
    
  pinMode(button_pin, INPUT_PULLUP); 
  //attachInterrupt(0, wake_up, LOW);
  
  //Serial.begin(9600);
  while (!DS3231M.begin())  // Initialize RTC communications
  {
    //Serial.println("Not found");
    //delay(1000);
  }
  DS3231M.adjust(DateTime(2025, 7, 22, 12, 0, 0));  // Set to specific Date/Time  

}

void loop() {
  DateTime       now = DS3231M.now(); 
  hour = now.hour();
  minute = now.minute();
  second = now.second();
  
  // Light second, minute, and hour hands briefly  
  turnOffAllLEDs(); 
  lightSecondLED(second);
  delayMicroseconds(200);
  turnOffAllLEDs();
  lightMinuteLED(minute);
  delayMicroseconds(200);
  turnOffAllLEDs();
  lightHourLED(hour);
  delayMicroseconds(1);

  //reset the time at 12 on button press
  if(digitalRead(button_pin) == LOW) {
     DS3231M.adjust(DateTime(2025, 7, 22, 12, 0, 0));
     /*
     buttonPressTime = millis();
     while (digitalRead(button_pin) == LOW); // wait for release
     unsigned long pressDuration = millis() - buttonPressTime;

     if (pressDuration > 1500) {
        // reset time on long press
        DS3231M.adjust(DateTime(2025, 7, 22, 6, 45, 30));
     } 
     else{
        // Sleep if short press
        //goToSleep();
     }
     */
  }
}

void lightSecondLED(int index) {
  sec_row = index / cols; // anode index
  sec_col = index % cols; // cathode index
  // Light only the current LED
  digitalWrite(anode[sec_row], HIGH);
  digitalWrite(cathode[sec_col], LOW);
}

void lightMinuteLED(int index) {
  min_row = index / cols; // anode index
  min_col = index % cols; // cathode index
  // Light only the current LED
  digitalWrite(anode[min_row], HIGH);
  digitalWrite(cathode[min_col], LOW);
}

void lightHourLED(int index) {
  if(index>12) index = index - 12;
  if(index<4 || index == 12){    
    digitalWrite(7, HIGH);
    digitalWrite(8, LOW);
    if(index==1)digitalWrite(cathode[5], LOW);
    else if(index==2)digitalWrite(cathode[6], LOW);
    else if(index==3)digitalWrite(cathode[7], LOW);
    else if(index==12)digitalWrite(cathode[4], LOW);
    }
  else if(index>=4 && index<12){
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(cathode[index-4], LOW);
    }
}

void lightOneLED(int index) {
  int row = index / cols; // anode index
  int col = index % cols; // cathode index
  // Light only the current LED
  digitalWrite(anode[row], HIGH);
  digitalWrite(cathode[col], LOW);
}

void turnOffAllLEDs() {
  for (int i = 0; i < rows; i++) digitalWrite(anode[i], LOW);
  for (int j = 0; j < cols; j++) digitalWrite(cathode[j], HIGH);
}

void goToSleep() {
  delay(100); // Let serial flush
  wakeUp = false;
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  
}
