// ATMEGA8 mit internen 8MHz-RC-Oszillator
// PB0=PA-M104B1, PB1=PB-M104B1, PB2=PC-M104B1, PB3=PD-M104B1, PB4=HIFI-TO, PB5=STBY-M104B1
// PROGRAMM RUNTER           PC0 vom ATMEGA8
// PROGRAMM RUNTER           PC1 vom ATMEGA8
// LAUTSTÄRKE VERRINGERN     PD6 vom ATMEGA8
// LAUTSTÄRKE ERHÖHEN        PD5 vom ATMEGA8
// IN BEREITSCHAFT SCHALTEN  PD4 vom ATMEGA8
// HIFI-Funktion             PD3 vom ATMEGA8
// IR-Diode an               PD7 vom ATMEGA8

#define DECODE_NEC
#define DECODE_SONY
#define DISABLE_CODE_FOR_RECEIVE_PROTOCOLS 1
#include <IRremote.hpp>

#define IR_RECEIVE_PIN 7  // IR-Diode an PD7 vom ATMEGA8

// --- Zusätzliche Tastenpins ---
#define BTN_PROG_MINUS A0  // PROGRAMM RUNTER           PC0 vom ATMEGA8
#define BTN_PROG_PLUS  A1  // PROGRAMM RUNTER           PC1 vom ATMEGA8
#define BTN_VOL_MINUS  6   // LAUTSTÄRKE VERRINGERN     PD6 vom ATMEGA8
#define BTN_VOL_PLUS   5   // LAUTSTÄRKE ERHÖHEN        PD5 vom ATMEGA8
#define BTN_STBY       4   // IN BEREITSCHAFT SCHALTEN  PD4 vom ATMEGA8
#define BTN_HIFI       3   // HIFI-Funktion             PD3 vom ATMEGA8

byte portB_state = 0xFF;
unsigned long lastValidCode = 0;
unsigned long lastActionTime = 0;
bool waitingForValidIR = false;

void setup() {
  IrReceiver.begin(IR_RECEIVE_PIN);
  DDRB = 0xFF;

  // Eingänge mit Pullups
  pinMode(BTN_PROG_MINUS, INPUT_PULLUP);
  pinMode(BTN_PROG_PLUS,  INPUT_PULLUP);
  pinMode(BTN_VOL_MINUS,  INPUT_PULLUP);
  pinMode(BTN_VOL_PLUS,   INPUT_PULLUP);
  pinMode(BTN_STBY,       INPUT_PULLUP);
  pinMode(BTN_HIFI,       INPUT_PULLUP);

  // --- Einschaltimpuls ---
  PORTB = 0xDF;
  delay(35);
  PORTB = 0xFF;
  portB_state = 0xFF;
}

void loop() {
  unsigned long now = millis();

  // === Hardware-Tasten prüfen ===
  if (digitalRead(BTN_PROG_MINUS) == LOW) {
    PORTB = 0xFD;  // PROG-
    portB_state = 0xFD;
    lastActionTime = now;
  }
  else if (digitalRead(BTN_PROG_PLUS) == LOW) {
    PORTB = 0xFE;  // PROG+
    portB_state = 0xFE;
    lastActionTime = now;
  }
  else if (digitalRead(BTN_VOL_MINUS) == LOW) {
    PORTB = 0xFC;  // VOL-
    portB_state = 0xFC;
    lastActionTime = now;
  }
  else if (digitalRead(BTN_VOL_PLUS) == LOW) {
    PORTB = 0xFA;  // VOL+
    portB_state = 0xFA;
    lastActionTime = now;
  }
  else if (digitalRead(BTN_STBY) == LOW) {
    PORTB = 0xF0;  // STBY
    portB_state = 0xF0;
    lastActionTime = now;
  }
  else if (digitalRead(BTN_HIFI) == LOW) {
    PORTB = 0xEF;  // HIFI aktiv
    portB_state = 0xEF;
    lastActionTime = now;
  }

  // === IR-CODE prüfen ===
  if (IrReceiver.decode()) {
    unsigned long code = IrReceiver.decodedIRData.decodedRawData;

    // Fehlerhafte Codes abfangen
    if (code == 0x1821 || code == 0x1020) {
      waitingForValidIR = true;
      IrReceiver.resume();
      return;
    }

    if (waitingForValidIR) {
      if (code != 0x0 && code != 0x1821 && code != 0x1020)
        waitingForValidIR = false;
      else {
        IrReceiver.resume();
        return;
      }
    }

    if (code == 0x0 && lastValidCode != 0)
      code = lastValidCode;

    byte newPortB = portB_state;

    // --- IR-Befehle --- // PB0=PA-M104B1, PB1=PB-M104B1, PB2=PC-M104B1, PB3=PD-M104B1, PB4=HIFI-TO, PB5=STBY-M104B1
    switch (code) {
      case 0xEA15FF00: case 0x90: newPortB = 0xFE; break; // CH+, P+
      case 0xE718FF00: case 0x91: newPortB = 0xFD; break; // CH-, P-
      case 0xBE41FF00: case 0x92: newPortB = 0xFA; break; // VOL+
      case 0xBD42FF00: case 0x93: newPortB = 0xFC; break; // VOL-
      case 0xF50AFF00: case 0x95: newPortB = 0xF0; break; // STBY
      case 0xBB44FF00: case 0x97: newPortB = 0xEF; break; // HIFI AKTIV
      case 0xAC53FF00: case 0xE5: newPortB = 0xF8; break; // NORMALZUSTAND
    }

    if (newPortB != portB_state) {
      PORTB = newPortB;
      portB_state = newPortB;
    }

    if (code != 0x0) lastValidCode = code;
    lastActionTime = now;
    IrReceiver.resume();
  }

  // --- Automatisches Reset ---
  if (now - lastActionTime > 500 && portB_state != 0xFF) {
    if (portB_state != 0xF0) {
      PORTB = 0xFF;
      portB_state = 0xFF;
    }
  }

  delay(50);
}
