package core

import "core:fmt"

DEFAULT_PROMPT_AGE :: "young adult"
DEFAULT_PROMPT_GENDER :: "person"
DEFAULT_PROMPT_BODY :: "average"
DEFAULT_PROMPT_OUTFIT :: "casual clothing"
DEFAULT_PROMPT_ACCESSORIES :: "no accessories"

build_character_prompt :: proc(c: Character, action, setting, lighting, art_style: string) -> string {
	t := c.prompt_template

	age := t.age
	if len(age) == 0 { age = DEFAULT_PROMPT_AGE }
	gender := t.gender
	if len(gender) == 0 { gender = DEFAULT_PROMPT_GENDER }
	body := t.body_type
	if len(body) == 0 { body = DEFAULT_PROMPT_BODY }
	outfit := t.outfit
	if len(outfit) == 0 { outfit = DEFAULT_PROMPT_OUTFIT }
	accessories := t.accessories
	if len(accessories) == 0 { accessories = DEFAULT_PROMPT_ACCESSORIES }

	return fmt.aprintf(
		"%s style. %s-year-old %s, %s %s hair, %s eyes, %s skin, %s build, wearing %s, %s, %s, %s, %s, %s",
		art_style,
		age,
		gender,
		t.hair_color,
		t.hair_style,
		t.eye_color,
		t.skin_tone,
		body,
		outfit,
		accessories,
		t.distinguishing_features,
		action,
		setting,
		lighting,
	)
}

derive_seed_from_string :: proc(s: string) -> i64 {
	hash: i32 = 0
	for r in s {
		hash = ((hash << 5) - hash) + i32(r)
	}

	res := i64(hash)
	if res < 0 {
		res = -res
	}
	return res % 2147483647
}

hash_char :: proc(hash: ^i32, c: u8) {
	hash^ = ((hash^ << 5) - hash^) + i32(c)
}

hash_string :: proc(hash: ^i32, s: string) {
	for r in s {
		hash^ = ((hash^ << 5) - hash^) + i32(r)
	}
}

hash_decimal_int :: proc(hash: ^i32, n: int) {
	if n == 0 {
		hash_char(hash, '0')
		return
	}

	value := n
	if value < 0 {
		hash_char(hash, '-')
		value = -value
	}

	buf: [20]u8
	i := len(buf)
	for value > 0 {
		i -= 1
		d := value % 10
		buf[i] = u8('0' + d)
		value /= 10
	}

	for ; i < len(buf); i += 1 {
		hash_char(hash, buf[i])
	}
}

generate_panel_seed :: proc(project_id: string, page_number, panel_number: int, panel_id: string) -> i64 {
	hash: i32 = 0
	hash_string(&hash, project_id)
	hash_char(&hash, '_')
	hash_decimal_int(&hash, page_number)
	hash_char(&hash, '_')
	hash_decimal_int(&hash, panel_number)
	hash_char(&hash, '_')
	hash_string(&hash, panel_id)

	res := i64(hash)
	if res < 0 {
		res = -res
	}
	return res % 2147483647
}
