#include <IRremote.hpp>

const int receiverPin = 7;   // Pin connected to IR receiver
const int ledWhitePin = 8;   // Pin connected to LED 1 (White)
const int ledRedPin = 9;     // Pin connected to LED 2 (Red)
const int ledYellowPin = 10; // Pin connected to LED 3 (Yellow)
const int ledOrange4Pin = 11;// Pin connected to LED 4 (Orange)
const int ledOrange5Pin = 12;// Pin connected to LED 5 (Orange)

int brightnessWhite = 0;  // Brightness of LED 1 (White)
int brightnessRed = 0;    // Brightness of LED 2 (Red)
int brightnessYellow = 0; // Brightness of LED 3 (Yellow)
int brightnessOrange4 = 0;// Brightness of LED 4 (Orange)
int brightnessOrange5 = 0;// Brightness of LED 5 (Orange)

bool syncBlinkState = false;

const int fadeAmount = 25;  // Amount to fade LED with each button press (0-255)

unsigned long previousMillis = 0;
const long interval = 500;  // Interval for blinking (500 ms)

void setup() {
  pinMode(ledWhitePin, OUTPUT);
  pinMode(ledRedPin, OUTPUT);
  pinMode(ledYellowPin, OUTPUT);
  pinMode(ledOrange4Pin, OUTPUT);
  pinMode(ledOrange5Pin, OUTPUT);

  IrReceiver.begin(receiverPin, ENABLE_LED_FEEDBACK);  // Initialize the IR receiver
  Serial.begin(9600);  // Initialize serial communication for debugging
}

void loop() {
  if (IrReceiver.decode()) {  // Check if a signal is received
    unsigned long keyValue = IrReceiver.decodedIRData.command;  // Get the command from the IR signal
    Serial.println(keyValue, HEX);  // Print the value received for debugging

    switch (keyValue) {
      case 0x30:  // Code for button "1"
        brightnessWhite = adjustBrightness(brightnessWhite);
        analogWrite(ledWhitePin, brightnessWhite);
        break;
      case 0x18:  // Code for button "2"
        brightnessRed = adjustBrightness(brightnessRed);
        analogWrite(ledRedPin, brightnessRed);
        break;
      case 0x7A:  // Code for button "3"
        brightnessYellow = adjustBrightness(brightnessYellow);
        analogWrite(ledYellowPin, brightnessYellow);
        break;
      case 0x10:  // Code for button "4"
        brightnessOrange4 = adjustBrightness(brightnessOrange4);
        analogWrite(ledOrange4Pin, brightnessOrange4);
        break;
      case 0x38:  // Code for button "5"
        brightnessOrange5 = adjustBrightness(brightnessOrange5);
        analogWrite(ledOrange5Pin, brightnessOrange5);
        break;
      case 0x5A:  // Code for button "6"
        syncBlinkState = !syncBlinkState;  // Toggle synchronized blinking of LEDs 4 and 5
        break;
      case 0x40:  // Code for button "+"
        increaseBrightness();
        break;
      case 0x80:  // Code for button "-"
        decreaseBrightness();
        break;
    }

    IrReceiver.resume();  // Prepare for the next value
  }

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (syncBlinkState) {
      brightnessOrange4 = toggleBrightness(brightnessOrange4);
      brightnessOrange5 = toggleBrightness(brightnessOrange5);
      analogWrite(ledOrange4Pin, brightnessOrange4);
      analogWrite(ledOrange5Pin, brightnessOrange5);
    }
  }
}

int adjustBrightness(int currentBrightness) {
  return currentBrightness > 0 ? 0 : 255;  // Toggle between 0 and 255
}

void increaseBrightness() {
  // Increase brightness of all LEDs
  brightnessWhite = constrain(brightnessWhite + fadeAmount, 0, 255);
  brightnessRed = constrain(brightnessRed + fadeAmount, 0, 255);
  brightnessYellow = constrain(brightnessYellow + fadeAmount, 0, 255);
  brightnessOrange4 = constrain(brightnessOrange4 + fadeAmount, 0, 255);
  brightnessOrange5 = constrain(brightnessOrange5 + fadeAmount, 0, 255);
  analogWrite(ledWhitePin, brightnessWhite);
  analogWrite(ledRedPin, brightnessRed);
  analogWrite(ledYellowPin, brightnessYellow);
  analogWrite(ledOrange4Pin, brightnessOrange4);
  analogWrite(ledOrange5Pin, brightnessOrange5);
}

void decreaseBrightness() {
  // Decrease brightness of all LEDs
  brightnessWhite = constrain(brightnessWhite - fadeAmount, 0, 255);
  brightnessRed = constrain(brightnessRed - fadeAmount, 0, 255);
  brightnessYellow = constrain(brightnessYellow - fadeAmount, 0, 255);
  brightnessOrange4 = constrain(brightnessOrange4 - fadeAmount, 0, 255);
  brightnessOrange5 = constrain(brightnessOrange5 - fadeAmount, 0, 255);
  analogWrite(ledWhitePin, brightnessWhite);
  analogWrite(ledRedPin, brightnessRed);
  analogWrite(ledYellowPin, brightnessYellow);
  analogWrite(ledOrange4Pin, brightnessOrange4);
  analogWrite(ledOrange5Pin, brightnessOrange5);
}

int toggleBrightness(int currentBrightness) {
  return currentBrightness == 0 ? 255 : 0;  // Toggle between 0 and 255
}