#include "Shield_RichShield1.h"

Shield_RichShield1::Shield_RichShield1() : 
  btnK1(9), 
  btnK2(8),
  _display(10, 11),
  _dht(12, DHT11),
  _currentIRCode(0),
  _newIRCodeAvailable(false)
{
}

void Shield_RichShield1::begin() {
  const int ledPins[] = {_pinLed1_Yellow, _pinLed2_Blue, _pinLed3_Green, _pinLed4_Red};
  for(int i = 0; i < 4; i++) {
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], LOW);
  }
  
  pinMode(_pinBuzzer, OUTPUT);
  digitalWrite(_pinBuzzer, LOW);

  btnK1.begin();
  btnK2.begin();

  _display.setBrightness(0x0f); 
  delay(10);
  clearDisplay();

  _dht.begin();
  
  IrReceiver.begin(_pinIR, ENABLE_LED_FEEDBACK); // IR starten
  
  delay(50);
}

void Shield_RichShield1::update() {
  btnK1.update();
  btnK2.update();
  
  _newIRCodeAvailable = false;
  if (IrReceiver.decode()) {
    _currentIRCode = IrReceiver.decodedIRData.decodedRawData;
    _newIRCodeAvailable = true;
    IrReceiver.resume();
  }
}

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

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

// --- LEDs ---
void Shield_RichShield1::setLED(uint8_t ledNum, bool state) {
  switch(ledNum) {
    case 1: digitalWrite(_pinLed1_Yellow, state); break;
    case 2: digitalWrite(_pinLed2_Blue, state); break;
    case 3: digitalWrite(_pinLed3_Green, state); break;
    case 4: digitalWrite(_pinLed4_Red, state); break;
  }
}

void Shield_RichShield1::setLEDPWM(uint8_t ledNum, uint8_t value) {
  int pin = -1;
  switch(ledNum) {
    case 1: pin = _pinLed1_Yellow; break;
    case 2: pin = _pinLed2_Blue; break; 
    case 3: pin = _pinLed3_Green; break;   
    case 4: pin = _pinLed4_Red; break;
  }
  
  if (pin == _pinLed2_Blue || pin == _pinLed3_Green) {
    analogWrite(pin, value);
  } else {
    digitalWrite(pin, value > 127 ? HIGH : LOW);
  }
}

// --- Buzzer ---
void Shield_RichShield1::playTone(uint16_t freq, uint32_t ms) {
  tone(_pinBuzzer, freq, ms);
}

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

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

float Shield_RichShield1::readNTC() {
  int raw = analogRead(_pinNTC);
  if (raw == 0 || raw == 1023) return 0.0;
  
  float r = 10000.0 * (1023.0 / (float)raw - 1.0);
  float tempC = 1.0 / (log(r / 10000.0) / 3950.0 + 1.0 / 298.15) - 273.15;
  
  return tempC;
}

float Shield_RichShield1::readVoltage() {
  int raw = analogRead(_pinVoltage);
  return (raw * 5.0 * 5.0) / 1023.0; 
}

float Shield_RichShield1::readTemperature() {
  float t = _dht.readTemperature();
  return isnan(t) ? 0.0 : t;
}

float Shield_RichShield1::readHumidity() {
  float h = _dht.readHumidity();
  return isnan(h) ? 0.0 : h;
}

// --- Display ---
void Shield_RichShield1::showNumber(int num) {
  _display.showNumberDec(num);
}

void Shield_RichShield1::showWord(char c1, char c2, char c3, char c4) {
  uint8_t data[] = {
    _charToSegment(c1),
    _charToSegment(c2),
    _charToSegment(c3),
    _charToSegment(c4)
  };
  _display.setSegments(data);
}

void Shield_RichShield1::clearDisplay() {
  uint8_t data[] = {0, 0, 0, 0};
  _display.setSegments(data);
}

uint8_t Shield_RichShield1::_charToSegment(char c) {
  switch (c) {
    case 'H': case 'h': return 0b01110110; 
    case 'A': case 'a': return 0b01110111; 
    case 'b':           return 0b01111100; 
    case 'C':           return 0b00111001; 
    case 'd':           return 0b01011110; 
    case 'E': case 'e': return 0b01111001; 
    case 'F': case 'f': return 0b01110001; 
    case 'I': case 'i': return 0b00000110; 
    case 'L': case 'l': return 0b00111000; 
    case 'O':           return 0b00111111; 
    case 'o':           return 0b01011100;
    case 'P': case 'p': return 0b01110011; 
    case 'S': case 's': return 0b01101101; 
    case 'U':           return 0b00111110;
    case 'u':           return 0b00011100; 
    case '-':           return 0b01000000; 
    case ' ':           return 0b00000000; 
    default:            return 0b00000000;
  }
}