#include <DHT.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

#define CMRGB 4
#define DHTPIN 12        // Pin where the DHT22 is connected
#define DHTTYPE DHT22   // Type of DHT sensor
// RGB
int b = 15;
int g  = 2;
int r = 0;
#define LDRPIN 34       // Pin where the LDR sensor is connected
float temperature;
float humidity;
float ldrVoltage;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
  pinMode(b, OUTPUT);
  pinMode(r, OUTPUT);
  pinMode(g, OUTPUT);
}

void loop() {
  delay(2000);  // Wait for 2 seconds to avoid flooding the serial monitor

  temperature = dht.readTemperature();  // Read temperature in Celsius
  humidity = dht.readHumidity();       // Read humidity

  // Check if any reads failed and exit early (to try again)
  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  int ldrValue = analogRead(LDRPIN);  // Read LDR sensor value
  ldrVoltage = ldrValue * (5.0 / 1023.0);  // Convert to voltage
  char mode = '0';
  
  Display();
  Serial.println("Enter mode: '1' for auto, '2' for manual, '0' to exit");
  
  if (Serial.available() > 0) {
    mode = Serial.read();
  }

  switch(mode) {
    case '1': // Auto mode
      Serial.println("Welcome to auto mode");
      autoMode();
      break;
    case '2': // Manual mode
      manualMode();
      break;
    case '0': // Exit
      Serial.println("Exiting program");
      return;
    default:
      Serial.println("Invalid mode. Please select '1', '2' or '0'");
  }
}

void autoMode() {
  Serial.println("Auto mode is active.");
  Serial.println("LED color will adjust based on light and temperature.");
  
  while (true) {
    // Read LDR sensor value
    int ldrValue = analogRead(LDRPIN);  
    ldrVoltage = ldrValue * (5.0 / 1023.0); 

    // Adjust LED brightness based on light conditions
    adjustLEDByLight(ldrVoltage);

    // Read temperature from DHT22 sensor
    temperature = dht.readTemperature();  
    
    // Adjust LED color based on temperature
    adjustLEDByTemperature(temperature);

    // Display sensor readings
    Display();
    delay(1000); // Wait for a while before taking another reading
  }
}

void manualMode() {
  Serial.println("Welcome to manual mode");
  Serial.println("Select color: 'c' for cool, 'w' for warm, 'n' for neutral");
  
  while (true) {
    if (Serial.available() > 0) {
      char color = Serial.read();
      switch (color) {
        case 'c': // cool
          cool();
          break;
        case 'w': // warm
          warm();
          break;
        case 'n': // neutral
          neutral();
          break;
        case 'x': // exit
          Serial.println("Exiting manual mode");
          return;
        default:
          Serial.println("Invalid selection. Please select 'c', 'w', 'n' or 'x'");
      }
    }
  }
}

void Display() {
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print(" °C\tHumidity: ");
  Serial.print(humidity);
  Serial.print(" %\tLDR Voltage: ");
  Serial.print(ldrVoltage);
  Serial.println(" V");
}

void adjustLEDByLight(float ldrVoltage) {
  // Map the LDR voltage to LED brightness range
  int brightness = map(ldrVoltage, 0, 5, 255, 0); 

  // Set LED brightness
  analogWrite(r, brightness);
  analogWrite(g, brightness);
  analogWrite(b, brightness);
}

void adjustLEDByTemperature(float temperature) {
  if (!isnan(temperature)) {
    if (temperature < 20.0) {
      cool();
    } else if (temperature >= 20.0 && temperature < 25.0) {
      warm();
    } else {
      neutral();
    }
  }
}

void cool() {
  digitalWrite(r, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(b, LOW);
}

void neutral() {
  digitalWrite(r, LOW);
  digitalWrite(g, LOW);
  digitalWrite(b, LOW);
}

void warm() {
  digitalWrite(r, LOW);
  digitalWrite(g, HIGH);
  digitalWrite(b, HIGH);
}