/*
  11/22/24 CM
  Created with chatGPT
  This represents the full color spectrum over the time of 1 minute.
  0 and 1 minute are at full red color
  20 seconds is at full green color
  40 seconds is at full blue color
*/

// PWM minute pins
const byte minRedLED = 13;
const byte minGreenLED = 12;
const byte minBlueLED = 11;
// Digital minute pins
const byte minLEDs[10] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31};

// PWM 10 minute pins
const byte tenMinRedLED = 10;
const byte tenMinGreenLED = 9;
const byte tenMinBlueLED = 8;
// Digital 10 minute pins
const byte tenMinLEDs[6] = {32, 33, 34, 35, 36, 37};

// PWM hour pins
const byte hrRedLED = 7;
const byte hrGreenLED = 6;
const byte hrBlueLED = 5;
// Digital hour pins
const byte hrLEDs[12] = {42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53};

const unsigned long minCycleTime = 60000; // Minute cycle time in milliseconds
const unsigned long tenMinCycleTime = 600000; // 10 minute cycle time in milliseconds
const unsigned long hrCycleTime = 3600000; // 1 hour cycle time in milliseconds
const unsigned long dayCycleTime = 43200000; // 12 hours in milliseconds

unsigned long minTimeInCycle;
unsigned long tenMinTimeInCycle;
unsigned long hrTimeInCycle;

// Variables for the brightness of each PWM LED
unsigned int minRedLED_fadeValue = 0;
unsigned int minGreenLED_fadeValue = 0;
unsigned int minBlueLED_fadeValue = 0;

unsigned int tenMinRedLED_fadeValue = 0;
unsigned int tenMinGreenLED_fadeValue = 0;
unsigned int tenMinBlueLED_fadeValue = 0;

unsigned int hrRedLED_fadeValue = 0;
unsigned int hrGreenLED_fadeValue = 0;
unsigned int hrBlueLED_fadeValue = 0;


void setup() {
  Serial.begin(9600);
  // put all LEDs into known state (off)
  analogWrite(minRedLED, minRedLED_fadeValue);
  analogWrite(minGreenLED, minGreenLED_fadeValue);
  analogWrite(minBlueLED, minBlueLED_fadeValue);

  analogWrite(tenMinRedLED, tenMinRedLED_fadeValue);
  analogWrite(tenMinGreenLED, tenMinGreenLED_fadeValue);
  analogWrite(tenMinBlueLED, tenMinBlueLED_fadeValue);

  analogWrite(hrRedLED, hrRedLED_fadeValue);
  analogWrite(hrGreenLED, hrGreenLED_fadeValue);
  analogWrite(hrBlueLED, hrBlueLED_fadeValue);

  // Initialize all LEDs as off
  for (int i = 0; i < 10; i++) {
    pinMode(minLEDs[i], OUTPUT);
    digitalWrite(minLEDs[i], LOW);
  }
  for (int i = 0; i < 6; i++) {
    pinMode(tenMinLEDs[i], OUTPUT);
    digitalWrite(tenMinLEDs[i], LOW);
  }
  for (int i = 0; i < 12; i++) {
    pinMode(hrLEDs[i], OUTPUT);
    digitalWrite(hrLEDs[i], LOW);
  }
}


