local super = require "Hook"

PropertyHook = super:new()

function PropertyHook:new(defaultValue)
    self = super.new(self)
    
    self.defaultValue = defaultValue
    self.value = defaultValue
    if (type(defaultValue) == 'table' or type(defaultValue) == 'userdata') and type(defaultValue.addObserver) == 'function' then
        defaultValue:addObserver(self)
    end
    self.validator = nil
    self:setUndoable(true)
    
    return self
end

function PropertyHook:setValidator(validator)
    self.validator = validator
end

function PropertyHook:getValue()
    return self.value
end

function PropertyHook:setValue(value)
    if self.validator and not self.validator(value) then
        return false
    end
    local oldValue = self.value
    if value ~= oldValue then
        if (type(oldValue) == 'table' or type(oldValue) == 'userdata') and type(oldValue.removeObserver) == 'function' then
            oldValue:removeObserver(self)
        end
        self.value = value
        if (type(value) == 'table' or type(value) == 'userdata') and type(value.addObserver) == 'function' then
            value:addObserver(self)
        end
        self:invalidate(self)
        self:addUndo(function() self:setValue(oldValue) end)
    end
    return true
end

function PropertyHook:setDefaultValue(value)
    self.defaultValue = value
end

function PropertyHook:getDefaultValue()
    return self.defaultValue
end

return PropertyHook
