package main

import rl "vendor:raylib"
import "core:math/ease"
import "core:fmt"

MenuItemType :: enum {
	NONE,
	BOOL,
	INT,
}

BoolStrings := map[bool]cstring {
	true = "вкл",
	false = "выкл"
}

MenuItem :: struct{
	text: cstring,
	param: rawptr,
	type: MenuItemType,
}

MenuList :: struct($T: typeid) {
	state: ^GameState,
	position: vec2,
	line_size: f32,
	font_size: f32,
	active_element: T,
	active_marker: vec2,
	tween: ^Tween,
	elements: ^[T]MenuItem,
	menu_pressed: proc(state: ^GameState, element: T),
	background: rl.Color,
	mouse_pos: vec2,
}


menu_list_update :: proc(list: ^MenuList($T)) {

	activate_element := false
	prev_element := cast(i8)list.active_element
	cur_element := prev_element

	last_mouse_pos := list.mouse_pos
	list.mouse_pos = rl.GetMousePosition()

	size := menu_list_get_size(list)
	if rl.CheckCollisionPointRec(list.mouse_pos, rl.Rectangle{
		x = list.position.x,
		y = list.position.y,
		width = size.x,
		height = size.y,
	}) {
		if last_mouse_pos != list.mouse_pos {
			mouse_relative := list.mouse_pos - list.position	
			cur_element = i8(mouse_relative.y / list.line_size)
		}
		if rl.IsMouseButtonPressed(rl.MouseButton.LEFT) {
			list.menu_pressed(list.state, list.active_element)
		}
	}
	last_mouse_pos = list.mouse_pos



	if rl.IsKeyPressed(rl.KeyboardKey.DOWN) {
		cur_element += 1
	}
	if rl.IsKeyPressed(rl.KeyboardKey.UP) {
		cur_element -= 1
	}
	if prev_element != cur_element {
		if cur_element < 0 { cur_element = len(T) -1 }
		if cur_element == len(T) { cur_element = 0 }
		list.active_element = cast(T)cur_element
		if list.tween != nil {
			tween_cancel(list.tween)
		}
		list.tween = tween_to(
			&list.active_marker.y,
			f32(list.active_element) * list.line_size,
			0.25,
			ease.Ease.Quadratic_Out,
		)
	}
	if rl.IsKeyPressed(rl.KeyboardKey.ENTER) || rl.IsKeyPressed(rl.KeyboardKey.SPACE) {
		list.menu_pressed(list.state, list.active_element)
	}
}

menu_list_draw :: proc(list: ^MenuList($T)) {
	if list.background[3] != 0 {
		size := menu_list_get_size(list)
		rl.DrawRectangleV(list.position - {40, 40}, size + {80, 80}, list.background)
	}
	rl.DrawTextEx(Res.Fonts.UI, ">", list.position + list.active_marker + {-30, 0}, 48, 2, rl.WHITE)
	for el, i in list.elements {
		pos := list.position + {0, f32(i) * list.line_size}
		text := el.text 
		if el.type == .BOOL {
			param := transmute(^bool)el.param
			value := param^
			text = rl.TextFormat("%s: %s", el.text, BoolStrings[value])
		}
		rl.DrawTextEx(Res.Fonts.UI, text, pos, list.font_size, 2, rl.WHITE)
	}
}


menu_list_get_size :: proc(list: ^MenuList($T)) -> vec2 {
	size := vec2{}
	for el, i in list.elements {
		line_size := rl.MeasureTextEx(Res.Fonts.UI, el.text, list.font_size, 2)
		if line_size.x > size.x {
			size.x = line_size.x
		}
		size.y += list.line_size
	}
	return size
}
