events = require "events"

###
 virtual properties that get called
###


class VirtualsDecor extends events.EventEmitter

  ###
  ###

  constructor: (@model, @_virtuals) ->
    @_loading = {}
    @model.on "watching", @_loadVirtual
    @model.reloadVirtual = (property) =>
      if @model.has(property)
        @_loadVirtual2 property

  ###
  ###

  _loadVirtual: (propertyChain) =>

    # virtuals are the first property chain
    root = propertyChain[0]

    # property exists? ignore it
    return if @model.get(root)?

    # ignore if the property is loading
    return if @_loading[root]

    # flag it!
    @_loading[root] = true

    # virtual defined? call it!
    if @_virtuals[root]
      @_virtuals[root].call @model, (err, result) =>
        @_loading[root] = false
        return if err?
        @model.set root, result

    # otherwise call load on the model
    else
      return @model.load()

  ###
  ###

  _loadVirtual2: (property) ->
    # virtual defined? call it!
    if @_virtuals[property]
      @_virtuals[property].call @model, (err, result) =>
        return if err?
        @model.set property, result


  ###
  ###

  @options  : (model) -> model.virtuals
  @decorate : (model, virtuals) ->
    new VirtualsDecor model, virtuals

module.exports = VirtualsDecor
