package main

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

vec3 :: [3]f32
vec2 :: [2]f32
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{}

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


load_sfx :: proc(name: string, volume: f32 = 1) -> rl.Sound {
    p := filepath.join([]string{"./assets/sfx/", name})
    cstr := strings.clone_to_cstring(p)
    snd := rl.LoadSound(cstr)
    rl.SetSoundVolume(snd, volume)
    return snd
}

load_music :: proc(name: string, volume: f32 = 1) -> rl.Music {
    p := filepath.join([]string{"./assets/music/", name})
    cstr := strings.clone_to_cstring(p)
    snd := rl.LoadMusicStream(cstr)
    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 = rl.LoadModel("./assets/models/chariot.glb")
    Res.Models.SnakeHeadTop = rl.LoadModel("./assets/models/snake_head_top.obj")
    Res.Models.SnakeHeadJaw = rl.LoadModel("./assets/models/snake_jaw.obj")
    Res.Models.SnakeBody = rl.LoadModel("./assets/models/snake_body.obj")

    Res.Sfx.Drums = load_sfx("drums.ogg")
    Res.Sfx.Lightning = load_sfx("lightning.ogg", 0.5)
    Res.Sfx.LightningHit = load_sfx("lightning-hit.ogg", 0.3)
    Res.Sfx.Rocket = load_sfx("rocket.ogg", 0.5)
    Res.Sfx.PlayerHit = load_sfx("player-hit.ogg", 0.5)
    Res.Sfx.PlayerSwoosh = load_sfx("player-swoosh.ogg")
    Res.Sfx.PlayerDead = load_sfx("player-dead.ogg")
    Res.Sfx.SnakeGrowl = load_sfx("snake-growl.ogg", 0.7)
    Res.Sfx.SnakeRoarBlast = load_sfx("snake-roar-blast.ogg", 0.8)
    Res.Sfx.SnakeBeam = load_sfx("snake-beam.ogg")
    Res.Sfx.SnakeSegmentExplode = load_sfx("snake-segment-explode.ogg", 0.8)
    Res.Sfx.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)
}

Fullscreen := true

main :: proc() {
    rl.SetConfigFlags(rl.ConfigFlags{.MSAA_4X_HINT, .FULLSCREEN_MODE, .VSYNC_HINT, .WINDOW_RESIZABLE})
    rl.SetWindowMinSize(800, 480)
    
    rl.InitWindow(0, 0, "Ragnarøkkr")
    rl.InitAudioDevice()

    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)
        tweens_process(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()
    }
}
