x = require '../helper/XMLHttpRequest.js'
ajax = require '../helper/ajax.js'

###
 HTTP Interface for the WebSocketRails client.
###

class WebSocketRails.HttpConnection

	

  httpFactories: -> [
    -> new x.XMLHttpRequest(),
    -> new ActiveXObject("Msxml2.XMLHTTP"),
    -> new ActiveXObject("Msxml3.XMLHTTP"),
    -> new ActiveXObject("Microsoft.XMLHTTP")
  ]

  createXMLHttpObject: =>
    xmlhttp   = false
    factories = @httpFactories()
    for factory in factories
      try
        xmlhttp = factory()
      catch e
        continue
      break
    xmlhttp

  constructor: (@url, @dispatcher) ->
    @_url = @url
    @_conn         = new x.XMLHttpRequest()
    @last_pos      = 0
    @message_queue = []
    @_conn.onreadystatechange = @parse_stream
#    @_conn.addEventListener "load", @connectionClosed, false
    @_conn.open "GET", @_url, true
    @_conn.send()

  parse_stream: =>
    if @_conn.readyState == 3
      
      data         = @_conn.responseText.substring @last_pos
      @last_pos    = @_conn.responseText.length

      data = data.replace( /\]\]\[\[/g, "],[" )
      if data != ""
        decoded_data = JSON.parse data
      else
        decoded_data = {}

      @dispatcher.new_message decoded_data
    
#    if @_conn.readyState == 0
#      close_event = new WebSocketRails.Event(['connection_closed',{}])
#      @dispatcher.dispatch close_event

#    if @_conn.readyState == 4
#      close_event = new WebSocketRails.Event(['connection_closed',{}])
#      @dispatcher.dispatch close_event	

  trigger: (event) =>
    if @dispatcher.state != 'connected'
      @message_queue.push event
    else
      @post_data @dispatcher.connection_id, event.serialize()

  post_data: (connection_id, payload) ->
    ajax
      url: @_url
      type: 'POST'
      data:
        client_id: connection_id
        data: payload
      success: ->

  flush_queue: (connection_id) =>
    for event in @message_queue
      # Events queued before connecting do not have the correct
      # connection_id set yet. We need to update it before dispatching.
      if connection_id?
        event.connection_id = @dispatcher.connection_id
      @trigger event
    @message_queue = []

  connectionClosed: (event) =>
    close_event = new WebSocketRails.Event(['connection_closed', event])
    @dispatcher.state = 'disconnected'
    @dispatcher.dispatch close_event