package examples

import "core:os"
import sdl "vendor:sdl3"

import "../../draw"
import "../../vendor/clay"
import cyber "../cybersteel"

// Clay border debug example.
//
// Lays out a grid of bordered Clay elements that exercise every code path in
// `clay_emit_partial_border` and `try_dispatch_clay_rect_border_pair`:
//
//   1. Uniform borders (fast path) — sharp, rounded, and the border-thicker-than-radius
//      edge case (inner corner clamps to 0).
//   2. Background + border combinations — opaque bg + opaque uniform border MERGES into one
//      SDF primitive; translucent border DECLINES the merge to preserve blend fidelity;
//      non-uniform border declines and falls through to the slow path; translucent bg with
//      opaque border still merges (bg alpha doesn't affect merge correctness).
//   3. Single-side borders — top / right / bottom / left individually.
//   4. Two-side borders — parallel pairs (no corners drawn) and adjacent pairs (one corner
//      rounds, others stay square).
//   5. Three-side borders + asymmetric widths.
//   6. Layout correctness — a vertical list with bottom-border separators (each border
//      lives inside its own item, no bleed between siblings) and a row of adjacent fully
//      bordered siblings (no border overlap, each in its own bounds).
clay_borders :: proc() {
	if !sdl.Init({.VIDEO}) do os.exit(1)
	window := sdl.CreateWindow("Clay Borders Debug", 1200, 900, {.HIGH_PIXEL_DENSITY})
	gpu := sdl.CreateGPUDevice(draw.PLATFORM_SHADER_FORMAT, true, nil)
	if !sdl.ClaimWindowForGPUDevice(gpu, window) do os.exit(1)
	if !draw.init(gpu, window) do os.exit(1)
	PLEX_SANS_REGULAR = draw.register_font(cyber.SANS_REGULAR_RAW)

	// Distinct colors so the fill, border, and translucent variants are visually unambiguous.
	BG_PAGE :: draw.Color{25, 25, 30, 255}
	FILL_OPAQUE :: draw.Color{80, 120, 200, 255}
	FILL_TRANSLUCENT :: draw.Color{80, 120, 200, 128}
	BORDER_OPAQUE :: draw.Color{255, 200, 100, 255}
	BORDER_TRANSLUCENT :: draw.Color{255, 200, 100, 128}

	label_config := clay.TextElementConfig {
		fontId    = PLEX_SANS_REGULAR,
		fontSize  = 12,
		textColor = {220, 220, 220, 255},
	}
	header_config := clay.TextElementConfig {
		fontId    = PLEX_SANS_REGULAR,
		fontSize  = 16,
		textColor = {255, 255, 255, 255},
	}
	title_config := clay.TextElementConfig {
		fontId    = PLEX_SANS_REGULAR,
		fontSize  = 22,
		textColor = {255, 255, 255, 255},
	}

	for {
		defer free_all(context.temp_allocator)
		ev: sdl.Event
		for sdl.PollEvent(&ev) {
			if ev.type == .QUIT do return
		}

		base_layer := draw.begin({width = 1200, height = 900})
		clay.SetLayoutDimensions({width = base_layer.bounds.width, height = base_layer.bounds.height})
		clay.BeginLayout()

		if clay.UI(clay.ID("borders_page"))(
		{
			layout = {
				sizing = {clay.SizingGrow({}), clay.SizingGrow({})},
				padding = clay.PaddingAll(20),
				childGap = 14,
				layoutDirection = .TopToBottom,
			},
			backgroundColor = clay_color(BG_PAGE),
		},
		) {
			clay.Text("Clay Borders Debug", title_config)

			//----- Section 1: Uniform borders (fast path) -----------------------------------
			clay.Text("Uniform borders (fast path)", header_config)
			if clay.UI(clay.ID("row_uniform"))(border_row_layout()) {
				border_test_card(
					"1px sharp",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 1, right = 1, top = 1, bottom = 1},
					{},
				)
				border_test_card(
					"2px, radius 8",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 2, right = 2, top = 2, bottom = 2},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"8px, radius 20",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 8, right = 8, top = 8, bottom = 8},
					{topLeft = 20, topRight = 20, bottomRight = 20, bottomLeft = 20},
				)
				border_test_card(
					"10px > radius 5 (inner clamps)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 10, right = 10, top = 10, bottom = 10},
					{topLeft = 5, topRight = 5, bottomRight = 5, bottomLeft = 5},
				)
			}

			//----- Section 2: Background + border (merge optimization) ----------------------
			clay.Text("Background + border (merge optimization)", header_config)
			if clay.UI(clay.ID("row_bg_border"))(border_row_layout()) {
				border_test_card(
					"opaque bg + opaque (MERGES: 1 prim)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 2, right = 2, top = 2, bottom = 2},
					{topLeft = 6, topRight = 6, bottomRight = 6, bottomLeft = 6},
				)
				border_test_card(
					"translucent bg + opaque (MERGES)",
					label_config,
					FILL_TRANSLUCENT,
					BORDER_OPAQUE,
					{left = 3, right = 3, top = 3, bottom = 3},
					{topLeft = 6, topRight = 6, bottomRight = 6, bottomLeft = 6},
				)
				border_test_card(
					"opaque bg + translucent (NO merge)",
					label_config,
					FILL_OPAQUE,
					BORDER_TRANSLUCENT,
					{left = 4, right = 4, top = 4, bottom = 4},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"opaque bg + non-uniform (NO merge)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 1, right = 4, top = 2, bottom = 3},
					{topLeft = 6, topRight = 6, bottomRight = 6, bottomLeft = 6},
				)
			}

			//----- Section 3: Single side borders -------------------------------------------
			clay.Text("Single side", header_config)
			if clay.UI(clay.ID("row_single_side"))(border_row_layout()) {
				border_test_card("top only (4px)", label_config, FILL_OPAQUE, BORDER_OPAQUE, {top = 4}, {})
				border_test_card("right only (4px)", label_config, FILL_OPAQUE, BORDER_OPAQUE, {right = 4}, {})
				border_test_card(
					"bottom only (4px, divider)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{bottom = 4},
					{},
				)
				border_test_card("left only (4px)", label_config, FILL_OPAQUE, BORDER_OPAQUE, {left = 4}, {})
			}

			//----- Section 4: Two side borders ----------------------------------------------
			clay.Text("Two sides", header_config)
			if clay.UI(clay.ID("row_two_sides"))(border_row_layout()) {
				border_test_card(
					"T+B parallel (no corners)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 3, bottom = 3},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"L+R parallel (no corners)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{left = 3, right = 3},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"T+L adjacent (TL rounds)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 3, left = 3},
					{topLeft = 12, topRight = 12, bottomRight = 12, bottomLeft = 12},
				)
				border_test_card(
					"B+R adjacent (BR rounds)",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{bottom = 3, right = 3},
					{topLeft = 12, topRight = 12, bottomRight = 12, bottomLeft = 12},
				)
			}

			//----- Section 5: Three sides + asymmetric widths -------------------------------
			clay.Text("Three sides + asymmetric widths", header_config)
			if clay.UI(clay.ID("row_advanced"))(border_row_layout()) {
				border_test_card(
					"T+R+B (no L), rounded",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 3, right = 3, bottom = 3},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"T+L+R (no B), rounded",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 3, left = 3, right = 3},
					{topLeft = 8, topRight = 8, bottomRight = 8, bottomLeft = 8},
				)
				border_test_card(
					"asym 1/2/3/4 T/R/B/L",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 1, right = 2, bottom = 3, left = 4},
					{},
				)
				border_test_card(
					"asym + rounded",
					label_config,
					FILL_OPAQUE,
					BORDER_OPAQUE,
					{top = 2, right = 4, bottom = 2, left = 4},
					{topLeft = 10, topRight = 10, bottomRight = 10, bottomLeft = 10},
				)
			}

			//----- Section 6: Layout correctness --------------------------------------------
			clay.Text("Layout correctness", header_config)
			if clay.UI(clay.ID("row_correctness"))(
			{layout = {sizing = {clay.SizingGrow({}), clay.SizingFit({})}, childGap = 14}},
			) {
				// 6a: vertical list with per-item bottom-border separator. Each item's
				// border draws INSIDE its own bounds, so adjacent items don't bleed.
				if clay.UI(clay.ID("list_demo"))(
				{
					layout = {
						sizing = {clay.SizingFixed(300), clay.SizingFit({})},
						padding = clay.PaddingAll(6),
						childGap = 6,
						layoutDirection = .TopToBottom,
					},
				},
				) {
					clay.Text("List with bottom-border separators", label_config)
					if clay.UI(clay.ID("list_outer"))(
					{
						layout = {sizing = {clay.SizingGrow({}), clay.SizingFit({})}, layoutDirection = .TopToBottom},
						backgroundColor = clay_color(FILL_OPAQUE),
					},
					) {
						for index in 0 ..< 5 {
							if clay.UI(clay.ID("list_item", u32(index)))(
							{
								layout = {sizing = {clay.SizingGrow({}), clay.SizingFixed(28)}, padding = clay.PaddingAll(6)},
								border = {color = clay_color(BORDER_OPAQUE), width = {bottom = 1}},
							},
							) {
								clay.Text("Item", label_config)
							}
						}
					}
				}

				// 6b: row of adjacent fully bordered siblings. With borders rendered
				// INSIDE each element's bounds, the boundary between two siblings shows
				// the natural 2*width sum (no overlap, no bleed).
				if clay.UI(clay.ID("adj_demo"))(
				{
					layout = {
						sizing = {clay.SizingFixed(380), clay.SizingFit({})},
						padding = clay.PaddingAll(6),
						childGap = 6,
						layoutDirection = .TopToBottom,
					},
				},
				) {
					clay.Text("Adjacent bordered siblings (no gap)", label_config)
					if clay.UI(clay.ID("adj_row"))({layout = {sizing = {clay.SizingGrow({}), clay.SizingFit({})}}}) {
						for index in 0 ..< 4 {
							if clay.UI(clay.ID("adj_item", u32(index)))(
							{
								layout = {sizing = {clay.SizingFixed(80), clay.SizingFixed(60)}},
								backgroundColor = clay_color(FILL_OPAQUE),
								border = {color = clay_color(BORDER_OPAQUE), width = {left = 2, right = 2, top = 2, bottom = 2}},
							},
							) {}
						}
					}
				}
			}
		}

		clay_batch := draw.ClayBatch {
			bounds = base_layer.bounds,
			cmds   = clay.EndLayout(0),
		}
		draw.prepare_clay_batch(base_layer, &clay_batch)
		draw.end(gpu, window)
	}
}

