package main

clamp :: proc(a, min, max: int) -> int {
	t := (a < min ? min : a)
	return t > max ? max : t
}

draw_line :: proc(bitmap: ^Bitmap, x1, y1, x2, y2: int, color: u32) {
	xx1 := clamp(x1, 0, bitmap.width - 1)
	yy1 := clamp(y1, 0, bitmap.height - 1)
	xx2 := clamp(x2, 0, bitmap.width - 1)
	yy2 := clamp(y2, 0, bitmap.height - 1)

	sx := (xx1 < xx2 ? 1 : -1)
	sy := (yy1 < yy2 ? 1 : -1)
	dx := abs(xx2 - xx1)
	dy := -abs(yy2 - yy1)

	x := xx1
	y := yy1
	e := dx + dy
	buffer := transmute([]u32)(bitmap.buffer)
	for {
		i := (y * bitmap.width) + x
		buffer[i] = color
		if x == xx2 && y == yy2 {
			break
		}

		e2 := e * 2
		if e2 >= dy {
			e += dy
			x += sx
		}
		if e2 <= dx {
			e += dx
			y += sy
		}
	}
}

draw_rect :: proc(bitmap: ^Bitmap, x1, y1, x2, y2: int, color: u32) {
	xx1 := clamp(x1, 0, bitmap.width - 1)
	yy1 := clamp(y1, 0, bitmap.height - 1)
	xx2 := clamp(x2, 0, bitmap.width - 1)
	yy2 := clamp(y2, 0, bitmap.height - 1)

	buffer := transmute([]u32)(bitmap.buffer)
	for y in yy1 ..= yy2 {
		i := y * bitmap.width
		buffer[i + xx1] = color
		buffer[i + xx2] = color
	}
	iy1 := yy1 * bitmap.width
	iy2 := yy2 * bitmap.width
	for x in xx1 ..= xx2 {
		buffer[iy1 + x] = color
		buffer[iy2 + x] = color
	}
}

draw_rect_filled :: proc(bitmap: ^Bitmap, x1, y1, x2, y2: int, stroke_color, fill_color: u32) {
	xx1 := clamp(x1, 0, bitmap.width - 1)
	yy1 := clamp(y1, 0, bitmap.height - 1)
	xx2 := clamp(x2, 0, bitmap.width - 1)
	yy2 := clamp(y2, 0, bitmap.height - 1)

	buffer := transmute([]u32)(bitmap.buffer)
	for y in yy1 ..= yy2 {
		i := y * bitmap.width
		buffer[i + xx1] = stroke_color
		draw_line(bitmap, xx1 + 1, y, xx2 - 1, y, fill_color)
		buffer[i + xx2] = stroke_color
	}
	iy1 := yy1 * bitmap.width
	iy2 := yy2 * bitmap.width
	for x in xx1 ..= xx2 {
		buffer[iy1 + x] = stroke_color
		buffer[iy2 + x] = stroke_color
	}
}