+# this file is used by the client and server.
+
+class GameState
+ constructor: (agent) ->
+ @agent = agent
+ state = {
+ hooks: {}
+ card_types: []
+ auto_shuffle: false
+ cards: []
+ piles: {}
+ }
+ on: (event, callback) ->
+ unless hooks[event]?
+ hooks[event] = []
+ hooks[event].push callback
+ trigger: (event, args...) ->
+ return unless hooks[event]?
+ for callback in hooks[event]
+ callback.apply this, args
+ move: (agent, card, x, y) -> # FIXME add pile argument
+ # FIXME what to do on error?
+ return unless cards[card]? #?.pile?
+ #cur_pile = cards[card].pile
+ #if pile isnt cur_pile
+
+ cards[card].x = x
+ cards[card].y = y
+
+ @trigger 'move', agent, card, x, y # FIXME add pile argument
+
+ mark: (agent, card, state) ->
+ # FIXME what to do on error?
+ return unless cards[card]?.marked? #?.pile?
+ card.marked = state
+ @trigger 'mark', agent, state
+
+ flip: (agent, card, state) ->
+ # FIXME what to do on error?
+ return unless cards[card]?.flipped? #?.pile?
+ card.flipped = state
+ @trigger 'flip', agent, state
+
+ # FIXME implement set_pile(pile, card_order_array)
+
+ set_cards: (cards) ->
+ trigger 'delete_all_cards'
+ @cards = []
+ @piles = {}
+ for card in cards
+ card.number = @cards.length
+ @cards.push card
+ if card.pile?
+ unless @piles[card.pile]?
+ @piles[card.pile] = []
+ @piles[card.pile].push card
+ trigger 'all_new_cards'
+