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

local love       = require 'love'
local make_class = require 'src.utils.classes'
local Drawable   = require 'src.graphics.drawable'
local Sprite     = require 'src.graphics.sprite'
local Font       = require 'src.ui.font'

------------------------------------------------------------------------------
-- Class definitions
------------------------------------------------------------------------------

local AssetManager = make_class(Drawable)
local Asset        = require 'src.utils.asset'


------------------------------------------------------------------------------
-- Helper functions
------------------------------------------------------------------------------

local function _load(manager, owner)
    if manager.assets[owner] ~= nil then
        for k, _ in pairs(manager.assets[owner]) do
            if k.is_a ~= nil and k.is_a[Asset] then
                k:load()
            end
            coroutine.yield(false)
        end
    end

    return true
end


------------------------------------------------------------------------------
-- Class methods
------------------------------------------------------------------------------

function AssetManager:_init()
    Drawable._init(self)
    self.assets = {}
    self.bckg   = Sprite('imgs/floppy.png')
    self.font   = Font('fonts/BBrick.ttf', 40)
    self.co     = nil

    self.bckg:load()
    self.font:load()
end


function AssetManager:unload(owner)
    -- If the owner is known...
    if self.assets[owner] ~= nil then
        -- Iterate over it's asset set and unload everything.
        for k, _ in pairs(self.assets[owner]) do
            if k.is_a ~= nil and k.is_a[Asset] then
                k:unload()
            end
        end
    end
end


function AssetManager:update(owner)
    if self.assets[owner] ~= nil then
        if self.assets[owner].co == nil then
            self.assets[owner].co = coroutine.create(_load)
        end

        local errorfree, retval = coroutine.resume(self.assets[owner].co, self, owner)

        if errorfree then
            self.assets[owner].done = retval

            if retval then
                self.assets[owner].co   = nil
            end
        else
            error(retval)
        end
    end
end


function AssetManager:draw()
    self.bckg:draw()

    love.graphics.setColor(195, 147, 123)
    self.font:set()
    love.graphics.print('Loading...', 5, 150)
    self.font:unset()
    love.graphics.setColor()
end


function AssetManager:register(owner, asset)
    -- If the owner is new, then create an asset set for it.
    if self.assets[owner] == nil then
        self.assets[owner] = {
            done = false,
            co   = nil,
        }
    end

    -- Store the asset in the set.
    self.assets[owner][asset] = true
end


function AssetManager:remove(owner, asset)
    -- If the owner is new, then create an asset set for it.
    if self.assets[owner] ~= nil then
        -- Unload the asset just in case.
        if self.assets[owner][asset] ~= nil then
            self.assets[owner][asset]:unload()
        end

        -- Then remove it from the set.
        self.assets[owner][asset] = nil
    end
end


function AssetManager:done(owner)
    return self.assets[owner] ~= nil and self.assets[owner].done
end


------------------------------------------------------------------------------
-- Module return
------------------------------------------------------------------------------

return AssetManager()
