 # TODO mit canvas tag kommt man direkt auf die browser render ticks.
 
 
+# multiple changes of this context possible
+singlton_callback = (that, callback) ->
+    req = -> callback?.apply(that, arguments)
+    req.replace = (replacement) -> that = req.that = replacement
+    req.that = that
+#     req.callback = callback?.callback
+#     req.cancel = callback?.cancel
+    return req
+
+cancelable_callback = (callback) ->
+    canceled = no
+    cb = -> callback?() unless canceled
+    cb.cancel = -> canceled = yes
+    cb.cancel.reset = -> canceled = no
+#     cb.callback = callback?.callback
+#     cb.replace = callback?.replace
+    return cb
+
+deferred_callbacks = () ->
+    done = no
+    callbacks = []
+    res = (cb) ->
+        return cb?() if done
+        callbacks.push(cb)
+    allowed = null
+    res.callback = ->
+        return (->) if done
+        callback = ->
+            if callback is allowed
+                while (cb = callbacks.shift())?
+                    cb?(arguments...)
+                callbacks = null
+                allowed = null
+                done = yes
+        allowed = callback
+        return callback
+    return res
+
+cancelable_and_retrivable_callbacks = () ->
+    canceled = no
+    res = (cb) ->
+        return ->
+            if canceled
+                res.callbacks.push(cb)
+            else
+                cb?(arguments...)
+    res.cancel = -> canceled = yes
+    res.reset = -> canceled = no
+    res.callbacks = []
+    return res
+
+
 removed = (el) ->
     el.closed is "removed"
 
+
+# NOTE delay and release are only for manipulations where no parent is needed
 # delay or invoke job immediately
 delay = (job) ->
     return if removed this

    # eventlisteners

    onadd: (parent, el) ->
        el._jquery_tracker = {el}
        # insert into parent
        that = this
        delay.call parent, -> # !
            el = el?._jquery_tracker?.el
            return if not el or removed this
            if this is @builder and @_jquery.parent().length is 0
                @_jquery = @_jquery.add(el._jquery)
#                 parent._jquery.data('dt-jquery', parent)
#                 console.error "ready!", el.name, el._jquery_ready
                el._jquery_ready?()
                el._jquery_ready = yes
            else
                parent = @_jquery_tracker.el
                done = -> that.animation.push ->
                    parent = parent?._jquery_tracker?.el
                    el = el?._jquery_tracker?.el
                    return unless parent and el
                    if parent is parent.builder
                        parent._jquery.parent().append(el._jquery)
                    else
                        for e in el._jquery ? []
                            parent._jquery?.append(e)
                    # FIXME listen on dom insertion event
#                     console.error "ready!", el.name, el._jquery_ready
                    el._jquery_ready?()
                    el._jquery_ready = yes
                # delay til end if el is a builder
                if el is el.builder
                    el.ready(done)
                else
                    done()

    onclose: (el) ->
        el._jquery_tracker ?= {el}
#         return if removed el
        if el is el.builder
            el._jquery ?= $()
        else
            el._jquery ?= $(el.toString())
#         el._jquery.data('dt-jquery', el)
        release.call el

        el.on 'newListener', (type) ->
            return if el._events?[type]?.length # dont bind two times for the same type
            el._jquery.bind type, ->
                el.emit type, this, arguments...
                return # dont return emit result (which is either true or false)

    ontext: (el, text) ->
        delay.call el, ->
            @_jquery.text(text)

    onraw: (el, html) ->
        that = this
        delay.call el, ->
            that.animation.push =>
                @_jquery?.html(html)

    onshow: (el) ->
        delay.call el, ->
            @_jquery.show()


    initialize: () ->
        do @listen
        # prefill builder with state
        @builder._jquery = $([])
        @builder._jquery_done = deferred_callbacks()
        do @builder._jquery_done.callback() # builder is allways done
        # override query
        old_query = @builder.query
        @builder.query = (type, tag, key) ->
