#pragma once

/*
	PluginFramework
	by John Ryland
	Copyright (c) 2023
*/

////////////////////////////////////////////////////////////////////////////////////
//	Plugin Interface

namespace PluginFramework {

// https://en.wikipedia.org/wiki/Universally_unique_identifier
//         8-4-4-4-12
// example: 123e4567-e89b-12d3-a456-426614174000
struct UUID
{
    uint32_t    time_low; // integer giving the low 32 bits of the time
    uint16_t    time_mid; // integer giving the middle 16 bits of the time
    uint16_t    time_hi_and_version; // 4-bit "version" in the msb, followed by the high 12 bits of the time
    uint16_t    clock_seq_hi_and_res clock_seq_low; // 1 to 3-bit "variant" in the msb, followed by the 13 to 15-bit clock sequence
    uint8_t     node[6];  // the 48-bit node id (MAC address)
};

class IPlugin
{
public:
    IPlugin() {}
    virtual ~IPlugin() {}

    virtual void Initialize() = 0;
    virtual void Shutdown() = 0;

    template <typename T>
    bool InterfaceSupported()
    {
        return SupportedInterface(T::InterfaceUIID());
    }

    static UIID InterfaceUIID()
    {
        static UUID IUnknownInterfaceUUID = { 1, 2, 3, 4, 5 };
        return IUnknownInterfaceUUID;
    }

    virtual bool SupportedInterface(UUID uuid) = 0;

    virtual void Prepare() = 0;
    virtual void Update() = 0;
    virtual void Render() = 0;
    virtual void Present() = 0;
};

} // PluginFramework namespace
