package core

Page_Size :: struct {
	name: string,
	width: int,
	height: int,
	dpi: int,
}

get_page_size :: proc(name: Page_Size_Name) -> Page_Size {
	switch name {
	case .A4:
		return Page_Size{"A4", 2480, 3508, 300}
	case .Letter:
		return Page_Size{"US Letter", 2550, 3300, 300}
	case .Manga:
		return Page_Size{"B5 Manga", 2158, 3035, 300}
	case .Webtoon:
		return Page_Size{"Webtoon", 800, 1280, 72}
	case .Square:
		return Page_Size{"Square", 1080, 1080, 72}
	}
	return Page_Size{"A4", 2480, 3508, 300}
}

GRID_2X2_CELLS : [4]Layout_Cell = [4]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.47, h = 0.47},
	{x = 0.51, y = 0.02, w = 0.47, h = 0.47},
	{x = 0.02, y = 0.51, w = 0.47, h = 0.47},
	{x = 0.51, y = 0.51, w = 0.47, h = 0.47},
}

MANGA_3_TIER_CELLS : [6]Layout_Cell = [6]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.3, h = 0.3},
	{x = 0.35, y = 0.02, w = 0.3, h = 0.3},
	{x = 0.68, y = 0.02, w = 0.3, h = 0.3},
	{x = 0.02, y = 0.35, w = 0.47, h = 0.3},
	{x = 0.51, y = 0.35, w = 0.47, h = 0.3},
	{x = 0.02, y = 0.68, w = 0.96, h = 0.3},
}

ACTION_DYNAMIC_CELLS : [5]Layout_Cell = [5]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.6, h = 0.35},
	{x = 0.64, y = 0.02, w = 0.34, h = 0.35},
	{x = 0.02, y = 0.4, w = 0.34, h = 0.28},
	{x = 0.38, y = 0.4, w = 0.6, h = 0.28},
	{x = 0.02, y = 0.71, w = 0.96, h = 0.27},
}

SPLASH_CELLS : [1]Layout_Cell = [1]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.96, h = 0.96},
}

WEBTOON_CELLS : [3]Layout_Cell = [3]Layout_Cell{
	{x = 0.02, y = 0.01, w = 0.96, h = 0.32},
	{x = 0.02, y = 0.34, w = 0.96, h = 0.32},
	{x = 0.02, y = 0.67, w = 0.96, h = 0.32},
}

WESTERN_3X3_CELLS : [9]Layout_Cell = [9]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.3, h = 0.29},
	{x = 0.35, y = 0.02, w = 0.3, h = 0.29},
	{x = 0.68, y = 0.02, w = 0.3, h = 0.29},
	{x = 0.02, y = 0.35, w = 0.3, h = 0.29},
	{x = 0.35, y = 0.35, w = 0.3, h = 0.29},
	{x = 0.68, y = 0.35, w = 0.3, h = 0.29},
	{x = 0.02, y = 0.68, w = 0.3, h = 0.29},
	{x = 0.35, y = 0.68, w = 0.3, h = 0.29},
	{x = 0.68, y = 0.68, w = 0.3, h = 0.29},
}

DIALOGUE_HEAVY_CELLS : [8]Layout_Cell = [8]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.47, h = 0.22},
	{x = 0.51, y = 0.02, w = 0.47, h = 0.22},
	{x = 0.02, y = 0.26, w = 0.47, h = 0.22},
	{x = 0.51, y = 0.26, w = 0.47, h = 0.22},
	{x = 0.02, y = 0.5, w = 0.47, h = 0.22},
	{x = 0.51, y = 0.5, w = 0.47, h = 0.22},
	{x = 0.02, y = 0.74, w = 0.47, h = 0.22},
	{x = 0.51, y = 0.74, w = 0.47, h = 0.22},
}

CINEMATIC_CELLS : [4]Layout_Cell = [4]Layout_Cell{
	{x = 0.02, y = 0.02, w = 0.96, h = 0.22},
	{x = 0.02, y = 0.26, w = 0.96, h = 0.22},
	{x = 0.02, y = 0.5, w = 0.96, h = 0.22},
	{x = 0.02, y = 0.74, w = 0.96, h = 0.22},
}

pattern_max_panels :: proc(id: string) -> int {
	switch id {
	case "grid-2x2":
		return 4
	case "manga-3-tier":
		return 6
	case "action-dynamic":
		return 5
	case "splash-page":
		return 1
	case "webtoon-scroll":
		return 3
	case "western-3x3":
		return 9
	case "dialogue-heavy":
		return 8
	case "cinematic-widescreen":
		return 4
	}
	return 4
}

pattern_matches_genre :: proc(id: string, genre: string) -> bool {
	if len(genre) == 0 {
		return true
	}

	switch id {
	case "grid-2x2":
		return true
	case "manga-3-tier":
		return genre == "manga" || genre == "action"
	case "action-dynamic":
		return genre == "action" || genre == "superhero"
	case "splash-page":
		return true
	case "webtoon-scroll":
		return genre == "webtoon" || genre == "slice-of-life"
	case "western-3x3":
		return genre == "western-comic"
	case "dialogue-heavy":
		return genre == "drama" || genre == "slice-of-life" || genre == "romance"
	case "cinematic-widescreen":
		return genre == "action" || genre == "scifi" || genre == "noir"
	}

	return true
}

