@Tutorial {

    @Intro(title: "Model the task data") {
        Data modelling is the art of creating a data model for representing real-world concepts in your code.
        Create a model to represent the tasks.
    }

    @Section(title: "Create a new type to represent a task") {
        @ContentAndMedia {
            Create a `Task` type that holds a task's label, completion, and subtasks.
        }
        @Steps {
            @Step {
                Create a new file `Task.swift` by right-clicking on the `Sources` folder in the sidebar of GNOME Builder.
                @Image(source: "NewFile.png", alt: "GNOME Builder's file context menu in the sidebar.")
            }
            @Step {
                Declare a new structure called `Task`.
                @Code(name: "Task.swift", file: "Task2.swift", previousFile: "Task1.swift")
            }
            @Step {
                Create the three stored properties for a task's label, completion, and subtasks.
                @Code(name: "Task.swift", file: "Task3.swift")
            }
            @Step {
                In the user interface, there will be a text field for entering the label of a new task.
                This means that a label is available before the instance of the type `Task` is created.
                The other two properties have a default value at the beginning and can be modified after the task's creation.
                Therefore, it makes sense to initialize these properties with default values.

                Let `done` be `false` and `subtasks` be an empty array when adding a task.
                @Code(name: "Task.swift", file: "Task4.swift")
            }
            @Step {
                The check box for toggling the task's completion should not only indicate whether a task is done or not,
                but also indicate the state of their subtasks. If the task is not completed, but some of their subtasks are, a mixed state design is visible.

                It is a good practice to add computed properties to type definitions in order to be able to focus on the UI when creating views.
                @Code(name: "Task.swift", file: "Task5.swift")
            }
        }
    }

    @Section(title: "Add protocol conformances") {
        @ContentAndMedia {
            As you've already seen in the Foundation section, a common way to make functions and types more flexible is by using protocols instead of concrete types.
            Every type conforming to a certain protocol can then be used as a parameter.
            In this section, you'll make the task type to protocols enabling tasks to be easily saved to the disk, listed in a view, or used for the window's title.
        }

        @Steps {
            @Step {
                Add `Codable` conformance.

                `Codable` enables a Swift type to be easily converted into and out of JSON representation that can be saved on the disk.
                @Code(name: "Task.swift", file: "Task6.swift", previousFile: "Task5.swift")
            }
            @Step {
                Add `Identifiable` conformance.

                `Identifiable` is a protocol that requires a type to have a property `id` that is unique across the app.
                `UUID` is a type often used for IDs that stores a random value after its initialization and is defined on Swift's [Foundation library](https://developer.apple.com/documentation/foundation).
                It is used by the ``List`` view that you'll later use to track how elements change.
                @Code(name: "Task.swift", file: "Task7.swift")
            }
            @Step {
                Add `CustomStringConvertible` conformance.

                This will allow the `Task` type to be used as a destination in the ``NavigationView`` that will be used for navigating subtasks, making the parent task the window's title.
                @Code(name: "Task.swift", file: "Task8.swift")
            }
        }
    }

}
