         clearInterval _masterID
         _masterID = null
     @clear = ->
-        _elmnts.canvas
-        .getContext('2d')
-        .clearRect(
-            -_elmnts.canvas.width / 2,
-            -_elmnts.canvas.height / 2,
-            _elmnts.canvas.width,
-            _elmnts.canvas.height)
+        _context.clearRect -@canvas.width / 2, -@canvas.height / 2, @canvas.width, @canvas.height
+    
+    #start function + helpers
+    _firstTime = true
+    _start = ->
+        _masterID = setInterval _masterUpdate, 1000 / @config.frameRate
+        Sprite._startAll()
+        Sound._playAll()
+        return
     @start = (stateName) =>
         #prevent starting without properly stopping first
         unless @isRunning()
             if _firstTime
                 #add engine to a user defined '#gh' div
-                mainDiv = document.querySelector '#gh'
-                if mainDiv?
+                if mainDiv = document.querySelector '#gh'
                     mainDiv.appendChild _elmnts.main
                 else
                     console.log "There is no '#gh' element!"
 
                 #set the innerHTML of each element
-                _elmnts.title.innerHTML = document.title
-                _elmnts.leftPanelHeader.innerHTML = env.ENGINE.leftHeader
-                _elmnts.rightPanelHeader.innerHTML = env.ENGINE.rightHeader
-                _elmnts.footer.innerHTML = env.ENGINE.footer
-                _elmnts.canvas.innerHTML = 'Your browser does not support the &ltcanvas&gt tag'
+                _title.innerHTML = @config.title
+                _leftPanelHeader.innerHTML = @config.leftHeader
+                _rightPanelHeader.innerHTML = @config.rightHeader
+                _footer.innerHTML = @config.footer
+                @canvas.innerHTML = 'Your browser does not support the &ltcanvas&gt tag'
 
                 #set the size of the canvas
-                _elmnts.canvas.width = _elmnts.canvas.clientWidth
-                _elmnts.canvas.height = _elmnts.canvas.clientHeight
+                @canvas.width = @canvas.clientWidth
+                @canvas.height = @canvas.clientHeight
 
                 #center the canvas origin point
-                _elmnts.canvas
-                .getContext('2d')
-                .translate(
-                    _elmnts.canvas.width / 2,
-                    _elmnts.canvas.height / 2)
+                _context.translate @canvas.width / 2, @canvas.height / 2
 
                 #draw the start screen
-                _ctx = _elmnts.canvas.getContext '2d'
-                _ctx.save()
-                _ctx.globalAlpha = 1.0
-                _ctx.textAlign = 'center'
-                _ctx.textBaseline = 'middle'
-                _ctx.font = "#{env.STARTUP.size}px #{env.STARTUP.font}"
-                _ctx.fillStyle = env.STARTUP.color
-                _ctx.fillText env.STARTUP.text, 0, 0
-                _ctx.restore()
+                _context.save()
+                _context.globalAlpha = 1.0
+                _context.textAlign = 'center'
+                _context.textBaseline = 'middle'
+                _context.font = "#{@config.startUp.size}px #{@config.startUp.font}"
+                _context.fillStyle = @config.startUp.color
+                _context.fillText @config.startUp.text, 0, 0
+                _context.restore()
 
                 #make the entire canvas a start button
-                _elmnts.canvas.onclick = ->
-                    _startEverything()
+                @canvas.onclick = ->
+                    _start()
                     Greenhorn.changeState stateName ? 'GREENHORN'
-                    _elmnts.canvas.onclick = (e) ->
-                        Sprite.emitAll 'mouse:click'
+                    @canvas.onclick = (e) ->
+                        Sprite.emitAll 'mouse:click', e
 
                 #don't do all this a second time
                 _firstTime = false
             else
-                _startEverything()
+                _start()
                 if stateName then @changeState stateName
 
 #add to namespace object

    T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90
gh.KEYS = KEYS

#automatic initialization
document.onreadystatechange = ->
    if @readyState is 'interactive'
        (gh.init ? Greenhorn.start)()

