package main

import ecs "deps/secs"
import rl "vendor:raylib"

import "core:fmt"

MAX_BUILDINGS :: 100
screenWidth :: 800
screenHeight :: 450

GameStateStartup :: struct {}
GameStateStartScreen :: struct {}
GameStateLoop :: struct {}
GameStateExitRequested :: struct {}

GameState :: union {
	GameStateStartup,
	GameStateStartScreen,
	GameStateLoop,
	GameStateExitRequested,
}

generate_buildings :: proc(
) -> (
	buildings: [MAX_BUILDINGS]rl.Rectangle,
	buildColors: [MAX_BUILDINGS]rl.Color,
) {
	spacing: i32 = 0
	for i in 0 ..< MAX_BUILDINGS {
		buildings[i].width = f32(rl.GetRandomValue(50, 200))
		buildings[i].height = f32(rl.GetRandomValue(100, 800))
		buildings[i].y = screenHeight - 130.0 - buildings[i].height
		buildings[i].x = f32(-6000.0 + spacing)

		spacing += i32(buildings[i].width)

		buildColors[i] = rl.Color(
			 {
				u8(rl.GetRandomValue(200, 240)),
				u8(rl.GetRandomValue(200, 240)),
				u8(rl.GetRandomValue(200, 240)),
				255,
			},
		)
	}
	return buildings, buildColors
}

Drawable :: union {
	rl.Rectangle,
}

handle_input :: proc(world: ^ecs.World) {
	ecs.Work(world, proc(e: ecs.Entity, p: ^Position, d: ^Player) {
			if rl.IsKeyDown(rl.KeyboardKey.A) do p.x -= 2
			if rl.IsKeyDown(rl.KeyboardKey.D) do p.x += 2
			if rl.IsKeyDown(rl.KeyboardKey.W) do p.y -= 2
			if rl.IsKeyDown(rl.KeyboardKey.S) do p.y += 2
		})
}

Player :: struct {}
Position :: struct {
	x: f32,
	y: f32,
}

CameraTarget :: struct {}

camera: rl.Camera2D
main :: proc() {
	rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera")
	exitWindow := false // Flag to set window to exit

	world := ecs.NewWorld()
	e := ecs.CreateEntity(world)
	ecs.AddComponents(
		world,
		e,
		Player{},
		Position{400, 280},
		Drawable(rl.Rectangle{0, 0, 40, 40}),
		CameraTarget{},
	)

	buildings, buildColors := generate_buildings()

	game_state: GameState = GameStateStartup{}
	last_state: GameState = nil

	camera.offset = rl.Vector2({screenWidth / 2.0, screenHeight / 2.0})
	camera.rotation = 0.0
	camera.zoom = 1.0

	rl.SetTargetFPS(60)

	for !exitWindow {
		switch s in game_state {
		case GameStateStartup:
			game_state = GameStateStartScreen{}
		case GameStateStartScreen:
			game_state = GameStateLoop{}
		case GameStateLoop:
			handle_input(world)

			ecs.Work(world, proc(done: ^bool, e: ecs.Entity, p: ^Position, d: ^CameraTarget) {
				camera.target = rl.Vector2({p.x + 20, p.y + 20})
				done^ = true
			})

			camera.zoom += f32(rl.GetMouseWheelMove() * 0.05)

			if camera.zoom > 3.0 do camera.zoom = 3.0
			else if camera.zoom < 0.1 do camera.zoom = 0.1

			if rl.IsKeyPressed(rl.KeyboardKey.R) {
				camera.zoom = 1.0
				camera.rotation = 0.0
			}

			if (rl.WindowShouldClose() || rl.IsKeyPressed(rl.KeyboardKey.ESCAPE)) do game_state = GameStateExitRequested{}
		case GameStateExitRequested:
			// A request for close window has been issued, we can save data before closing
			// or just show a message asking for confirmation

			if (rl.IsKeyPressed(rl.KeyboardKey.Y) || rl.IsKeyPressed(rl.KeyboardKey.Z)) do exitWindow = true
			else if (rl.IsKeyPressed(rl.KeyboardKey.N)) do game_state = last_state
		}


		rl.BeginDrawing()
		rl.ClearBackground(rl.RAYWHITE)

		rl.BeginMode2D(camera)
		rl.DrawRectangle(-6000, 320, 13000, 8000, rl.DARKGRAY)

		for i in 0 ..< MAX_BUILDINGS do rl.DrawRectangleRec(buildings[i], buildColors[i])

		ecs.Work(world, proc(e: ecs.Entity, p: ^Position, d: ^Drawable) {
			switch d in d {
			case rl.Rectangle:
				rl.DrawRectangleRec(rl.Rectangle{d.x + p.x, d.y + p.y, d.width, d.height}, rl.RED)
			}
		})

		rl.DrawLine(
			i32(camera.target.x),
			-screenHeight * 10,
			i32(camera.target.x),
			screenHeight * 10,
			rl.GREEN,
		)
		rl.DrawLine(
			-screenWidth * 10,
			i32(camera.target.y),
			screenWidth * 10,
			i32(camera.target.y),
			rl.GREEN,
		)
		rl.EndMode2D()

		rl.DrawText("SCREEN AREA", 640, 10, 20, rl.RED)

		rl.DrawRectangle(0, 0, screenWidth, 5, rl.RED)
		rl.DrawRectangle(0, 5, 5, screenHeight - 10, rl.RED)
		rl.DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, rl.RED)
		rl.DrawRectangle(0, screenHeight - 5, screenWidth, 5, rl.RED)

		rl.DrawRectangle(10, 10, 250, 80, rl.Fade(rl.SKYBLUE, 0.5))
		rl.DrawRectangleLines(10, 10, 250, 80, rl.BLUE)

		rl.DrawText("Free 2d camera controls:", 20, 20, 10, rl.BLACK)
		rl.DrawText("- WASD to move", 40, 40, 10, rl.DARKGRAY)
		rl.DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, rl.DARKGRAY)


		#partial switch _ in game_state {
		case GameStateExitRequested:
			rl.DrawRectangle(0, 100, screenWidth, 200, rl.BLACK)
			rl.DrawText("Are you sure you want to exit program? [Y/N]", 40, 180, 30, rl.WHITE)
		}

		rl.EndDrawing()
	}

	rl.CloseWindow()
}