#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_ST7789.h>
#define TFT_CS     10
#define TFT_RST    9
#define TFT_DC     8
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define TFT_WIDTH  240
#define TFT_HEIGHT 240
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_DS3231 rtc;
#define BLACK       0x0000
#define WHITE       0xFFFF
#define RED         0xF800
#define GREEN       0x07E0
#define BLUE        0x001F
#define YELLOW      0xFFE0
int clockCenterX = TFT_WIDTH / 2 - 30;
int clockCenterY = TFT_HEIGHT / 2;
void setup() {
  Serial.begin(9600);
  Serial.println("Initializing...");
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.display();
  tft.init(TFT_WIDTH, TFT_HEIGHT);
  tft.setRotation(1);
  tft.fillScreen(BLACK); // Clear the screen
  Serial.println("Display initialized.");
  drawClockFace();
  Serial.println("Clock face drawn.");
}
void loop() {
  DateTime now = rtc.now();
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Time: ");
  display.print(now.hour(), DEC);
  display.print(':');
  display.print(now.minute(), DEC);
  display.print(':');
  display.print(now.second(), DEC);
  display.display();
  drawClockHands(now.hour(), now.minute(), now.second());
  delay(1000); // Update every second
}
void drawClockFace() {
  tft.fillScreen(BLACK); // Clear the screen
  tft.drawCircle(clockCenterX, clockCenterY, 100, WHITE);
  // Draw the clock numbers
  tft.setTextSize(2);
  tft.setTextColor(WHITE);
  for (int i = 1; i <= 12; i++) {
    float angle = i * 30 * PI / 180;
    int x = clockCenterX + 90 * cos(angle - PI / 2);
    int y = clockCenterY + 90 * sin(angle - PI / 2);
    tft.setCursor(x - 5, y - 5);
    tft.print(i);
  }
}
void drawClockHands(int hours, int minutes, int seconds) {
  static int prevSecond = -1;
  static int prevMinute = -1;
  static int prevHour = -1;
  float hourAngle = (hours + minutes / 60.0) * 30 * PI / 180;
  float minuteAngle = (minutes + seconds / 60.0) * 6 * PI / 180;
  float secondAngle = seconds * 6 * PI / 180;
  int hx = clockCenterX + 50 * cos(hourAngle - PI / 2);
  int hy = clockCenterY + 50 * sin(hourAngle - PI / 2);
  int mx = clockCenterX + 70 * cos(minuteAngle - PI / 2);
  int my = clockCenterY + 70 * sin(minuteAngle - PI / 2);
  int sx = clockCenterX + 90 * cos(secondAngle - PI / 2);
  int sy = clockCenterY + 90 * sin(secondAngle - PI / 2);
  if (prevSecond != seconds) {
    // Clear the previous hands
    if (prevHour != -1 && prevMinute != -1 && prevSecond != -1) {
      float prevHourAngle = (prevHour + prevMinute / 60.0) * 30 * PI / 180;
      float prevMinuteAngle = (prevMinute + prevSecond / 60.0) * 6 * PI / 180;
      float prevSecondAngle = prevSecond * 6 * PI / 180;
      int prevHx = clockCenterX + 50 * cos(prevHourAngle - PI / 2);
      int prevHy = clockCenterY + 50 * sin(prevHourAngle - PI / 2);
      int prevMx = clockCenterX + 70 * cos(prevMinuteAngle - PI / 2);
      int prevMy = clockCenterY + 70 * sin(prevMinuteAngle - PI / 2);
      int prevSx = clockCenterX + 90 * cos(prevSecondAngle - PI / 2);
      int prevSy = clockCenterY + 90 * sin(prevSecondAngle - PI / 2);
      tft.drawLine(clockCenterX, clockCenterY, prevHx, prevHy, BLACK);
      tft.drawLine(clockCenterX, clockCenterY, prevMx, prevMy, BLACK);
      tft.drawLine(clockCenterX, clockCenterY, prevSx, prevSy, BLACK);
    }
    // Draw the new hands
    tft.drawLine(clockCenterX, clockCenterY, hx, hy, RED);
    tft.drawLine(clockCenterX, clockCenterY, mx, my, GREEN);
    tft.drawLine(clockCenterX, clockCenterY, sx, sy, YELLOW);
    // Update previous values
    prevHour = hours;
    prevMinute = minutes;
    prevSecond = seconds;
  }
}