local easing = require "lib.utils.easing"
local AnimationNode = require "lib.animation_node"
local Element = require "lib.simple_ui.element"
local Rect = require "lib.simple_ui.rect"
local SkillRow = require "lib.simple_ui.level.skill_row"
local Bars = require "lib.simple_ui.level.bottom_bars"


--- @class CharacterPanel : UIElement
--- @field animationNode AnimationNode
--- @field state "show" | "idle" | "hide"
--- @field skillRow SkillRow
--- @field bars BottomBars
local characterPanel = setmetatable({}, Element)
characterPanel.__index = characterPanel

function characterPanel.new(characterId)
    local t = {}
    t.state = "show"
    t.skillRow = SkillRow(characterId)
    t.bars = Bars(characterId)
    return setmetatable(t, characterPanel)
end

function characterPanel:show()
    AnimationNode {
        function(animationNode)
            if self.animationNode then self.animationNode:finish() end
            self.animationNode = animationNode
            self.state = "show"
        end,
        duration = 300,
        onEnd = function()
            self.state = "idle"
        end,
        easing = easing.easeOutCubic
    }:run()
end

function characterPanel:hide()
    AnimationNode {
        function(animationNode)
            if self.animationNode then self.animationNode:finish() end
            self.animationNode = animationNode
            self.state = "hide"
        end,
        duration = 300,
        easing = easing.easeOutCubic
    }:run()
end

--- @type love.Canvas
local characterPanelCanvas;

function characterPanel:update(dt)
    if self.animationNode then self.animationNode:update(dt) end
    self.skillRow:update(dt)
    self.bars.bounds = Rect {
        width = self.skillRow.bounds.width,
        x = self.skillRow.bounds.x,
        y = self.skillRow.bounds.y
    }
    self.bars:update(dt)

    self.bounds = Rect {
        x = self.bars.bounds.x,
        y = self.bars.bounds.y,
        width = self.bars.bounds.width,
        height = self.bars.bounds.height + self.skillRow.bounds.height
    }

    if not characterPanelCanvas then
        characterPanelCanvas = love.graphics.newCanvas(self.bounds.width, self.bounds.height)
    end

    --- анимация появления
    local alpha = 1
    if self.state == "show" then
        alpha = self.animationNode:getValue()
    elseif self.state == "hide" then
        alpha = 1 - self.animationNode:getValue()
    end
    local revealShader = Tree.assets.files.shaders.reveal
    revealShader:send("t", alpha)
end

function characterPanel:draw()
    self.skillRow:draw()

    --- @TODO: переписать этот ужас с жонглированием координатами, а то слишком хардкод (skillRow рисуется относительно нуля и не закрывает канвас)
    love.graphics.push()
    local canvas = love.graphics.getCanvas()
    love.graphics.translate(0, self.bars.bounds.height)
    love.graphics.setCanvas(characterPanelCanvas)
    love.graphics.clear()
    love.graphics.draw(canvas)
    love.graphics.pop()

    love.graphics.push()
    love.graphics.translate(-self.bounds.x, -self.bounds.y)
    self.bars:draw()
    self:drawBorder("outer")
    love.graphics.pop()

    --- рисуем текстуру шейдером появления
    love.graphics.setCanvas()
    love.graphics.setShader(Tree.assets.files.shaders.reveal)
    love.graphics.setColor(1, 1, 1, 1)

    love.graphics.push()
    love.graphics.translate(self.bounds.x, self.bounds.y)
    love.graphics.draw(characterPanelCanvas)
    love.graphics.setColor(1, 1, 1)
    love.graphics.pop()
    love.graphics.setShader()
end

return characterPanel.new
