﻿var TextStream = Class.create();

TextStream.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');
    },
    _handle404: function() {
        this._bl();
        this._wc('Event is not active');
    },
    _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.aspx?event=' + this.eventId + '&last=' + this.lastData, options);
    },
    _process: function(transport) {
        this.lastData = transport.getHeader('last_position');
        var decode = decodeURIComponent(transport.responseText);
        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 == 1){ //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);
        }
    }
};