 Immutable = require 'immutable'
+{Map,List}=Immutable
 
 Transforms = require './transforms'
 

      uiState: uiState

    @defaultInput = Immutable.fromJS
      controllers:
        player1: {}
        player2: {}
        debug1: {}
        admin: {}
      dt: 0
      static:
        worldMap: worldMap

    ########################################################################################
    # SIGNALLY STUFF 

    adminControlEvents = @adminControllerMailbox.signal
      .dropRepeats(Immutable.is)
      .map((event) -> event.set('tag','admin'))

    playerControlEvents = @playerControllerMailbox.signal
      .merge(@playerControllerGpMailbox.signal)
      .dropRepeats(Immutable.is)
      .map((event) -> event.set('tag','player1'))

    dtEvents = @dtMailbox.signal
      .map((dt) -> Immutable.Map(type:'Tick',dt:dt))

    # Per time slice, bundle ticks and controller events into an "input" structure
    bundleInput = (events) =>
      input = @defaultInput
      for e in events
        switch e.get('type')
          when 'Tick'
            input = input.set('dt',e.get('dt'))
          when 'ControllerEvent'
            isDown = ('down' == e.get('action'))
            input = input.setIn(['controllers' ,e.get('tag'), e.get('control')], isDown)
      input

    gameInput = playerControlEvents
      .merge(dtEvents)
      .sliceOn(dtEvents)
      .map(bundleInput)

    # Game state value over time:
    updateGame = (input,s) ->

      # TODO: process events?
      return s1

    adminStateToGameState = (adminState, s) ->
      input = adminState.get('input')
      if adminState.get('paused')
        stepDt = adminState.get('stepDt')
        if stepDt?
          return updateGame(input.set('dt',stepDt), s)
        else
          return s
      else
        return updateGame(input,s)

    gameState = adminState
      .foldp(adminStateToGameState, TheGame.initialState())
      .dropRepeats(Immutable.is)
      .map (s) -> s.get('gameState')

    # When gameState changes, update view:
    gameState.subscribe (s) =>
      @viewMachine.update2(s)

  update: (dt) ->
    @dtMailbox.address.send dt
    @postOffice.sync()


  _update: (dt) ->
    empty = Map(admin: null, debug: null, p1Keyboard: null, p1Gamepad: null)
    controllerEvents = @controllerEventMux.next()
    # XXX:
    doDebug = false