#listen for key events
document.onkeydown = (e) ->
    e.preventDefault()
    Greenhorn.isDown[e.keyCode] = true
document.onkeyup = (e) ->
    e.preventDefault()
    Greenhorn.isDown[e.keyCode] = false

#asynchronous ID
_masterID = null

#draws on canvas once per frame
_masterUpdate = ->
    #clear previous frame
    Greenhorn.clear()

    #call custom update
    gh.update?()

    #draw all Sprites
    Sprite._drawAll()

#Engine class
class Greenhorn extends EventEmitter
    #keyboard input tracking array
    @isDown = new Array 256
    key = false for key in @isDown

    #name of the current state
    @currentState = 'STARTUP'

    #create Engine elements
    _elmnts =
        main: document.createElement 'div'
        title: document.createElement 'h1'
        leftPanel: document.createElement 'div'
        leftPanelHeader: document.createElement 'h3'
        canvas: document.createElement 'canvas'
        rightPanel: document.createElement 'div'
        rightPanelHeader: document.createElement 'h3'
        footer: document.createElement 'div'

    #give id's to primary children
    _elmnts.main.id = 'gh-main'
    _elmnts.title.id = 'gh-title'
    _elmnts.leftPanel.id = 'gh-left-panel'
    _elmnts.canvas.id = 'gh-canvas'
    _elmnts.rightPanel.id = 'gh-right-panel'
    _elmnts.footer.id = 'gh-footer'

    #assign gh-h class to panelHeaders
    _elmnts.leftPanelHeader.classList.add 'gh-h'
    _elmnts.rightPanelHeader.classList.add 'gh-h'

    #append all primary children to main div
    _elmnts.main.appendChild _elmnts.title
    _elmnts.main.appendChild _elmnts.leftPanel
    _elmnts.main.appendChild _elmnts.canvas
    _elmnts.main.appendChild _elmnts.rightPanel
    _elmnts.main.appendChild _elmnts.footer

    #append headers to panels
    _elmnts.leftPanel.appendChild _elmnts.leftPanelHeader
    _elmnts.rightPanel.appendChild _elmnts.rightPanelHeader

    #keep track of mouse events over canvas
    _elmnts.canvas.onmousemove = (e) ->
        @mouseX = e.pageX
        @mouseY = e.pageY
        Sprite.emitAll 'mouse:move'
    _elmnts.canvas.onmousedown = (e) ->
        Sprite.emitAll 'mouse:down'
    _elmnts.canvas.onmouseup = (e) ->
        Sprite.emitAll 'mouse:up'
    _elmnts.canvas.ondblclick = (e) ->
        Sprite.emitAll 'mouse:doubleClick'
    _elmnts.canvas.oncontextmenu = (e) ->
        e.preventDefault()
        Sprite.emitAll 'mouse:rightClick'

    #start all asynchronous functions
    _startEverything = ->
        _masterID = setInterval _masterUpdate, 1000 / env.FRAME_RATE
        Sprite._startAll()
        Sound._playAll()
        return

    #mouse position getters
    @getMouseX = ->
        _elmnts.canvas.mouseX - _elmnts.canvas.offsetLeft - _elmnts.canvas.width / 2

    @getMouseY = ->
        -(_elmnts.canvas.mouseY - _elmnts.canvas.offsetTop - _elmnts.canvas.height / 2)

    #add button to one of the panels
    @addButton = (config = {}) ->
        #add missing keys to config
        for own key, value of env.BUTTON_DEFAULT_CONFIG
            config[key] ?= value

        #create element

sedabull@gmail.com
###

#automatic initialization
document.onreadystatechange = ->
    if @readyState is 'interactive'
        Greenhorn.emit 'ready'

#keyboard value mapping object
KEYS =
    SHIFT: 16, CTRL: 17, ALT: 18
    ESC: 27, SPACE: 32, PGUP: 33
    PGDOWN: 34, END: 35, HOME: 36
    LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40