get_layout_pattern_by_id :: proc(id: string) -> Layout_Pattern {
	switch id {
	case "grid-2x2":
		return Layout_Pattern{id = id, name = "Classic Grid", description = "2x2 equal panels", genres = nil, max_panels = 4, cells = GRID_2X2_CELLS[:]}
	case "manga-3-tier":
		return Layout_Pattern{id = id, name = "Manga 3-Tier", description = "Three horizontal tiers", genres = nil, max_panels = 6, cells = MANGA_3_TIER_CELLS[:]}
	case "action-dynamic":
		return Layout_Pattern{id = id, name = "Action Dynamic", description = "Varied action panels", genres = nil, max_panels = 5, cells = ACTION_DYNAMIC_CELLS[:]}
	case "splash-page":
		return Layout_Pattern{id = id, name = "Splash Page", description = "Single full-page panel", genres = nil, max_panels = 1, cells = SPLASH_CELLS[:]}
	case "webtoon-scroll":
		return Layout_Pattern{id = id, name = "Webtoon Scroll", description = "Vertical mobile panels", genres = nil, max_panels = 3, cells = WEBTOON_CELLS[:]}
	case "western-3x3":
		return Layout_Pattern{id = id, name = "Western 3x3", description = "Classic 3x3", genres = nil, max_panels = 9, cells = WESTERN_3X3_CELLS[:]}
	case "dialogue-heavy":
		return Layout_Pattern{id = id, name = "Dialogue Heavy", description = "Conversation-focused", genres = nil, max_panels = 8, cells = DIALOGUE_HEAVY_CELLS[:]}
	case "cinematic-widescreen":
		return Layout_Pattern{id = id, name = "Cinematic Widescreen", description = "Wide cinematic panels", genres = nil, max_panels = 4, cells = CINEMATIC_CELLS[:]}
	}

	return Layout_Pattern{id = "grid-2x2", name = "Classic Grid", description = "2x2 equal panels", genres = nil, max_panels = 4, cells = GRID_2X2_CELLS[:]}
}

select_best_pattern :: proc(panel_count: int, genre: string, preference: string) -> Layout_Pattern {
	pattern_ids := [8]string{
		"grid-2x2",
		"manga-3-tier",
		"action-dynamic",
		"splash-page",
		"webtoon-scroll",
		"western-3x3",
		"dialogue-heavy",
		"cinematic-widescreen",
	}

	if len(preference) > 0 {
		if pattern_max_panels(preference) >= panel_count {
			return get_layout_pattern_by_id(preference)
		}
	}

	best_genre_id := ""
	best_genre_max := 1 << 30
	for id in pattern_ids {
		max_panels := pattern_max_panels(id)
		if max_panels < panel_count {
			continue
		}
		if !pattern_matches_genre(id, genre) {
			continue
		}
		if max_panels < best_genre_max {
			best_genre_max = max_panels
			best_genre_id = id
		}
	}
	if len(best_genre_id) > 0 {
		return get_layout_pattern_by_id(best_genre_id)
	}

	best_id := ""
	best_max := 1 << 30
	for id in pattern_ids {
		max_panels := pattern_max_panels(id)
		if max_panels < panel_count {
			continue
		}
		if max_panels < best_max {
			best_max = max_panels
			best_id = id
		}
	}
	if len(best_id) > 0 {
		return get_layout_pattern_by_id(best_id)
	}

	return get_layout_pattern_by_id("grid-2x2")
}

auto_layout_pages :: proc(panels: []Panel, page_size: Page_Size_Name, genre: string, pattern_preference: string) -> []Page_Layout {
	if len(panels) == 0 {
		return nil
	}

	size := get_page_size(page_size)
	pages: [dynamic]Page_Layout
	panel_index := 0
	page_number := 1

	for panel_index < len(panels) {
		remaining := len(panels) - panel_index
		pattern := select_best_pattern(remaining, genre, pattern_preference)
		take := pattern.max_panels
		if take > remaining {
			take = remaining
		}

		layout_panels: [dynamic]Page_Layout_Panel
		for i in 0..<take {
			p := panels[panel_index+i]
			cell_index := i
			if cell_index >= len(pattern.cells) {
				cell_index = len(pattern.cells) - 1
			}

			append(&layout_panels, Page_Layout_Panel{
				panel_id = p.panel_id,
				panel_number = p.panel_number,
				layout_cell = pattern.cells[cell_index],
			})
		}

		append(&pages, Page_Layout{
			page_number = page_number,
			pattern_id = pattern.id,
			panels = layout_panels[:],
			width = size.width,
			height = size.height,
		})

		panel_index += take
		page_number += 1
	}

	return pages[:]
}
