#include "Shield_Keyestudio.h"

Shield_Keyestudio::Shield_Keyestudio() : 
  btn1(_pinBtn1), 
  btn2(_pinBtn2),
  _currentIRCode(0),
  _newIRCodeAvailable(false),
  _lastDHTRead(0),
  _lastDHTTemp(0.0),
  _lastDHTHum(0.0)
{
}

void Shield_Keyestudio::begin() {
  pinMode(_pinLedRed, OUTPUT);
  pinMode(_pinLedBlue, OUTPUT);
  pinMode(_pinLedR, OUTPUT);
  pinMode(_pinLedG, OUTPUT);
  pinMode(_pinLedB, OUTPUT);
  pinMode(_pinBuzzer, OUTPUT);

  digitalWrite(_pinLedRed, LOW);
  digitalWrite(_pinLedBlue, LOW);
  digitalWrite(_pinBuzzer, HIGH); // Buzzer ist oft active-low beim Keyestudio, HIGH = aus

  btn1.begin();
  btn2.begin();

  IrReceiver.begin(_pinIR, ENABLE_LED_FEEDBACK);
  
  // Erste DHT Messung anstoßen
  _updateDHT();
}

void Shield_Keyestudio::update() {
  btn1.update();
  btn2.update();
  
  _newIRCodeAvailable = false;
  if (IrReceiver.decode()) {
    _currentIRCode = IrReceiver.decodedIRData.decodedRawData;
    _newIRCodeAvailable = true;
    IrReceiver.resume();
  }
}

// --- IR Empfänger ---
void Shield_Keyestudio::printIRCode() {
  if (_newIRCodeAvailable) {
    Serial.print("IR Code: 0x");
    Serial.println(_currentIRCode, HEX);
  }
}

bool Shield_Keyestudio::checkIRCode(uint32_t hexCode) {
  return (_newIRCodeAvailable && _currentIRCode == hexCode);
}

// --- LEDs ---
void Shield_Keyestudio::setSingleLED(uint8_t ledNum, bool state) {
  if (ledNum == 1) digitalWrite(_pinLedRed, state);
  if (ledNum == 2) digitalWrite(_pinLedBlue, state);
}

void Shield_Keyestudio::setRGB(uint8_t r, uint8_t g, uint8_t b) {
  analogWrite(_pinLedR, r);
  analogWrite(_pinLedG, g);
  analogWrite(_pinLedB, b);
}

// --- Buzzer ---
void Shield_Keyestudio::playTone(uint16_t freq, uint32_t ms) {
  // Für einfachen passiven Summer
  tone(_pinBuzzer, freq, ms);
}

// --- Sensoren ---
uint16_t Shield_Keyestudio::readPoti() {
  return analogRead(_pinPoti);
}

uint8_t Shield_Keyestudio::readLDR() {
  int raw = analogRead(_pinLDR);
  return map(raw, 0, 1023, 0, 100);
}

float Shield_Keyestudio::readLM35() {
  int raw = analogRead(_pinLM35);
  // Umrechnung: (Wertebereich 0-1023 entspricht 0-5V. LM35: 10mV pro Grad Celsius)
  return (raw * 500.0) / 1023.0;
}

// DHT Helper - blockiert nicht, liest nur alle 2 Sekunden
void Shield_Keyestudio::_updateDHT() {
  if (millis() - _lastDHTRead > 2000 || _lastDHTRead == 0) {
    int chk = _dht.read(_pinDHT);
    if (chk == DHTLIB_OK) {
      _lastDHTTemp = _dht.temperature;
      _lastDHTHum = _dht.humidity;
    }
    _lastDHTRead = millis();
  }
}

float Shield_Keyestudio::readDHTTemp() {
  _updateDHT();
  return _lastDHTTemp;
}

float Shield_Keyestudio::readDHTHum() {
  _updateDHT();
  return _lastDHTHum;
}