###
Define a property on a Layer that will emit a change event when that property changes.
Also, optionally give the property an initial value and a callback to run when the property changes.
@param {Layer} layer The layer on which to define the property.
@param {String} property The name of the property.
@param {Object} [value] The initial value of the property.
@param {Function} [callback] The callback to run when this property changes. Executed with two arguments: the property's new value and the Layer itself.
@param {Function} [validation] A function to validate the property's new value.
@param {String} [error] An error to throw if the validation function returned false.
@examples
Utils.define(myLayer, "toggled")
Utils.define(myLayer, "toggled", false)
Utils.define(myLayer, "toggled", false, myLayer.showToggled)
Utils.define(myLayer, "toggled", false, null, _.isBoolean, "Layer.toggled must be true or false.")
###
Utils.define = (layer, property, value, callback, validation, error) ->
validation ?= -> true
error ?= "Layer #{layer.id}'s property '#{property}' was given the wrong value type."
Object.defineProperty layer,
property,
get: -> return layer["_#{property}"]
set: (value) ->
if value?
if not validation(value) then throw error
return if value is layer["_#{property}"]
layer["_#{property}"] = value
layer.emit("change:#{property}", value, layer)
configurable: true
if callback? and typeof callback is 'function'
layer.on("change:#{property}", callback)
layer[property] = value