------------------------------------------------------------------------------
-- Imports
------------------------------------------------------------------------------

local love = require 'love'
local game_states = require 'src.states'
local settings = require 'src.utils.settings'
local Fader = require 'src.utils.fader'


------------------------------------------------------------------------------
-- Variables
------------------------------------------------------------------------------

Current_state = 1
Fade = Fader()
Change_state = false
Debug = false


------------------------------------------------------------------------------
-- Helper methods
------------------------------------------------------------------------------

local function parse_args(args)
    for _, v in pairs(args) do
        -- Enable debug mode.
        if v == '-debug' then Debug = true end
    end
end


------------------------------------------------------------------------------
-- Game methods
------------------------------------------------------------------------------

function love.load(args)
    parse_args(args)

    -- Obtain the settigns for the game.
    settings:load_settings()

    -- Load the assets of the intro game state.
    game_states[Current_state]:load()

    -- Call a fade in after the intro assets are loaded.
    Fade:fade_in()
end


function love.update(dt)
    local new_state = game_states[Current_state]:update(dt)

    -- If the game state changed then trigger a fade out.
    if new_state ~= Current_state and Fade.done then
        Fade:fade_out()
        Change_state = true
    end

    Fade:update(dt)

    -- Update the game state.
    if game_states[new_state] == nil then
        -- If the new state doesn't exist then wait for the fade out to end and quit.
        if Fade.done then
            game_states[Current_state]:unload(dt)
            love.event.quit()

            -- Save the settings before quitting just in case.
            settings:load_settings()
        end
    else
        -- If the new state exists then unload it's data and set the new state.
        if Change_state and Fade.done then
            game_states[Current_state]:unload(dt)
            Current_state = new_state
            game_states[Current_state]:load()
            Change_state = false
            Fade:fade_in()
        end
    end
end


function love.draw()
    love.graphics.clear()
    game_states[Current_state]:draw()
    Fade:draw()

    if Debug then
        love.graphics.setColor(0, 0, 0)
        love.graphics.rectangle('fill', 0, 0, 140, 40)
        love.graphics.setColor()
        love.graphics.print(string.format('OS: %s', love.system.getOS()), 5, 5)
        love.graphics.print(string.format('Love version: %s', love.getVersion()), 5, 15)
        love.graphics.print(string.format('Memory usage: %s KiB', love.system.getMemUsage()), 5, 25)
    end
end


function love.keypressed(key, code, isrepeat)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:keypressed(key, code, isrepeat)
    end
end


function love.keyreleased(key, code)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:keyreleased(key, code)
    end
end


function love.textinput(text)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:textinput(text)
    end
end


function love.mousemoved(x, y, dx, dy)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:mousemoved(x, y, dx, dy)
    end
end


function love.mousepressed(x, y, btn)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:mousemoved(x, y, btn)
    end
end


function love.mousereleased(x, y, btn)
    -- Send events to the active game state if there is no fade active.
    if Fade.done then
        game_states[Current_state]:mousereleased(x, y, btn)
    end
end
