local super = require "GraphLayer"

RangeGraphLayer = super:new()

local defaults = {
}

local nilDefaults = {
    'min', 'max', 'paint',
}

local freeGetterNames = {}
local constrainedGetterNames = {}
local commonGetterNames = {'min', 'max', 'paint'}

local freeInspectorInfo = {
}

local constrainedInspectorInfo = {
}

local commonInspectorInfo = {
    {'KeyArtifact', {'min'}, 'Minimum'},
    {'KeyArtifact', {'max'}, 'Maximum'},
    {'Color', {'getPaint:setPaint', custom = 'hasExplicitPaint:'}, 'Fill'},
}

function RangeGraphLayer: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
    
    return self
end

function RangeGraphLayer:getGetterPieceNames(constrained)
    local result = {}
    if constrained then
        appendtables(result, constrainedGetterNames)
    else
        appendtables(result, freeGetterNames)
    end
    appendtables(result, commonGetterNames)
    return result
end

function RangeGraphLayer:getInspectorInfo(constrained)
    local result = {}
    if constrained then
        appendtables(result, constrainedInspectorInfo)
    else
        appendtables(result, freeInspectorInfo)
    end
    appendtables(result, commonInspectorInfo)
    return result
end

function RangeGraphLayer:iterateValues(orientation, mapFunction)
    if orientation == self:getOrientation() then
        local dataset = self:getDataset()
        for _, propertyName in pairs({'min', 'max'}) do
            local sequence = self:getPropertySequence(propertyName, dataset)
            for _, value in sequence:iter() do
                mapFunction(value)
            end
        end
    end
end

function RangeGraphLayer:isOrientable()
    return true
end

function RangeGraphLayer:getPaint()
    return self:getProperty('paint') or self:getParent():getLayerHighlightPaint()
end

function RangeGraphLayer:usesLayerPaint()
    return false
end

function RangeGraphLayer:draw(canvas, rect, propertySequence, xScaler, yScaler)
    local defaultPaint = self:getPaint()
    local isVertical = self:getOrientation() == Graph.verticalOrientation
    canvas:clipRect(rect)
    
    propertySequence:each(function(min, max, paint)
        if isVertical then
            min, max = yScaler(min), yScaler(max)
        else
            min, max = xScaler(min), xScaler(max)
        end
        if min and max then
            local rangeRect = rect:copy()
            if isVertical then
                rangeRect.bottom = min
                rangeRect.top = max
            else
                rangeRect.left = min
                rangeRect.right = max
            end
            canvas:setPaint(paint or defaultPaint)
                :fill(Path.rect(rangeRect))
        end
    end)
end

return RangeGraphLayer
