package main

import "core:fmt"
import "core:path/filepath"
import "core:strings"
import "ntween"
import rl "vendor:raylib"

vec3 :: [3]f32
vec3i :: [3]i32
vec2 :: [2]f32
vec2i :: [2]i32
vec3right := vec3{1, 0, 0}
vec3left := vec3{-1, 0, 0}
vec3up := vec3{0, 1, 0}
vec3down := vec3{0, -1, 0}
vec3forward := vec3{0, 0, 1}
vec3backward := vec3{0, 0, -1}


WSize := [2]f32{}
WSizei := [2]i32{}

WSizeLast := vec2i{}

WindowShouldExit := false

NeedTutorial := true
KeyboardOnly := false


Overlay_Opacity: f32 = 0

Resources :: struct {
	Fonts:  struct {
		UI:    rl.Font,
		Title: rl.Font,
	},
	Models: struct {
		PlayerModel:  rl.Model,
		SnakeHeadTop: rl.Model,
		SnakeHeadJaw: rl.Model,
		SnakeBody:    rl.Model,
		Background:   rl.Model,
	},
	Sfx:    struct {
		Drums:               rl.Sound,
		Lightning:           rl.Sound,
		LightningHit:        rl.Sound,
		Rocket:              rl.Sound,
		PlayerHit:           rl.Sound,
		PlayerSwoosh:        rl.Sound,
		PlayerDead:          rl.Sound,
		SnakeGrowl:          rl.Sound,
		SnakeRoarBlast:      rl.Sound,
		SnakeEarthHit:       rl.Sound,
		SnakeSegmentExplode: rl.Sound,
		SnakeBeam:           rl.Sound,
	},
	Music:  struct {
		First:  rl.Music,
		Second: rl.Music,
	},
}

Res: Resources

res_paths := map[typeid]string {
	rl.Music = "music",
	rl.Sound = "sfx",
	rl.Model = "models",
}

get_path :: proc(name: string, $T: typeid) -> cstring {
	p := filepath.join([]string{"./assets", res_paths[T], name})
	cstr := strings.clone_to_cstring(p)
	return cstr
}

load_model :: proc(name: string) -> rl.Model {
	p := get_path(name, rl.Model)
	mdl := rl.LoadModel(p)
	return mdl
}

load_sfx :: proc(name: string, volume: f32 = 1) -> rl.Sound {
	p := get_path(name, rl.Sound)
	snd := rl.LoadSound(p)
	rl.SetSoundVolume(snd, volume)
	return snd
}

load_music :: proc(name: string, volume: f32 = 1) -> rl.Music {
	p := get_path(name, rl.Music)
	snd := rl.LoadMusicStream(p)
	rl.SetMusicVolume(snd, volume)
	return snd
}

current_music: rl.Music

change_track :: proc(music: rl.Music) {
	rl.StopMusicStream(current_music)
	current_music = music
	rl.PlayMusicStream(current_music)
}

Cursor: rl.Texture
load_resources :: proc() {
	Res.Fonts.Title = rl.LoadFontEx("./assets/fonts/norse.otf", 96 * 2, nil, 2048)
	Res.Fonts.UI = rl.LoadFontEx("./assets/fonts/PTSerif-Regular.ttf", 96, nil, 2048)

	Res.Models = {
		PlayerModel  = load_model("chariot.glb"),
		SnakeHeadTop = load_model("snake_head_top.obj"),
		SnakeHeadJaw = load_model("snake_jaw.obj"),
		SnakeBody    = load_model("snake_body.obj"),
		Background   = load_model("background.obj"),
	}

	Res.Sfx = {
		Drums               = load_sfx("drums.ogg"),
		Lightning           = load_sfx("lightning.ogg", 0.5),
		LightningHit        = load_sfx("lightning-hit.ogg", 0.3),
		Rocket              = load_sfx("rocket.ogg", 0.5),
		PlayerHit           = load_sfx("player-hit.ogg", 0.5),
		PlayerSwoosh        = load_sfx("player-swoosh.ogg"),
		PlayerDead          = load_sfx("player-dead.ogg"),
		SnakeGrowl          = load_sfx("snake-growl.ogg", 0.7),
		SnakeRoarBlast      = load_sfx("snake-roar-blast.ogg", 0.8),
		SnakeBeam           = load_sfx("snake-beam.ogg"),
		SnakeSegmentExplode = load_sfx("snake-segment-explode.ogg", 0.8),
		SnakeEarthHit       = load_sfx("snake-earth-hit.ogg", 0.6),
	}

	Res.Music.First = load_music("alexander-nakarada-mjolnir.mp3", 0.7)
	Res.Music.Second = load_music("alexander-nakarada-the-northern-path.mp3", 0.7)
}

f32_tweens: ntween.Tween_Map(f32)
vec2_tweens: ntween.Tween_Map(vec2)
vec3_tweens: ntween.Tween_Map(vec3)

main :: proc() {
	f32_tweens = ntween.init(f32)
	vec2_tweens = ntween.init(vec2)
	vec3_tweens = ntween.init(vec3)
	//    rl.SetConfigFlags(rl.ConfigFlags{.MSAA_4X_HINT, .FULLSCREEN_MODE, .VSYNC_HINT, .WINDOW_RESIZABLE})
	rl.SetConfigFlags(rl.ConfigFlags{.VSYNC_HINT, .WINDOW_RESIZABLE})

	rl.InitWindow(800, 600, "Ragnarøkkr")
	rl.InitAudioDevice()
	rl.SetWindowMinSize(800, 600)

	rl.HideCursor()
	Cursor = rl.LoadTexture("./assets/gfx/crosshair.png")
	load_resources()

	WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
	WSize = {f32(WSizei.x), f32(WSizei.y)}

	game := game_init()
	stack_push(game)
	menu := menu_init(game)
	stack_push(menu)

	for !WindowShouldExit {
		if rl.IsWindowResized() {
			WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
			WSize = {f32(WSizei.x), f32(WSizei.y)}
		}

		rl.UpdateMusicStream(current_music)

		state := stack_top()
		delta := rl.GetFrameTime()
		timers_process(delta)
		ntween.process(&f32_tweens, delta)
		ntween.process(&vec2_tweens, delta)
		ntween.process(&vec3_tweens, delta)
		state->update(delta)

		rl.BeginDrawing()
		rl.ClearBackground(rl.SKYBLUE)
		state->draw()

		rl.DrawRectangleV({}, WSize, rl.Color{0, 0, 0, u8(Overlay_Opacity * 255)})
		pos := rl.GetMousePosition()
		rl.DrawTextureEx(Cursor, pos - {16, 16} * 3, 0, 3, rl.WHITE)
		rl.EndDrawing()
	}
}

Fullscreen := false

toggle_fullscreen :: proc() {
	monitor := rl.GetCurrentMonitor()
	rl.ToggleBorderlessWindowed()
	WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
	WSize = {f32(WSizei.x), f32(WSizei.y)}
	Fullscreen = !Fullscreen


	//	rl.ToggleFullscreen()
}
