local super = require "Object"

DataPresenter = super:new()

function DataPresenter:new(artifact)
    self = super.new(self)
    
    self._rules = List:new()
    self._rules:setUndoable(true)
    self._rules:addObserver(self)
    
    return self
end

function DataPresenter:rewrap(sequence)
    local mt = {}
    mt.__index = mt
    mt.entrySequence = function(self, fieldName)
        if fieldName then
            return sequence:map(function(entry) return entry and entry[fieldName] end)
        else
            return sequence
        end
    end
    mt.entryCount = function(self)
        return sequence:length()
    end
    return setmetatable({}, mt)
end

function DataPresenter:unarchiveRules(archived)
    self._rules:setUndoable(false)
    for index = 1, #archived do
        self:addRule(unarchive(archived[index]))
    end
    self._rules:setUndoable(true)
end

function DataPresenter:ruleClass()
    warn('DataPresenter:ruleClass!')
    return nil
end

function DataPresenter:addRule(rule)
    if Object.isa(rule, self:ruleClass()) then
        self._rules:add(rule)
    end
end

function DataPresenter:addNewRule(suppressUndo)
    local rule = self:ruleClass():new()
    if suppressUndo then
        self:notUndoably(function()
            self:addRule(rule)
        end)
    else
        self:addRule(rule)
    end
    return rule
end

function DataPresenter:removeRule(rule)
    self._rules:remove(rule)
end

function DataPresenter:clearRules()
    for rule in self._rules:iter() do
        self._rules:remove(rule)
    end
end

function DataPresenter:rules()
    local rules = {}
    for rule in self._rules:iter() do
        rules[#rules + 1] = rule
    end
    return rules
end

function DataPresenter:hasRules()
    return self._rules:count() > 0
end

function DataPresenter:archive()
    local typeName, properties = super.archive(self)
    local rules = {}
    for rule in self._rules:iter() do
        rules[#rules + 1] = rule
    end
    properties.rules = rules
    return typeName, properties
end

function DataPresenter:apply(dataset)
    return dataset
end

function DataPresenter:getInspectors()
    local list = List:new()
    for rule in self._rules:iter() do
        list:join(rule:getInspectors())
    end
    return list
end

return DataPresenter
