# Enumerated types and state machines

You can create our own types in C#. An example is `enum`. 

If a variable can only have a specific number of values, then an `enum` is useful.

:::{wpd} enumerated type
a data type consisting of a set of named values called *enumerators* of the type. The enumerator names are usually identifiers that behave as constants.
:::

Example:

```cs
var machines = new List<IndustrialMachine>
{
    new("CNC-Lathe-01", MachineStatus.Running, Priority.Low),
    new("Hydraulic-Press-02", MachineStatus.Warning, Priority.Medium),
    new("Conveyor-Belt-03", MachineStatus.Error, Priority.Critical),
    new("Welding-Robot-04", MachineStatus.Maintenance, Priority.High, MaintenanceType.Preventive)
};

// Status-based operations
foreach (var machine in machines)
{
    var statusMessage = machine.Status switch
    {
        MachineStatus.Running => "✅ Operating normally",
        MachineStatus.Warning => "⚠️ Requires attention",
        MachineStatus.Error => "❌ Production stopped",
        MachineStatus.Maintenance => $"🔧 Under {machine.ScheduledMaintenance} maintenance",
        MachineStatus.Starting => "🔄 Starting up...",
        MachineStatus.Stopped => "⏹️ Offline",
        _ => "Unknown status"
    };

    Console.WriteLine($"{machine.Name}: {statusMessage} (Priority: {machine.AlertLevel})");
}

internal enum MachineStatus
{
    Stopped,
    Starting,
    Running,
    Warning,
    Error,
    Maintenance
}

internal enum MaintenanceType
{
    Preventive,
    Corrective,
    Emergency,
    Calibration
}

internal enum Priority
{
    Low = 1,
    Medium = 2,
    High = 3,
    Critical = 4
}

internal record IndustrialMachine(
    string Name,
    MachineStatus Status,
    Priority AlertLevel,
    MaintenanceType? ScheduledMaintenance = null
);
```
(Example generated with GitLab Duo. Slightly modified)

Output:
```text
CNC-Lathe-01: ✅ Operating normally (Priority: Low)
Hydraulic-Press-02: ⚠️ Requires attention (Priority: Medium)
Conveyor-Belt-03: ❌ Production stopped (Priority: Critical)
Welding-Robot-04: 🔧 Under Preventive maintenance (Priority: High)
```

State machines are often implemented using enumerated types. A state machine can also be used to model the behavior of a robot.


:::{activity} Coffee machine state machine
Implement the following state machine for a coffee machine using a console program. Use an `enum` for the states. Simulate the states using console messages like *brewing*.

Steps:
1. define an enumerated type
1. define a variable with this type
1. create an endless loop
1. use an `if-else` statement to differentiate between the actions.
1. An action can be, e.g., wait (use `Task.Delay(milliseconds)`) or change state.

```{mermaid}
stateDiagram-v2
    [*] --> IDLE

    IDLE --> BREWING: "s" pressed
    BREWING --> DONE: after 2s
    DONE --> IDLE: "r" pressed
    DONE --> [*]: "e" pressed
```
:::