void loop() {
  // Get the current time
  unsigned long currentMillis = millis();

  /* 
    Calculate the phase of the cycle (each cycle is 60000 ms)
    'minTimeInCycle' will return the current millis() because 'minCycleTime' is greater than 'currentMillis'.
    Until 'currentMillis' reaches 60000, then 'minTimeInCycle' will = 0.
    Example 43550 % minCycleTime(60000) = 43550.
  */
  // Calculate time in cycles for each group
  minTimeInCycle = currentMillis % minCycleTime;
  tenMinTimeInCycle = currentMillis % tenMinCycleTime;
  hrTimeInCycle = currentMillis % hrCycleTime;


  // === Minute RGB LED Logic ===
  if (minTimeInCycle <= 20000) {
    minRedLED_fadeValue = 255 - (minTimeInCycle * 255 / 20000);
    minGreenLED_fadeValue = minTimeInCycle * 255 / 20000;
    minBlueLED_fadeValue = 0;
  } else if (minTimeInCycle <= 40000) {
    minRedLED_fadeValue = 0;
    minGreenLED_fadeValue = 255 - ((minTimeInCycle - 20000) * 255 / 20000);
    minBlueLED_fadeValue = (minTimeInCycle - 20000) * 255 / 20000;
  } else {
    minRedLED_fadeValue = (minTimeInCycle - 40000) * 255 / 20000;
    minGreenLED_fadeValue = 0;
    minBlueLED_fadeValue = 255 - ((minTimeInCycle - 40000) * 255 / 20000);
  }

  // === Ten-Minute RGB LED Logic ===
  if (tenMinTimeInCycle <= 200000) {
    tenMinRedLED_fadeValue = 255 - (tenMinTimeInCycle * 255 / 200000);
    tenMinGreenLED_fadeValue = tenMinTimeInCycle * 255 / 200000;
    tenMinBlueLED_fadeValue = 0;
  } else if (tenMinTimeInCycle <= 400000) {
    tenMinRedLED_fadeValue = 0;
    tenMinGreenLED_fadeValue = 255 - ((tenMinTimeInCycle - 200000) * 255 / 200000);
    tenMinBlueLED_fadeValue = (tenMinTimeInCycle - 200000) * 255 / 200000;
  } else {
    tenMinRedLED_fadeValue = (tenMinTimeInCycle - 400000) * 255 / 200000;
    tenMinGreenLED_fadeValue = 0;
    tenMinBlueLED_fadeValue = 255 - ((tenMinTimeInCycle - 400000) * 255 / 200000);
  }

  // === Hour RGB LED Logic ===
  if (hrTimeInCycle <= 1200000) {
    hrRedLED_fadeValue = 255 - (hrTimeInCycle * 255 / 1200000);
    hrGreenLED_fadeValue = hrTimeInCycle * 255 / 1200000;
    hrBlueLED_fadeValue = 0;
  } else if (hrTimeInCycle <= 2400000) {
    hrRedLED_fadeValue = 0;
    hrGreenLED_fadeValue = 255 - ((hrTimeInCycle - 1200000) * 255 / 1200000);
    hrBlueLED_fadeValue = (hrTimeInCycle - 1200000) * 255 / 1200000;
  } else {
    hrRedLED_fadeValue = (hrTimeInCycle - 2400000) * 255 / 1200000;
    hrGreenLED_fadeValue = 0;
    hrBlueLED_fadeValue = 255 - ((hrTimeInCycle - 2400000) * 255 / 1200000);
  }


  // === Minute Digital LEDs ===
  for (int i = 0; i < 10; i++) {
    digitalWrite(minLEDs[i], i < (currentMillis / minCycleTime) % 10 ? HIGH : LOW); // Ternary operator
  }

  // === 10 Minute Digital LEDs ===
  for (int i = 0; i < 6; i++) {
    digitalWrite(tenMinLEDs[i], i < (currentMillis / tenMinCycleTime) % 6 ? HIGH : LOW);
  }

  // === 1 Hour Digital LEDs ===
  for (int i = 0; i < 12; i++) {
    digitalWrite(hrLEDs[i], i < (currentMillis / hrCycleTime) % 12 ? HIGH : LOW);
  }


  // Write the calculated PWM values to the corresponding LED pins
  analogWrite(minRedLED, minRedLED_fadeValue);
  analogWrite(minGreenLED, minGreenLED_fadeValue);
  analogWrite(minBlueLED, minBlueLED_fadeValue);

  analogWrite(tenMinRedLED, tenMinRedLED_fadeValue);
  analogWrite(tenMinGreenLED, tenMinGreenLED_fadeValue);
  analogWrite(tenMinBlueLED, tenMinBlueLED_fadeValue);

  analogWrite(hrRedLED, hrRedLED_fadeValue);
  analogWrite(hrGreenLED, hrGreenLED_fadeValue);
  analogWrite(hrBlueLED, hrBlueLED_fadeValue);


  // Debugging output
  Serial.print("currentMillis: ");
  Serial.println(currentMillis);

/*
  // Minute LEDs debug
  Serial.print("minRedLED_fadeValue: ");
  Serial.println(minRedLED_fadeValue);
  Serial.print("minGreenLED_fadeValue: ");
  Serial.println(minGreenLED_fadeValue);
  Serial.print("minBlueLED_fadeValue: ");
  Serial.println(minBlueLED_fadeValue);

  // Ten-Minute LEDs debug
  Serial.print("tenMinRedLED_fadeValue: ");
  Serial.println(tenMinRedLED_fadeValue);
  Serial.print("tenMinGreenLED_fadeValue: ");
  Serial.println(tenMinGreenLED_fadeValue);
  Serial.print("tenMinBlueLED_fadeValue: ");
  Serial.println(tenMinBlueLED_fadeValue);

  // Hour LEDs debug
  Serial.print("hrRedLED_fadeValue: ");
  Serial.println(hrRedLED_fadeValue);
  Serial.print("hrGreenLED_fadeValue: ");
  Serial.println(hrGreenLED_fadeValue);
  Serial.print("hrBlueLED_fadeValue: ");
  Serial.println(hrBlueLED_fadeValue);
*/

}