#pragma once
#include <stdint.h>
#include "ogl.h"
#include "stringmap.h"
struct _yr_ui_screen;
typedef struct _yr_ui_screen* yrUiScreen;
struct _yr_ui_elem;
typedef struct _yr_ui_elem* yrUiElem;
struct yr_ui_rendertexes;
#define color_undefined (0x001A1A1Aul)

typedef void (*func_screen_callback)(yrUiScreen s);
#define UISCREEN_MAX_CALLBACKS 32
#define UIRENDER_BUFFER 64

enum UiScreenId { usVRMode, usFile, usBackgrounds, usExport, usExportProgress, usImport, us_end };
yrUiScreen		yrUiScreen_load(		enum UiScreenId id);
void			yrUiScreen_destroy(		yrUiScreen s);
enum UiScreenId	yrUiScreen_nextscreen(	yrUiScreen s);
void			yrUiScreen_tick(		yrUiScreen s);
void			yrUiScreen_render(		yrUiScreen s, struct yr_ui_rendertexes* unis);
void			yrUiScreen_resize(		yrUiScreen s, float scale, float ar);
void			yrUiScreen_reset(		yrUiScreen s);
void			yrUiScreen_mousepos(	yrUiScreen s, float x, float y);
void			yrUiScreen_keyevent(	yrUiScreen s, unsigned keycode, int down);
void			yrUiScreen_char(		yrUiScreen s, unsigned c);
void			yrUiScreen_elemcallback(yrUiScreen s, yrUiElem e);

void	yrUiElem_destroy(	yrUiElem e);
void	yrUiElem_layout(	yrUiElem e, float scale, float ar);
void	yrUiElem_render(	yrUiElem e, uint32_t inherit_fg, struct yr_ui_rendertexes* unis);
void	yrUiElem_reset(		yrUiElem e);
void	yrUiElem_mousepos(	yrUiElem e, float x, float y);
void	yrUiElem_keyevent(	yrUiElem e, unsigned keycode, int down, yrUiScreen s);
void	yrUiElem_char(		yrUiElem e, unsigned c);
void	yrUiElem_set_enabled(	yrUiElem e, int enabled);
void	yrUiElemText_set_text(	yrUiElem e, const char* text);
void	yrUiElemBgList_populate(		yrUiElem e, const char* scenec);
void	yrUiElemBgList_savetofile(		yrUiElem e, const char* scenec);
void	yrUiElemBgList_remove_selected(	yrUiElem e);
void	yrUiElemBgList_replace_selected(yrUiElem e);
void	yrUiElemBgList_add(				yrUiElem e);
void	yrUiElemCheck_set(				yrUiElem e, int checked);
void	yrUiElemEdit_input_enabled(		yrUiElem e, int enabled);
void	yrUiElemProgress_set_progress(	yrUiElem e, float progress);

struct _yr_ui_screen {
	enum UiScreenId id;
	enum UiScreenId next;
	unsigned elemcount;
	yrUiElem* elems;
	float scale;
	float ar;
	yrStringmap* idmap;
	void* data;

	yrUiElem				cb_elems[UISCREEN_MAX_CALLBACKS];
	func_screen_callback	cb_funcs[UISCREEN_MAX_CALLBACKS];
};

enum UiElementType { etRect, etImage, etText, etNewline, etBgList, etCheck, etEdit, etProgress, etMirror, et_end };
enum UiTextAlign { taLeft, taCenter, taRight };
#define UIELEM_ENABLED ((uint32_t) 1)
#define UIELEM_HOVER ((uint32_t) 2)
#define UIELEM_DOWN ((uint32_t) 4)
#define UIELEM_CHECKED ((uint32_t) 8)
struct _yr_ui_elem
{
	enum UiElementType type;
	float w;
	float h;
	float x;
	float y;
	uint32_t bg;
	uint32_t bg_hover;
	uint32_t bg_down;
	uint32_t bg_disabled;
	uint32_t fg;
	uint32_t fg_hover;
	uint32_t fg_down;
	uint32_t fg_disabled;
	uint32_t flags;
};

