local super = require "Object"

SVGTag = super:new()

function SVGTag:new(name, attributes, children)
    self = super.new(self)
    
    self._name = name
    self._attributes = attributes
    self._children = children
    
    return self
end

local function escapeText(value)
    local escapeCodes = {
        { char = '&', code = '&amp;' },
        { char = '<', code = '&lt;' },
        { char = '>', code = '&gt;' },
        { char = '"', code = '&quot;' },
        { char = "'", code = '&apos;' },
    }
    value = tostring(value)
    for index = 1, #escapeCodes do
        value = string.gsub(value, escapeCodes[index].char, escapeCodes[index].code)
    end
    return value
end

local function formatAttribute(value)
    if type(value) == 'number' then
        return string.format('%g', value)
    else
        return escapeText(value)
    end
end

function SVGTag:addChild(child)
    if type(self._children) == 'table' then
        self._children[#self._children + 1] = child
    end
    return self
end

function SVGTag:childCount()
    return #self._children
end

function SVGTag:serialize(buffer, depth)
    local spaces = string.rep(' ', depth)
    buffer:add(spaces, '<', self._name)
    for key, value in pairs(self._attributes) do
        buffer:add(' ', key, '="', formatAttribute(value), '"')
    end
    if type(self._children) == 'table' then
        buffer:add('>\n')
        for index = 1, #self._children do
            self._children[index]:serialize(buffer, depth + 1)
        end
        buffer:add(spaces, '</', self._name, '>')
    elseif type(self._children) == 'string' then
        buffer:add('>', escapeText(self._children), '</', self._name, '>')
    else
        buffer:add('/>')
    end
    buffer:add('\n')
end

return SVGTag
