#pragma once

#include <stdint.h>

#ifdef __linux__
# include <cstddef>
# include <sys/types.h>
#endif

// ::BaseTypes::

typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

typedef char c8;

typedef intptr_t intptr;
typedef uintptr_t uintptr;

typedef float f32;
typedef double f64;

typedef uint8_t b8;
typedef uint32_t b32;

typedef void * rawptr;

#ifdef __linux__
	typedef ssize_t isize;
	typedef size_t usize;
#elif _WIN64
	typedef int64_t isize;
	typedef u64 usize;
#elif _WIN32
	typedef i32 isize;
	typedef u32 usize;
#endif

typedef struct String8
{
	c8  *value;
	u64 len;
} String8;

typedef union
{
	struct { f32 x, y, z, w; };
	struct { f32 r, g, b, a; };
} Vec4;

typedef union
{
	struct { u8 x, y, z, w; };
	struct { u8 r, g, b, a; };
	struct { u32 packed; 		};
} U8Vec4;

// ::Macros::

#define i8(x) ((i8)(x))
#define i16(x) ((i16)(x))
#define i32(x) ((i32)(x))
#define i64(x) ((i64)(x))

#define u8(x) ((u8)(x))
#define u16(x) ((u16)(x))
#define u32(x) ((u32)(x))
#define u64(x) ((u64)(x))

#define c8(x) ((c8)(x))
#define c8ptr(x) ((c8 *)(x))
#define u8ptr(x) ((u8 *)(x))
#define i8ptr(x) ((i8 *)(x))

#define intptr(x) ((intptr)(x))
#define uintptr(x) ((uintptr)(x))

#define f32(x) ((f32)(x))
#define f64(x) ((f64)(x))

#define rawptr(x) ((rawptr)(x))

#define cast(T, x) ((T)(x))

#define isizeof(T) ((isize)(sizeof(T)))
