#pragma once

#include <Core/Common/NonNullPtr.h>
#include <Core/Container/Vector.h>
#include <Core/HAL/Display/Window.h>

namespace Juliet
{
    // Driver to the display device.
    // Functions ptr will be set by the chosen factory
    // Acts as a singleton after Initialize has been called and is freed in Shutdown.
    struct DisplayDevice
    {
        Arena* Arena;

        const char* Name = "Unknown";

        // Initialize all subsystems needed for the device to works
        bool (*Initialize)(NonNullPtr<DisplayDevice> self);
        void (*Shutdown)(NonNullPtr<DisplayDevice> self);
        void (*Free)(NonNullPtr<DisplayDevice> self);

        // Window management
        bool (*CreatePlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
        void (*DestroyPlatformWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
        void (*ShowWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
        void (*HideWindow)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window);
        void (*SetWindowTitle)(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, String title);

        // Events
        void (*PumpEvents)(NonNullPtr<DisplayDevice> self);

        VectorArena<Window> Windows;
    };

    struct DisplayDeviceFactory
    {
        const char* Name = "Unknown";
        DisplayDevice* (*CreateDevice)(Arena* arena);
    };

    // TODO : Support more platforms
    extern DisplayDeviceFactory Win32DisplayDeviceFactory;

    // Utils
    extern DisplayDevice* GetDisplayDevice();
} // namespace Juliet
