// -- ---------------------------------------------------------------------------------------- --
// --    1. Der Dampfkessel meldet Überdruck
// -- ---------------------------------------------------------------------------------------- --
// Thema: eigener Delegate-Typ + einfaches Event
 
// Ein  Luftschiff-Ingenieur überwacht einen Dampfkessel. Sobald der Druck zu hoch wird, soll ein
// Event ausgelöst werden.
 
 
class SteamBoiler {
 
    public delegate void PressureHandler(int pressure);
 
    public event PressureHandler? OnOverPressure;
 
 
    // 1.1) Schreiben Sie eine Methode zum Ausloesen des Events.
    // a) Gegen Sie die Höhe des Drucks auf der Konsole aus.
    // b) Ist der Druck höher als 10 soll das Event OnOverPressure
    //    ausgelöst werden.
 
}
 
 
// 1.2) Schreiben Sie einen Unittest der die zuvor geschriebene
// Logik testet.
 
class BoilerClassTest {
    // 1.2) Vervollständigen Sie den folgenden Test
    [Test]
    public void SteamEventTest() {
        // 1.2.1) Instanzieren Sie den Publisher
 
 
        // 1.2.2) Implementieren Sie 2 unterschiedliche Subscriber Methoden in
        Form eines Lambdas
 
        a) Subscriber: Geben Sie eine Warnung auf der Konsole aus.
 
        b) Subscriber: Geben Sie auf der Konsole die Aufforderung aus, dass Schiff
        zu verlassen.
 
        // 1.2.3) Lösen Sie das Event aus
 
    }
}
 
 
 
// -- ---------------------------------------------------------------------------------------- --
// --  2. CoalChamber
// -- ---------------------------------------------------------------------------------------- --
// Die CooperSeagal, ein dampfbetriebenes Luftschiff, besitzt mehrere Kohlekammern.
 
 
class CoalChamber {
 
    public delegate void CoalInventoryHandler(string coalChamber, int remainingStock);
 
    public event CoalInventoryHandler? OnCoalSpend;
 
    // 2.1 Implementieren Sie die UseCoal Methode
    public void UseCoal(string coalChamber, int remainingStock) {
 
        // a) Geben Sie den Namen der Kohlekammer aus.
 
 
        // b) Ist der Restbestand <= 5 soll das OnCoalSpend Event ausgelöst
        // werden.
 
    }
}
 
class Program {
 
    // 2.2) Adaptiern Sie den folgenden Code auf Ihr Beispiel und testen Sie ihn.
    // Uebersetzten Sie die Begriffe ins Englische
    static void Main() {
        Kohlenkammer lager = new Kohlenkammer();
 
        lager.KohleLeer += MechanikerWarnen;
 
        lager.KohleEntnehmen("Kammer Alpha", 20);
        lager.KohleEntnehmen("Kammer Alpha", 4);
    }
 
    static void MechanikerWarnen(string kammer, int restbestand)
    {
        Console.WriteLine(
            $"Mechaniker! {kammer} hat nur noch {restbestand} kg!");
    }
}
 
 
// -- ---------------------------------------------------------------------------------------- --
// --  3. Pirateattack
// -- ---------------------------------------------------------------------------------------- --
Thema: mehrere Events und mehrere eigene Delegate-Typen
 
Ein Luftschiff kann sowohl einen Piratenangriff als auch einen Maschinenschaden melden.
 
 
class Airship {
    public delegate void AttackHandler(string pirateShip);
    public delegate void DamageHandler(string component, int damageLevel);
 
    public event AttackHandler? OnPirateAttack;
    public event DamageHandler? OnDamage;
 
    // 3.1 Schreiben Sie für die beiden Events jeweils eine Methode um Sie
    // auszulösen.
 
}
 
// 3.2 Subscriber Test
 
// Implementieren Sie für jede der folgenden Ausgaben einen Subscriber.
 
// a) OnPirateAttack: Sky pirates spotted: The Iron Vulture!
// b) OnPirateAttack: Prepare the steam cannons!
 
 
// c) OnDamage: Damage detected in the left engine!
// d) OnDamage: Damage level: 4
// e) Call the mechanic!
 
 
 
// -- ---------------------------------------------------------------------------------------- --
// --  4. Steamengine started
// -- ---------------------------------------------------------------------------------------- --
// Übergang zum Eventhandler ohne Parameter. Verwenden Sie das EventHandler Delegate der .net
// Standardlibrary
 
 
public class SteamEngine {
    // 4.1 Verwenden Sie den EventHandler ohne Parameter um ein OnStart
    // Event zu definieren
 
    public void StartEngine () {
        Console.WriteLine("Zisch... Klack... RUMM!");
        Console.WriteLine("Die Dampfmaschine läuft.");
 
        // 4.2 Feuern Sie das OnStart Event
 
    }
}
 
public class SteamEngineTest {
 
    public void StartEngineTest() {
        SteamEngine engine = new SteamEngine();
 
        // 4.2 Registrieren Sie die StartEngine Methode
        //     Starten Sie die engine
        //
        // Hinweis: Sind keine Argumente notwendig
        // wird EventArgs.Empty verwendet.
 
    }
 
    static void StartEngine(object? sender, EventArgs e) {
        Console.WriteLine("Der Maschinist meldet: Maschine läuft!");
    }
}
 
 
 
 
 
// -- ---------------------------------------------------------------------------------------- --
// --  5. AetherCrystal
// -- ---------------------------------------------------------------------------------------- --
// Eventhandler mit Parametern. Verwenden Sie das EventHandler Delegate der .net Standardlibrary
// mit Parameter.
 
 
// Definition der Event Argumente
class OverheatingEventArgs : EventArgs {
    public int Temperature { get; }
    public string CrystalName { get; }
 
    public OverheatingEventArgs(int temperature, string crystalName) {
        Temperature = temperature;
        CrystalName = crystalName;
    }
}
 
 
class AetherCrystal {
 
    // 5.1 Verwenden Sie den EventHandler mit dem OverheatingEventArgs Parameter um
    // ein OnOverheating Event zu definieren
 
    public void CheckTemperature(int temperature) {
        Console.WriteLine($"Crystal temperature: {temperature} °C");
 
 
        if (temperature > 120)
        {
            // 5.2 Feuern Sie das OnOverheating Event
 
        }
    }
}
 
// 5.3 Registieren Sie die folgende Methode als Subscriber in einer Konsolenanwendung
 
static void KristallUeberhitzt(
    object? sender,
    UeberhitzungsEventArgs e)
{
    Console.WriteLine(
        $"WARNUNG: {e.KristallName} hat {e.Temperatur} °C!");
}