###
Global object
###
@global = @

###
Console
###
console = do ->
    getMessage = (args) ->
        Array::join.call args, ' '

    Object.preventExtensions
        assert: (assertion, msg) ->
            unless assertion
                throw new Error msg
        log: ->
            _neft.console.log getMessage(arguments)
        info: ->
            _neft.console.info getMessage(arguments)
        warn: ->
            _neft.console.warn getMessage(arguments)
        error: ->
            _neft.console.error getMessage(arguments)
        trace: ->
            err = new Error
            err.name = 'Trace'
            err.message = getMessage arguments
            Error.captureStackTrace err, console.trace
            console.error err.stack

###
Timers
###
setTimeout = clearTimeout = setImmediate = null
do ->
    shots = Object.create null

    _neft.timers.registerCallback (id) ->
        if timer = shots[id]
            delete shots[id]
            timer()
        return

    setTimeout = (func, delay, arg1, arg2, arg3) ->
        if typeof func isnt 'function'
            throw new TypeError "'callback' argument must be a function"

        if typeof delay isnt 'number'
            delay = parseInt delay
        if isNaN(delay)
            delay = 4

        argc = arguments.length
        switch argc
            when 1, 2
                callFunc = func
            when 3
                callFunc = ->
                    func arg1
            when 4
                callFunc = ->
                    func arg1, arg2
            when 5
                callFunc = ->
                    func arg1, arg2, arg3
            else
                args = new Array argc - 2
                for i in [2...argc] by 1
                    args[i - 2] = arguments[i]
                callFunc = ->
                    func.apply null, args

        id = _neft.timers.shot delay
        shots[id] = -> Neft.tryCatch.tryCall callFunc
        id

    setImmediate = (func, arg1, arg2, arg3) ->
        if typeof func isnt 'function'
            throw new TypeError "'callback' argument must be a function"

        argc = arguments.length
        switch argc
            when 1
                callFunc = func
            when 2
                callFunc = ->
                    func arg1
            when 3
                callFunc = ->
                    func arg1, arg2
            when 4
                callFunc = ->
                    func arg1, arg2, arg3
            else
                args = new Array argc - 1
                for i in [1...argc] by 1
                    args[i - 1] = arguments[i]
                callFunc = ->
                    func.apply null, args

        _neft.timers.immediate -> Neft.tryCatch.tryCall callFunc

        -1

    clearTimeout = (id) ->
        delete shots[id]
        return

###
Neft code
###
`{{&neftCode}}`
@Neft = Neft

###
Application code
###
`{{&appCode}}`