struct _yr_ui_elem_rect
{
	struct _yr_ui_elem;
	float hpad;
	float vpad;
	unsigned childcount;
	yrUiElem* children;
};
typedef struct _yr_ui_elem_rect* yrUiElemRect;

struct _yr_ui_elem_image
{
	struct _yr_ui_elem;
	GLuint tex;
	uint64_t handle_tex;
};
typedef struct _yr_ui_elem_image* yrUiElemImage;

struct _yr_ui_elem_newline
{
	struct _yr_ui_elem;
};
typedef struct _yr_ui_elem_newline* yrUiElemNewline;

struct _yr_ui_elem_text
{
	struct _yr_ui_elem;
	float size;
	char* text;
	enum UiTextAlign align;
	char singleline;
	char autowidth;
	GLuint bitmap;
	uint64_t handle_bitmap;
};
typedef struct _yr_ui_elem_text* yrUiElemText;

struct _yr_ui_elem_check
{
	struct _yr_ui_elem;
};
typedef struct _yr_ui_elem_check* yrUiElemCheck;

struct _yr_ui_elem_edit
{
	struct _yr_ui_elem;
	uint64_t lastblink;
	char* buffer;
	enum UiTextAlign align;
	float size;
	float border;
	char input_enabled;
	char caret_on;
	unsigned capacity;
	unsigned caretpos;
	float caret_x;
	float text_x;
	float scale;
	float ar;
	float bitmap_w;
	GLuint bitmap;
	uint64_t handle_bitmap;
};
typedef struct _yr_ui_elem_edit* yrUiElemEdit;

struct _yr_ui_elem_progress
{
	struct _yr_ui_elem;
	float progress;
	float bitmap_h;
	GLuint bitmap;
	uint64_t handle_bitmap;
};
typedef struct _yr_ui_elem_progress* yrUiElemProgress;

#define BG_MAX_TEX 125
struct _yr_ui_elem_bglist
{
	struct _yr_ui_elem;
	uint32_t id_remap[BG_MAX_TEX];
	unsigned char count;
	unsigned char selected;
	uint32_t last_id;
	GLuint bg_tex[BG_MAX_TEX];
	uint64_t handle_bg_tex[BG_MAX_TEX];
	unsigned bg_size[BG_MAX_TEX];
	unsigned total_size;
	float scroll_pos;
	float scroll_max;
	GLuint scroll_icon;
	uint64_t handle_scroll_icon;
	float scale;
	float ar;
	uint32_t fg2;
	int scroll_hover;
	float scrolling;
	float mousex;
	float mousey;
	GLuint count_indic;
	uint64_t handle_count_indic;
	float count_height;
	float capa_h_text;
	float capa_h_0;
	float capa_h_100;
	GLuint capa_text;
	uint64_t handle_capa_text;
	GLuint capa_0;
	uint64_t handle_capa_0;
	GLuint capa_100;
	uint64_t handle_capa_100;
};
typedef struct _yr_ui_elem_bglist* yrUiElemBgList;

struct _yr_ui_elem_mirror
{
	struct _yr_ui_elem;
	float scale;
	float ar;
};
typedef struct _yr_ui_elem_mirror* yrUiElemMirror;

struct yr_ui_rendertexes
{
	GLint ar;
	GLuint notex;
	GLuint checktex;
	GLuint nocheck;
	GLuint mirror;
	GLuint ssbo;
	uint64_t handle_notex;
	uint64_t handle_checktex;
	uint64_t handle_nocheck;
	uint64_t handle_mirror;
};

struct yr_ui_ssbo
{
	float size[2];
	float pos[2];
	uint32_t fg;
	uint32_t bg;
	uint64_t texhandle;
};