#pragma once

// ::Platform::Types::Header::

typedef struct Library Library;
typedef struct Function Function;

// ::Platform::Includes::Header::

#if __linux__
#include "platform/platform_linux.h"
#endif

#if _WIN32
#include "platform/platform_windows.h"
#endif

#if __APPLE__ || __MACH__
#error Not yet implemented
#endif

#if __unix__ && !__linux__
#error Not yet implemented
#endif

// ::Platform::Types::Header::

typedef struct WindowSize 
{
	u16 h, w;
} WindowSize;

// ::Platform::ConsoleOut::Functions::Header::

i32 WriteStdOut(void *buf, i32 len);
i32 WriteStdErr(void *buf, i32 len);

// ::Platform::Library::Functions::Header::

b32 LoadLib(const char *name, Library *out_lib);
b32 LoadFn(const char *name, Library *lib, Function *out_fn);

// ::Platform::Memory::Functions::Header::

rawptr MemAlloc(usize size);
rawptr MemAllocZeroed(usize size);
rawptr MemRealloc(rawptr ptr, usize old_size, usize new_size);
void MemFree(rawptr ptr, usize size);
usize GetPageSize();

// ::Platform::Window::Functions::Header::

b32 CreatePlatformWindow(const char *window_name);
WindowSize GetWindowSize();
b32 ShouldQuit();
PlatformWindow *GetPlatformWindow();

// ::Platform::SystemInfo::Functions::Header::

u32 AvailableCPUCount();

// ::Platform::FileSystem::Functions::Header::

b32 ChangeDir(c8 *dir);
c8 **GetFileNamesInDir(Arena *arena, u32 *count);
b8 DirVisible(c8 *dir_name);

// ::Platform::Profiling::Functions::Header::

static u64 GetOSTimerFreq();
static u64 ReadOSTimer();
static inline u64 ReadCPUTimer();

// ::Platform::Atomics::Header::

static inline u32 AtomicFetchIncrU32(u32 *ptr);
static inline void AtomicIncrU32(u32 *ptr);
