#include "layout.h"
#include "gui.h"

// Grid
Rect Gui_Layout_Grid::rect()
{
	return last_rect;
}

void Gui_Layout_Grid::row(u32 count)
{
	cursor.x = 0;
	cursor.y += count;
}

Rect Gui_Layout_Grid::cell(u32 count)
{
	count = minimum(count, max_cells_count.x);
	s32 free_space_in_row = max_cells_count.x - cursor.x;
	if(free_space_in_row < count)
		row();

	last_rect = rect_at(cursor, {count, 1});
	cursor.x += count;

	return last_rect;
}

Rect Gui_Layout_Grid::rect_at(v2s cell_index, v2s size)
{
	Rect result;
	v2 cell_border_v = v2{cell_border, cell_border};
	result.position = window_position + cell_border_v + (cell_border_v + cell_size) * V2(cell_index);
	result.size = cell_size * V2(size) + cell_border_v * (V2(size - v2s{1,1}));
	return result;
}



Gui_Layout_Grid gui_layout_grid_create_by_divisions(v2 position, v2 window_size, u32 divisions_x, u32 divisions_y, f32 border)
{
	Gui_Layout_Grid layout;
	layout.window_position = position;
	layout.window_size     = window_size;
	layout.cell_size       = (window_size - v2{1,1}*border) / v2{divisions_x, divisions_y} - v2{1,1}*border;
	layout.cell_border     = border;
	layout.max_cells_count = v2s{divisions_x, divisions_y};

	layout.cursor = {0,0};
	layout.last_rect = layout.rect_at({0,0});

	return layout;
}

Gui_Layout_Grid gui_layout_grid_create_by_cell_size(v2 position, v2 window_size, v2 cell_size, f32 border)
{
	Gui_Layout_Grid layout;
	layout.window_position = position;
	layout.window_size     = window_size;
	layout.cell_size       = cell_size;
	layout.cell_border     = border;
	layout.max_cells_count = V2S((window_size - v2{1,1}*border) / (cell_size + v2{1,1}*border));

	layout.cursor = {0,0};
	layout.last_rect = layout.rect_at({0,0});

	return layout;
}


// Basic
Rect Gui_Layout_Basic::rect()
{
	return last_rect;
}

void Gui_Layout_Basic::push_rect(Rect r)
{
	cursor.x = cursor.x + r.size.x + element_distance.x;
	cursor.y = cursor.y;

	last_rect = r;
	next_row_y = maximum(next_row_y, cursor.y + r.size.y + element_distance.y);
}

void Gui_Layout_Basic::row()
{
	cursor.x = window_padding.x;
	cursor.y = next_row_y;
	next_row_y = cursor.y + font_size + element_distance.y;
}

Rect Gui_Layout_Basic::label_rect(const char *text)
{
	Rect r;
	r.size.y = font_size;
	r.size.x = gui_text_compute_size(text).x;

	f32 remaining_space_x = window_size.x - 2*window_padding.x - cursor.x;
	if(cursor.x != window_padding.x && remaining_space_x < r.size.x)
		row();

	r.position = window_position + cursor;

	push_rect(r);
	return r;
}

Rect Gui_Layout_Basic::button_rect(const char *text)
{
	Rect r;
	r.size.y = font_size;
	r.size.x = gui_text_compute_size(text).x;
	r.size += 2*button_padding;

	f32 remaining_space_x = window_size.x - 2*window_padding.x - cursor.x;
	if(cursor.x != window_padding.x && remaining_space_x < r.size.x)
		row();

	r.position = window_position + cursor;

	push_rect(r);
	return r;
}

Rect Gui_Layout_Basic::button_rect(f32 length)
{
	Rect r;
	r.size.y = font_size;
	r.size.x = length;
	r.size.y += 2*button_padding.y; // No x padding in this case. We already have an assigned length

	f32 remaining_space_x = window_size.x - 2*window_padding.x - cursor.x;
	if(cursor.x != window_padding.x && remaining_space_x < r.size.x)
		row();

	r.position = window_position + cursor;

	push_rect(r);
	return r;
}

Gui_Layout_Basic gui_layout_basic_create(v2 position, v2 size, f32 font_size)
{
	Gui_Layout_Basic layout;
	layout.window_position = position;
	layout.window_size = size;

	layout.cursor = {0,0};
	layout.next_row_y = 0;
	layout.last_rect = {0,0,0,0};

	layout.font_size = font_size;
	layout.button_padding = {0,0};
	layout.element_distance = {0,0};
	layout.window_padding = {0,0};

	return layout;
}
