﻿var CartStream = Class.create();

CartStream.prototype = {
    options: null,
    eventId: null,
    lastData: '-1',
    _pe: null,
    initialize: function() {
        this.options = Object.extend({
            eventNameParam: 'event',
            eventId: null,
            contentId: 'content',
            textChange: null,
            delay: .5
        }, arguments[0] || {});
        if (this.options.eventId == null) {
            var h = new Hash(window.location.search.toQueryParams());
            this.eventId = h.get(this.options.eventNameParam);
        }
        else this.eventId = this.options.eventId;
        this.content = $(this.options.contentId);
        this._queueRequest();
    },
    _queueRequest: function(transport) {
        if (transport && (transport.status == 404 || transport.status == 403)) return;
        this._pe = new PeriodicalExecuter(this._pex.bindAsEventListener(this), this.options.delay);
    },
    _handleError: function(r, ex) {
        if (ex != null) this._wc(ex.toString());
    },
    _handle403: function() {
        this._bl();
        this._wc('You are not authorized to view this event');
        if (this.options.textChange) this.options.textChange();
    },
    _handle404: function() {
        if (this.content.childNodes.length <= 1) window.setTimeout('window.location.reload()', 10000);
        this._bl();
        this._wc('Event is not active');
        if (this.options.textChange) this.options.textChange();
    },
    _pex: function(pe) {
        this._pe.stop();
        this._pe = null;
        var options = {
            method: 'get',
            onSuccess: this._process.bindAsEventListener(this),
            onComplete: this._queueRequest.bindAsEventListener(this),
            onException: this._handleError.bindAsEventListener(this),
            on404: this._handle404.bindAsEventListener(this),
            on403: this._handle403.bindAsEventListener(this)
        }
        new Ajax.Request('/text-data.ashx?event=' + this.eventId + '&last=' + this.lastData, options);
    },
    _process: function(transport) {
        var r = transport.responseJSON;
        this.lastData = transport.getHeader('l_p');
        //this is a debug scenario when the javascript engine was not able to parse the json
        if (!r && transport.responseText.length > 0) {
            this._wc('||' + transport.responseText + '||');
            return;
        }
        for (var j = 0; j < r.i.length; j++) {
            var item = r.i[j];
            var decode = decodeURIComponent(item.d);
            for (i = 0; i < decode.length; i++) {
                switch (decode.charCodeAt(i)) {
                    case 8:
                        this._dc();
                        break;
                    case 10:
                        this._bl();
                        break;
                    case 13:
                        break;
                    default:
                        this._wc(decode.charAt(i));
                }
            }
            if (this.options.textChange) this.options.textChange();
        }
    },
    _bl: function() {
        Element.insert(this.content, "<br />");
    },
    _wc: function(c) {
        var lNode = this.content.lastChild;
        if (lNode == null || lNode.nodeType == 1 || this.content.childNodes.length == 0) { //last check is an IE hack
            lNode = document.createTextNode('');
            this.content.appendChild(lNode);
        }
        lNode.appendData(c);
    },
    _dc: function() {
        var lNode = this.content.lastChild;
        if (!lNode) return;
        //if the last node is a text node, then remove the text from that node
        if (lNode.nodeType == 3) {
            //if there is enough text in the text node to take care of all the
            //delete characters, then just remove those number of characters from
            //the end
            if (lNode.length > 1) {
                lNode.deleteData(lNode.length - 1, 1);
            }
            else {
                //remove the node from the document
                this.content.removeChild(lNode);
            }
        }
        else {
            //remove the node from the document and decrement the delete by one
            this.content.removeChild(lNode);
        }
    }
};
