local super = require "View"

Chart = super:new()

local defaults = {
}

local nilDefaults = {
    'title',
    'dataset',
}

local handles = {
    ButtonHandle:new{
        text = Hook:new(
            function(self)
                local title = self:getProperty('title')
                if not ispresent(title) and not self._editingTitle then
                    return 'Add Title'
                end
            end,
            function(self, text)
            end),
        location = Hook:new(
            function(self)
                local rect = self:rect()
                local contentRect = self:contentRect()
                return contentRect:midx(), rect.top, 0.5, 1, 0, -3
            end,
            function(self, x, y, valign, halign, dx, dy)
            end),
        isVertical = Hook:new(false),
        inspector = Hook:new(
            function(self)
                return self:getTitleComponent()
            end,
            function(self, inspector)
            end),
    },
}

function Chart:new()
    self = super.new(self)
    
    for k, v in pairs(defaults) do
        self:addProperty(k, v)
    end
    for _, k in pairs(nilDefaults) do
        self:addProperty(k)
    end
    
    self._editingTitle = false
    
    return self
end

function Chart:unarchiveTitleFont(archived)
    -- NOTE: Version 1.4.2 and earlier stored chart title fonts without a typography scheme.
    self._legacyTitleFont = unarchive(archived)
end

function Chart:unarchived()
    if self._legacyTitleFont then
        self:setFont(TypographyScheme.titleFont, self._legacyTitleFont)
    end
    super.unarchived(self)
end

function Chart:getHandles()
    return appendtables({}, handles, super.getHandles(self))
end

function Chart:getInspectors()
    local list = super.getInspectors(self)
    local inspector
    inspector = self:createInspector('Dataset', {'dataset'}, 'Dataset')
    inspector:addHook(Hook:new(true), 'ordered')
    list:add(inspector)
    inspector = Inspector:new{
        title = 'Colors',
        type = 'Popup',
        icon = 'Colors',
        target = function()
            return self:getColorSchemeInspectors()
        end,
    }
    list:add(inspector)
    inspector = Inspector:new{
        title = 'Fonts',
        type = 'Popup',
        icon = 'Fonts',
        target = function()
            return self:getTypographySchemeInspectors()
        end,
    }
    list:add(inspector)
    return list
end

function Chart:getColorInspectors()
    local list = super.getColorInspectors(self)
    list:add(self:createColorInspector(ColorScheme.titlePaint, 'Titles'))
    return list
end

function Chart:getFontInspectors()
    local list = super.getFontInspectors(self)
    list:add(self:createFontInspector(TypographyScheme.titleFont, 'Title'))
    return list
end

function Chart:setDataset(dataset)
    self:setProperty('dataset', dataset)
end

function Chart:getDataset()
    return self:getProperty('dataset')
end

function Chart:contentRect()
    local rect = self:rect()
    local title = self:getProperty('title')
    if ispresent(title) or self._editingTitle then
        local titleFont = self:getFont(TypographyScheme.titleFont)
        local titleHeight = titleFont:height()
        rect.top = rect.top - titleHeight * 2
    end
    return rect
end

function Chart:getTitleRect()
    local rect = self:rect()
    local titleFont = self:getFont(TypographyScheme.titleFont)
    local titleHeight = titleFont:height()
    return Rect:new{
        left = rect.left,
        bottom = rect.top - 1.5 * titleHeight,
        right = rect.right,
        top = rect.top - 0.5 * titleHeight,
    }
end

function Chart:draw(canvas)
    self:drawTitle(canvas)
end

function Chart:drawTitle(canvas)
    local title = self:getProperty('title')
    if title then
        local titleRect = self:getTitleRect():insetXY(0, -3)
        local titleFont = self:getFont(TypographyScheme.titleFont)
        title = StyledString.new(title, { font = titleFont })
        canvas:setPaint(Color.invisible):fill(Path.rect(titleRect))
        TruncatedStyledStringStamp(canvas, titleRect, title, self:getPaint(ColorScheme.titlePaint), 0.5, 0.5)
    end
end

function Chart:getTitleComponent()
    local inspector, hook
    inspector = self:createInspector('string', { text = 'title' }, 'Title')
    inspector:addHook(self:getPaintHook(ColorScheme.titlePaint), 'paint')
    inspector:addHook(self:getFontHook(TypographyScheme.titleFont), 'font')
    inspector:addHook(Hook:new(0.5), 'halign')
    inspector:addHook(Hook:new(0.5), 'valign')
    hook = Hook:new(
        function()
            return self:getTitleRect():insetXY(0, -3)
        end,
        function(value) end)
    self:addDidDrawObserver(hook)
    inspector:addHook(hook, 'rect')
    hook = Hook:new(
        function() end,
        function(value)
            self._editingTitle = value
            self:invalidate(self)
        end)
    inspector:addHook(hook, 'editing')
    inspector:addHook(Hook:new(false), 'multiline')
    return inspector
end

function Chart:getEditableComponent(x, y)
    if not (x and y) then
        return
    end
    local contentRect = self:contentRect()
    if ispresent(self:getProperty('title')) and self:getTitleRect():contains(x, y) then
        return self:getTitleComponent()
    end
end

return Chart
