#pragma GCC push_options
#pragma GCC optimize ("O1")

// I2C
#include <Wire.h>
// RTC
#include <DS3231.h>
// Display
#include <TM1637Display.h>

// Init TM1637 Module
#define CLK 3   // clock
#define DIO 2   // data
TM1637Display display(CLK, DIO);
// Init DS3231 RTC
DS3231 rtc;
bool h12;
bool hPM;

void setup() {
       // Buttons
       for(int i = 8; i < 11; i++)
               pinMode(i,INPUT);
       // Display
       display.setBrightness(7);
       display.clear();
       // RTC
       Wire.begin();
       rtc.setClockMode(false); // 24 hour

       // Check RTC for problems
       if(!rtc.oscillatorCheck()) {
               // RTC NOT OK, set values to known ones
               rtc.setMinute(0);
               rtc.setHour(12);
       }
}

byte minute, hour, decTemp;
float temp;
// Create degree Celsius symbol
const uint8_t celsius[] = {
       SEG_A | SEG_B | SEG_F | SEG_G,  // Circle
       SEG_A | SEG_D | SEG_E | SEG_F   // C
};

void loop() {
       minute = rtc.getMinute();
       hour = rtc.getHour(h12, hPM);

       display.showNumberDecEx(hour * 100 + minute, 0b01000000, true);

       // Hour up
       if(digitalRead(10)) {
               if(rtc.getHour(h12, hPM) == 23) {
                       rtc.setHour(0);
               } else {
                       rtc.setHour(rtc.getHour(h12, hPM) + 1);
               }
               while(digitalRead(10));
       }

       // Minute up, set seconds to 0
       if(digitalRead(9)) {
               if(rtc.getMinute() == 59) {
                       rtc.setMinute(0);
               }
               rtc.setSecond(0);
               rtc.setMinute(rtc.getMinute() + 1);
               while(digitalRead(9));
       }

       // Show temperature reading from RTC
       while(digitalRead(8)) {
               temp = rtc.getTemperature();
               decTemp = (int)temp;
               if(temp > -9999) {
                       // OK
                       display.showNumberDec(decTemp, false, 2);
               } else {
                       display.showNumberDec(99, false, 2);
               }
               display.setSegments(celsius, 2, 2);
       }
}

#pragma GCC pop_options