/* date = April 26th 2023 5:12 pm */

#ifndef VN_PLATFORM_H
#define VN_PLATFORM_H

#include "core/core.h"
#include "core/core_math.h"
#include "core/core_memory.h"
#include "core/core_string.h"
#include "core/core_thread_context.h"

// sixten: Services the platform provides to the application

enum
{
    PlatformAccess_Read = 0x1,
    PlatformAccess_Write = 0x2,
};
typedef u32 platform_access_flags;

struct platform_file_handle
{
    u64 Platform;
    b32 IsValid;
};

struct platform_file_info
{
    string Name;
    b32 IsDirectory;
};

struct platform_file_iter
{
    u64 U64[1024];
};

enum platform_cursor
{
    PlatformCursor_Arrow,
    PlatformCursor_Cross,
    PlatformCursor_Hand,
    PlatformCursor_Help,
    PlatformCursor_IBeam,
    PlatformCursor_SlashedCircle,
    PlatformCursor_ArrowAll,
    PlatformCursor_ArrowNESW,
    PlatformCursor_ArrowVertical,
    PlatformCursor_ArrowNWSE,
    PlatformCursor_ArrowHorizontal,
    PlatformCursor_Wait,
    
    PlatformCursor_Count
};

enum platform_message_type
{
    Platform_Message_Info,
    Platform_Message_Warning,
    Platform_Message_Error,
    Platform_Message_Fatal,
};

enum platform_event_type
{
    PlatformEvent_Press,
    PlatformEvent_Release,
    PlatformEvent_Text,
    PlatformEvent_MouseScroll,
    PlatformEvent_WindowClose,
};

enum platform_key
{
    Key_Invalid,
    
    Key_A, Key_B, Key_C, Key_D,
    Key_E, Key_F, Key_G, Key_H,
    Key_I, Key_J, Key_K, Key_L,
    Key_M, Key_N, Key_O, Key_P,
    Key_Q, Key_R, Key_S, Key_T,
    Key_U, Key_V, Key_W, Key_X,
    Key_Y, Key_Z,
    
    Key_F1, Key_F2,  Key_F3,  Key_F4,
    Key_F5, Key_F6,  Key_F7,  Key_F8,
    Key_F9, Key_F10, Key_F11, Key_F12,
    
    Key_Left, Key_Right, Key_Up, Key_Down,
    
    Key_Space, Key_Return,
    
    Key_PageUp, Key_PageDown,
    Key_Home, Key_End,
    
    Key_Backspace, Key_Delete,
    
    Key_MouseLeft, Key_MouseMiddle, Key_MouseRight, 
};

typedef u32 platform_modifiers;
enum
{
    PlatformModifier_Ctrl          = (1 << 0),
    PlatformModifier_Shift         = (1 << 1),
    PlatformModifier_Alt           = (1 << 2),
    
    PlatformModifier_DoesNotMatter = -1
};

struct platform_event
{
    platform_event *Next;
    platform_event *Prev;
    platform_event_type Type;
    platform_modifiers Modifiers;
    platform_key Key;
    u32 Codepoint;
    v2 P;
    v2 Scroll;
};

struct platform_event_list
{
    platform_event *First;
    platform_event *Last;
};

#include "generated/vn_platform.meta.h"

static platform_api Platform;

// sixten: Services that the render backend provides to the application

#include "vn_render.h"

#define RENDER_ALLOCATE_TEXTURE(name) render_handle name(v2_s32 Dim, render_texture_format Format, void *Data)
typedef RENDER_ALLOCATE_TEXTURE(render_allocate_texture);

#define RENDER_FILL_REGION(name) void name(render_handle Handle, v2_s32 DestP, v2_s32 DestDim, void *Data)
typedef RENDER_FILL_REGION(render_fill_region);

struct vn_render_commands
{
    render_allocate_texture *AllocateTexture;
    render_fill_region *FillRegion;
    
    render_handle WhiteTexture;
    
    u64 MaxPushBufferSize;
    u8 *PushBufferBase;
    u8 *PushBufferAt;
    
#if VN_USE_INSTANCING
    s32 MaxInstancedQuadCount;
    instanced_quad *InstancedQuadBase;
    s32 InstancedQuadCount;
#else
    s32 MaxQuadVertexCount;
    quad_vertex *QuadVertexBase;
    s32 QuadVertexCount;
    
    s32 MaxQuadIndexCount;
    s32 *QuadIndexBase;
    s32 QuadIndexCount;
#endif
    
    v2 RenderDim;
};

// sixten: Services the application provides to the platform

struct vn_input
{
    // sixten: Platform to application
    platform_event_list *EventList;
    
    v2 MouseP;
    v2 dMouseP;
    
    r32 dtForFrame;
    
    // sixten: Application to platform
    s32 RefreshRate;
    b32 ExitRequested;
};

struct vn_memory
{
    platform_api PlatformAPI;
    
    struct vn_state *State;
};

#define VN_UPDATE_AND_RENDER(name) void name(thread_context *ThreadContext, vn_memory *Memory, vn_input *Input, vn_render_commands *RenderCommands)
typedef VN_UPDATE_AND_RENDER(vn_update_and_render);

#include "core/core_math.cpp"
#include "core/core_memory.cpp"
#include "core/core_string.cpp"
#include "core/core_thread_context.cpp"

#endif //VN_PLATFORM_H
