
/*
 * weinre is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 * 
 * Copyright (c) 2010, 2011 IBM Corporation
 */

require ./Ex
require ./Weinre
require ./EventListeners

//-----------------------------------------------------------------------------
class WebSocketXhr(url)
    this.initialize(url)
    
//-----------------------------------------------------------------------------
static
    WebSocketXhr.CONNECTING = 0
    WebSocketXhr.OPEN       = 1
    WebSocketXhr.CLOSING    = 2
    WebSocketXhr.CLOSED     = 3

//-----------------------------------------------------------------------------
method initialize(url)
    this.readyState      = WebSocketXhr.CONNECTING 
    this._url            = url
    this._urlChannel     = null
    this._queuedSends    = []
    this._sendInProgress = true
    
    this._listeners = {
        open:    new EventListeners(),
        message: new EventListeners(),
        error:   new EventListeners(),
        close:   new EventListeners()
    }
    
    this._getChannel()

//-----------------------------------------------------------------------------
method _getChannel
    this._xhr(this._url, "POST", "", this._handleXhrResponseGetChannel)

//-----------------------------------------------------------------------------
method _handleXhrResponseGetChannel(xhr)
    if (xhr.status != 200) return this._handleXhrResponseError(xhr)

    try {
        var object = JSON.parse(xhr.responseText)
    }
    catch (e) {
        this._fireEventListeners("error", {message: "non-JSON response from channel open request"})
        this.close()
        return
    }
    
    if (!object.channel) {
        this._fireEventListeners("error", {message: "channel open request did not include a channel"})
        this.close()
        return
    }
    
    Weinre.connectorId = object.channel
    
    this._urlChannel = this._url + "/" + object.channel
    this.readyState = WebSocketXhr.OPEN

    this._fireEventListeners("open", { message: "open" })
    
    this._sendInProgress = false
    this._sendQueued()
    
    this._readLoop()

//-----------------------------------------------------------------------------
method _readLoop
    if (this.readyState == WebSocketXhr.CLOSED) return
    if (this.readyState == WebSocketXhr.CLOSING) return
    
    this._xhr(this._urlChannel, "GET", "", this._handleXhrResponseGet)

//-----------------------------------------------------------------------------
method _handleXhrResponseGet(xhr)
    var self = this
    
    if (xhr.status != 200) return this._handleXhrResponseError(xhr)

    try {
        var datum = JSON.parse(xhr.responseText)
    }
    catch (e) {
        this.readyState = WebSocketXhr.CLOSED
        
        this._fireEventListeners("error", {
            message: "non-JSON response from read request"
        })
        return
    }
    
    window.setTimeout(function() {self._readLoop()}, 0)

    datum.forEach(function(data) {
        self._fireEventListeners("message", {data: data})
    })

//-----------------------------------------------------------------------------
method send(data)
    if (typeof data != "string") throw new Ex(arguments, this.constructor.name + "." + this.caller)

    this._queuedSends.push(data)
    
    if (this._sendInProgress) return
    this._sendQueued();

//-----------------------------------------------------------------------------
method _sendQueued
    if (this._queuedSends.length == 0) return
    if (this.readyState == WebSocketXhr.CLOSED) return
    if (this.readyState == WebSocketXhr.CLOSING) return
    
    datum = JSON.stringify(this._queuedSends)
    this._queuedSends = []
    
    this._sendInProgress = true
    
    this._xhr(this._urlChannel, "POST", datum, this._handleXhrResponseSend)

//-----------------------------------------------------------------------------
method _handleXhrResponseSend(xhr)
    var httpSocket = this
    
    if (xhr.status != 200) return this._handleXhrResponseError(xhr)
    
    this._sendInProgress = false
    window.setTimeout(function() {httpSocket._sendQueued()}, 0)

//-----------------------------------------------------------------------------
method close
    this._sendInProgress = true
    this.readyState = WebSocketXhr.CLOSING
    this._fireEventListeners("close", {
        message: "closing",
        wasClean: true
    })
    this.readyState = WebSocketXhr.CLOSED

//-----------------------------------------------------------------------------
method addEventListener(type, listener, useCapture)
    this._getListeners(type).add(listener, useCapture)

//-----------------------------------------------------------------------------
method removeEventListener(type, listener, useCapture)
    this._getListeners(type).remove(listener, useCapture)

//-----------------------------------------------------------------------------
method _fireEventListeners(type, event)
    if (this.readyState == WebSocketXhr.CLOSED) return
    
    event.target = this
    this._getListeners(type).fire(event)

//-----------------------------------------------------------------------------
method _getListeners(type)
    var listeners = this._listeners[type]
    if (null == listeners) throw new Ex(arguments, "invalid event listener type: '" + type + "'")
    
    return listeners

//-----------------------------------------------------------------------------
method _handleXhrResponseError(xhr)
    if (xhr.status == 404) {
        this.close()
        return
    }
    
    this._fireEventListeners("error", {
        target: this,
        status: xhr.status,
        message: "error from XHR invocation: " + xhr.statusText
    })
    
    console.log("error from XHR invocation: " + xhr.status + ": " + xhr.statusText)

//-----------------------------------------------------------------------------
method _xhr(url, method, data, handler)
    if (null == handler) throw new Ex(arguments, "handler must not be null")
    
    var xhr = new XMLHttpRequest()
    
    xhr.httpSocket         = this
    xhr.httpSocketHandler  = handler
    xhr.onreadystatechange = _xhrEventHandler
    
    xhr.open(method, url, true)
    xhr.setRequestHeader("Content-Type", "text/plain")
    xhr.send(data)

//-----------------------------------------------------------------------------
function _xhrEventHandler(event)
    var xhr = event.target
    if (xhr.readyState != 4) return
    
    xhr.httpSocketHandler.call(xhr.httpSocket, xhr) 
