-- Imports
local util = require("util")
local window = require("window")
local entity = require("entity")
local button = require("button")

function min(a, b)
    if a < b then
        return a
    else
        return b
    end
end

function max(a, b)
    if a > b then
        return a
    else
        return b
    end
end

-- entities that has update method
active_entities = {}

function register(entity)
    util.add_entity(active_entities, entity)
end

function unregister(entity)
    util.del_entity(active_entities, entity)
end

--load room list
local rooms = require("rooms")

current_room = rooms['Alley']
--current_room = rooms['Vivarium']

function set_room_raw(r)
    current_room:onexit()
    current_room = r
    current_room:onenter()
end

function set_room(r)
    assert(rooms[r])
    set_room_raw(rooms[r])
end

screen = {
    x = 0, y = 60,
    width = 320,
    height = 240,
}

screen.mousepressed = window.mousepressed(function (self, x, y, button)
    current_room:mousepressed(x, y, button)
end)

screen.draw = window.draw(function (self)
    current_room:draw()
    window.draw_border(self.width, self.height)
end)

inventory = {
    x = 0, y = 0,
    width = screen.width,
    height = 60,
    selected_item = nil,
    items = {},
    item_idx = 1,
}

local cells = math.floor((inventory.width - 60) / 60)

function inventory:setpos(idx, item)
    local x = 30 + (idx - 1) * 60 + (60 - item.width) / 2
    local y = (60 - item.height) / 2

    item:setpos(x, y)
end

function inventory:move(d)
    self.item_idx = self.item_idx + d

    if self.item_idx < 1 then
        self.item_idx = 1
    elseif self.item_idx + cells - 1 > #self.items then
        self.item_idx = max(1, #self.items - cells + 1)
    end

    for i = 1, min(#self.items, cells) do
        local idx = self.item_idx + i - 1
        self:setpos(i, self.items[idx])
    end
end

function inventory:pickup(item)
    util.add_entity(self.items, item)
    self:move(#self.items)
end

function inventory:drop(item)
    util.del_entity(self.items, item)
    self:move(0)
end

function inventory:use()
    self:drop(self.selected_item)
    self.selected_item = nil
end

local move_left = entity:from{
    x = 0, y = 0,
    width = 20,
    height = 60,
}

move_left.draw = window.draw(function (self)
    love.graphics.polygon('line', 15, 5, 5, 30, 15, 55)
end)

move_left.mousepressed = window.mousepressed(function (self, x, y, button)
    inventory:move(-1)
end)

local move_right = entity:from{
    x = inventory.width - 20,
    y = 0,
    width = 20,
    height = 60,
}

move_right.draw = window.draw(function (self)
    love.graphics.polygon('line', 5, 5, 15, 30, 5, 55)
end)

move_right.mousepressed = window.mousepressed(function (self, x, y, button)
    inventory:move(1)
end)

inventory.mousepressed = window.mousepressed(function (self, x, y, button)
    move_left:mousepressed(x, y, button)
    move_right:mousepressed(x, y, button)

    for i = 1, min(cells, #self.items) do
        local item = self.items[self.item_idx + i - 1]

        if item:mousepressed(x, y, button) then
            return true
        end
    end

    inventory.selected_item = nil
end)

inventory.draw = window.draw(function (self)
    move_left:draw()
    move_right:draw()

    for i = 1, min(#self.items, cells) do
        local idx = i + self.item_idx - 1
        local item = self.items[idx]

        if self.selected_item and self.selected_item == item then
            love.graphics.circle('line', 60*i, 30, 25)
        end

        item:draw()
    end

    window.draw_border(self.width, self.height)
end)

log = {
    x = inventory.width , y = 0,
    width = WIDTH - screen.width,
    height = HEIGHT,
    lines = {},
}

local font = love.graphics.getFont()
local font_height = font:getHeight('L')
local line_limit = log.height / font_height

log.limit = log.width - 10

log.draw = window.draw(function (self)
    local h = 0
    for i, l in ipairs(self.lines) do
        local th = font:getHeight(l)
        love.graphics.printf(l, 5, 5 + h, self.limit)
        h = h + th
    end

    window.draw_border(self.width, self.height)
end)

function log:log(str)
    local rw, wl = font:getWrap(str, self.limit)

    for _, l in ipairs(wl) do
        table.insert(self.lines, l)
    end

    while #self.lines > line_limit do
        table.remove(self.lines, 1)
    end
end

function log:format(...)
    log:log(string.format(...))
end

function log:info(o)
    if o._t == 'item' then
        self:log(string.format("It's %s. %s", o.name, o.description))
    else
        self:log("There's no info for that.")
    end
end

function love.load()
    log:log("Welcome to the garden.")
end

function love.update(dt)
    for i, e in ipairs(active_entities) do
        e:update(dt)
    end
end

mw, mh = 0, 0
if love.system.getOS() == 'android' then
    mw = (love.window.getWidth() - WIDTH) / 2
    mh = (love.window.getHeight() - HEIGHT) / 2
end

function love.mousepressed(x, y, button)
    local x, y = (x - mw) / MULTIPLIER, (y - mh) / MULTIPLIER

    screen:mousepressed(x, y, button)
    inventory:mousepressed(x, y, button)
end

function love.draw()
    love.graphics.translate(mw, mh)
    love.graphics.scale(MULTIPLIER)

    screen:draw()
    inventory:draw()
    log:draw()
end