// Helper: convert a draw.Color (RGBA u8) to clay.Color (RGBA float in 0-255 range).
clay_color :: proc(c: draw.Color) -> clay.Color {
	return clay.Color{f32(c[0]), f32(c[1]), f32(c[2]), f32(c[3])}
}

// Helper: shared row container declaration for the test sections.
border_row_layout :: proc() -> clay.ElementDeclaration {
	return clay.ElementDeclaration{layout = {sizing = {clay.SizingGrow({}), clay.SizingFit({})}, childGap = 12}}
}

// One labeled test card: a fixed-width column with a caption above and a sample bordered
// rectangle below. Uses `clay.ID_LOCAL` for the inner element so each card gets a unique
// child ID without the caller passing one explicitly.
border_test_card :: proc(
	label: string,
	label_config: clay.TextElementConfig,
	fill_color: draw.Color,
	border_color: draw.Color,
	border_width: clay.BorderWidth,
	corner_radii: clay.CornerRadius,
) {
	if clay.UI(clay.ID(label))(
	{
		layout = {
			sizing = {clay.SizingFixed(275), clay.SizingFit({})},
			padding = clay.PaddingAll(4),
			childGap = 6,
			layoutDirection = .TopToBottom,
		},
	},
	) {
		clay.Text(label, label_config)
		if clay.UI(clay.ID_LOCAL("test_inner"))(
		{
			layout = {sizing = {clay.SizingGrow({}), clay.SizingFixed(64)}},
			backgroundColor = clay_color(fill_color),
			border = clay.BorderElementConfig{color = clay_color(border_color), width = border_width},
			cornerRadius = corner_radii,
		},
		) {}
	}
}
