local super = require "Button"

IconButton = super:new()

function IconButton:new()
    self = super.new(self)
    
    self.icon = nil
    
    return self
end

function IconButton:draw(canvas)
    local rect = self:rect()
    local strokeRect = rect:insetXY(0.375, 0.375)
    local strokePath = Path.rect(strokeRect, 3.25)
    local fillPath = Path.rect(rect:insetXY(self:fillInset(), self:fillInset()), 3.5)
    local shadowPath = Path.rect(rect:insetXY(self:fillInset() + self:outerShadowInset() / 2, self:fillInset() + self:outerShadowInset()), 3.5 - self:outerShadowInset() / 2)
    
    -- draw outer bevel
    canvas:preserve(function(canvas)
        canvas:setPaint(self:outerShadowPaint())
            :concatTransformation(Transformation.identity():translate(0, -self:outerShadowOffset()))
            :fill(shadowPath)
    end)
    
    -- draw button
    canvas:setPaint(self:fillPaint())
        :fill(fillPath)
    canvas:preserve(function(canvas)
        canvas:clip(fillPath)
            :setThickness(2.5)
            :setPaint(self:innerShadowPaint())
            :stroke(fillPath)
    end)
    canvas:setThickness(0.75)
        :setPaint(self:strokePaint())
        :stroke(strokePath)
    
    -- draw icon
    local icon = self.icon
    if icon then
        local iconRect = Rect:new(icon:canvas():metrics():rect())
        iconRect = iconRect:offset(rect:midx() - iconRect:width() / 2, rect:midy() - iconRect:height() / 2)
        canvas:drawIcon(icon, iconRect)
        
        canvas:preserve(function(canvas)
            canvas:clipIcon(icon, iconRect)
                :setPaint(self:tintPaint())
                :fill(Path.rect(iconRect))
        end)
    end
end

function IconButton:strokePaint()
    if self:isActive() then
        return Color.invisible
    else
        return Color.gray(0.85, 1)
    end
end

function IconButton:fillPaint(rect)
    if self:getStatus() then
        return Color.gray(0.95)
    elseif self:isActive() then
        return Color.gray(0.99)
    else
        return Color.gray(0.96)
    end
end

function IconButton:fillInset()
    return 0
end

function IconButton:innerShadowPaint()
    return Color.invisible
end

function IconButton:outerShadowPaint()
    if self:isActive() then
        return Color.gray(0, 0.15)
    else
        return Color.invisible
    end
end

function IconButton:outerShadowInset()
    return -0.5
end

function IconButton:outerShadowOffset()
    return 0.25
end

function IconButton:tintPaint()
    if self:getStatus() then
        return Color.gray(0, 0.1)
    elseif not self:isActive() then
        return Color.gray(0.9, 0.4)
    end
end

function IconButton:getIcon()
    return self.icon
end

function IconButton:setIcon(icon)
    self.icon = icon
    self:invalidate()
end

return IconButton
