// =======================================================================
// LOGIKKISTE - ZUSTANDS-REGISTER (OBJEKTORIENTIERTES KLASSEN-MODELL)
// =======================================================================

Blockly.defineBlocksWithJsonArray([
    // --- 1. DAS ZUSTANDS-REGISTER (HAUPTRAHMEN) ---
    {
        "type": "ard_class_register",
        "message0": "Zustands-Register (Klassen-Modell) 🗂️",
        "message1": "Start-Zustand (Name): %1",
        "args1": [
            {"type": "field_input", "name": "START_STATE", "text": "Start"}
        ],
        "message2": "Zustände hier einfügen: %1",
        "args2": [
            {"type": "input_statement", "name": "STATES", "check": "ClassStateBlock"}
        ],
        "previousStatement": null,
        "nextStatement": null,
        "colour": 260,
        "tooltip": "Der Hauptrahmen für das Klassen-Modell. Alle Zustände werden hier sicher und isoliert als C++ Klassen abgelegt."
    },

    // --- 2. DER ZUSTANDS-BLOCK (DIE KLASSE) ---
    {
        "type": "ard_class_state",
        "message0": "Zustand (Name): %1",
        "args0": [
            {"type": "field_input", "name": "STATE_NAME", "text": "MeinZustand"}
        ],
        "message1": "Einmalig beim Start (Enter) %1",
        "args1": [{"type": "input_statement", "name": "ENTER"}],
        "message2": "Zyklisch (Update) %1",
        "args2": [{"type": "input_statement", "name": "UPDATE"}],
        "message3": "Einmalig beim Ende (Exit) %1",
        "args3": [{"type": "input_statement", "name": "EXIT"}],
        "previousStatement": "ClassStateBlock",
        "nextStatement": "ClassStateBlock",
        "colour": 260,
        "tooltip": "Definiert einen isolierten Zustand. Der Code in 'Enter' und 'Exit' wird beim Betreten bzw. Verlassen automatisch ausgeführt."
    },

    // --- 3. DER UMSCHALT-BLOCK (TRANSITION) ---
    {
        "type": "ard_class_change",
        "message0": "Wechsle zu Zustand (Name): %1",
        "args0": [
            {"type": "field_input", "name": "NEXT_STATE", "text": "MeinZustand"}
        ],
        "previousStatement": null,
        "nextStatement": null,
        "colour": 260,
        "tooltip": "Beendet den aktuellen Zustand (führt dessen Exit-Code aus) und startet sofort den neuen Zustand (führt dessen Enter-Code aus)."
    }
]);


// =======================================================================
// C++ CODE GENERATOREN
// =======================================================================

// --- 1. GENERATOR: ZUSTANDS-REGISTER ---
ArduinoGenerator.forBlock['ard_class_register'] = function(block) {
    // Säubere den Namen des Start-Zustands von Leer- und Sonderzeichen
    const startState = block.getFieldValue('START_STATE').replace(/[^a-zA-Z0-9_]/g, '');

    // 1. Die abstrakte Basisklasse im globalen Scope anlegen
    ArduinoGenerator.globals_.add(`// --- Basisklasse für das Zustands-Register ---
class State {
public:
  virtual void enter() {}
  virtual void update() = 0;
  virtual void exit() {}
  virtual ~State() {}
};`);

    // 2. Den globalen Zeiger auf den aktuellen Zustand anlegen
    ArduinoGenerator.globals_.add(`State* currentState = nullptr;`);

    // 3. Die universelle Umschalt-Funktion (Dispatcher) anlegen
    ArduinoGenerator.globals_.add(`void changeState(State* newState) {
  if (currentState != nullptr) {
    currentState->exit();
  }
  currentState = newState;
  if (currentState != nullptr) {
    currentState->enter();
  }
}`);

    // 4. Alle Kinder-Blöcke (die Zustände) aufrufen. 
    // Diese bauen ihre eigenen Klassen und legen sie in globals_ ab.
    ArduinoGenerator.statementToCode(block, 'STATES');

    // 5. Setup: Den ausgewählten Startzustand beim Hochfahren setzen
    if (startState !== "") {
        ArduinoGenerator.autoSetup_.push(`  changeState(&state_${startState});\n`);
    }

    // 6. Loop: In jedem Zyklus die Update-Funktion der aktuellen Klasse aufrufen
    let code = `  // --- Zustands-Register Update ---
  if (currentState != nullptr) {
    currentState->update();
  }\n`;

    return code;
};


// --- 2. GENERATOR: EINZELNER ZUSTAND (DIE KLASSE) ---
ArduinoGenerator.forBlock['ard_class_state'] = function(block) {
    // Säubere den Klassennamen
    const stateName = block.getFieldValue('STATE_NAME').replace(/[^a-zA-Z0-9_]/g, '');
    
    // Generiere den Code aus den drei Zonen
    const enterCode = ArduinoGenerator.statementToCode(block, 'ENTER');
    const updateCode = ArduinoGenerator.statementToCode(block, 'UPDATE');
    const exitCode = ArduinoGenerator.statementToCode(block, 'EXIT');

    // Baue die isolierte C++ Klasse zusammen
    let classCode = `\n// --- Zustandsklasse: ${stateName} ---
class State_${stateName} : public State {
public:
  void enter() override {
${enterCode}  }
  void update() override {
${updateCode}  }
  void exit() override {
${exitCode}  }
};
State_${stateName} state_${stateName}; // Instanz erstellen\n`;

    // Lege die fertige Klasse im globalen Bereich ab
    ArduinoGenerator.globals_.add(classCode);

    // Der Block selbst gibt nichts in den Loop zurück, da der Aufruf über den Register-Block läuft
    return '';
};


// --- 3. GENERATOR: UMSCHALT-BLOCK (TRANSITION) ---
ArduinoGenerator.forBlock['ard_class_change'] = function(block) {
    // Säubere den Zielnamen
    const nextState = block.getFieldValue('NEXT_STATE').replace(/[^a-zA-Z0-9_]/g, '');
    
    // Führe die Transition aus und breche die aktuelle Update-Funktion mit 'return' sofort ab
    return `  changeState(&state_${nextState});\n  return;\n`;
};