/* date = May 27th 2022 9:17 pm */

#ifndef GFX_ABS_H
#define GFX_ABS_H

/* TODO(allen) - gfx_abs.h
**
** Unknown: What should a program do when there are multiple monitors with
**  different refresh rates? Should it constantly check the monitor for the
**  window(s) and dynamically apply different refresh rates? Should it pick
**  a refresh rate of it's own and just let whatever happens happen? What
**  even happens when a window straddles between two monitors?
**
**   Create an example showing how to setup an application for mixed
** Tool 2D and graphics API usage.
** 
*/

////////////////////////////////
// NOTE(allen): Static Parameters

#if !defined(GFX_MAX_WINDOW_COUNT)
# define GFX_MAX_WINDOW_COUNT 64
#endif

////////////////////////////////
// NOTE(allen): Window Handle

typedef void GFX_Window;

////////////////////////////////
// NOTE(allen): Function Types for API

typedef void GFX_ResizingFunc(GFX_Window *window, U32 width, U32 height);

////////////////////////////////
// NOTE(allen): Function Types for Graphics System Implementors

typedef void GFX_WindowReleaseFunc(GFX_Window *window);

////////////////////////////////
// NOTE(allen): APIs for All

link_function void gfx_message_box(String8 title, String8 message);


////////////////////////////////
// NOTE(allen): APIs for Applications

link_function B32 gfx_is_inited(void);
link_function B32 gfx_init(void);

link_function void              gfx_set_resizing_hook(GFX_ResizingFunc *func);
link_function GFX_ResizingFunc* gfx_get_resizing_hook(void);

link_function GFX_Window* gfx_window_create(void);
link_function void        gfx_window_destroy(GFX_Window *window);
link_function B32         gfx_window_is_valid(GFX_Window *window);

link_function B32 gfx_window_set_visible(GFX_Window *window, B32 visible);
link_function B32 gfx_window_set_title(GFX_Window *window, String8 title);
link_function B32 gfx_window_set_inner_rect(GFX_Window *window, RectS32 *rect);
link_function B32 gfx_window_get_inner_rect(GFX_Window *window, RectS32 *out);
link_function B32 gfx_window_get_outer_rect(GFX_Window *window, RectS32 *out);
link_function B32 gfx_window_set_resizable(GFX_Window *window, B32 resizable);
link_function B32 gfx_window_set_full_screen(GFX_Window *window, B32 full_screen);
link_function B32 gfx_window_is_full_screen(GFX_Window *window);
link_function B32 gfx_window_is_minimized(GFX_Window *window);
link_function B32 gfx_window_is_maximized(GFX_Window *window);

link_function B32  gfx_window_set_user_data(GFX_Window *window, void *ptr);
link_function void*gfx_window_get_user_data(GFX_Window *window);

link_function void*gfx_window_get_equipped_data(GFX_Window *window);

// TODO(allen): bad APIs - just throwing these in to get graphics
// up and running
link_function B32  gfx_wait_for_input(void);
link_function B32  gfx_peek_input(void);

// TODO(allen): would probably want a full monitor handling API but
// no idea how that would abstract yet - just throwing this in there
// for now.
link_function U64  gfx_window_refresh_rate(GFX_Window *window);

////////////////////////////////
// NOTE(allen): APIs for Graphics System Implementors

// available for this layer, but defined in the previous section:
//  gfx_window_is_valid
// TODO(allen): "allow" gfx_window_get_user_data here?

link_function B32
gfx_window_set_equipped_data(GFX_Window *window, void *ptr,
                             GFX_WindowReleaseFunc *release_func);

#endif //GFX_ABS_H
