﻿var Chat = Class.create({
	initialize: function(chatdiv, options) {
		this.options = { width: 'auto', height: '200px', lookback: 120, allowNameChange: false };
		Object.extend(this.options, options || { });

        var selfref = $$('script[src $= "javascript/chat.js"]');
        if (selfref.length == 1)
            this.baseURL = selfref[0].readAttribute('src').match('^(.*/?)javascript/chat.js$')[1];
        else
            this.baseURL = "";
        this.php = this.baseURL + "chat.php";
        
        this.timestamp = -this.options.lookback;
		this.updating = false;
		
		this.chatdiv = $(chatdiv);
		this.chatdiv.addClassName('chat');
		this.chatdiv.makePositioned();
		this.chatdiv.innerHTML = 
			'<div class="messages"></div> \
				<form onSubmit="return false;"> \
                    <label>' +
                    (this.options.allowNameChange ? '<a href="#" title="Change Name">You</a>' : 'You') +
                    ' say: </label> \
					<input type="text" name="chatline"/> \
				</form> \
			<div class="throbber"><img src="' + this.baseURL + 'Images/throbber_big.gif"/></div>';
		this.msgsdiv = this.chatdiv.select('.messages')[0];
		this.form = this.chatdiv.select('form')[0];
		this.input = $(this.form['chatline']);
		this.throbber = this.chatdiv.select('.throbber')[0];
        if (this.options.allowNameChange)
            this.form.select('label a')[0].observe('click', this._changeName.bindAsEventListener(this));
		
        this.chatdiv.setStyle({ width:this.options.width, marginLeft:'auto', marginRight:'auto' });
		this.msgsdiv.style.height = this.options.height;
		this.input.style.width = (this.msgsdiv.getWidth() - 64) + 'px';
		this.throbber.clonePosition(this.chatdiv).firstDescendant().centerOnParent();
		this.throbber.hide();
		this.form.observe('submit', this.send.bindAsEventListener(this));
	},
	
	login: function(username, room) {
		this.username = username;
		this.room = room;
		this._changeState('logged in', true);
		this.updater = setInterval(this._requestUpdate.bind(this), 5000);
	},
	
	logout: function() {
		this._changeState('logged out', false);
		this.updater = clearInterval(this.updater);
	},
    
    _changeName: function(evt) {
        var newname = prompt("Enter new name:", this.username);
        if (newname != null)
            this.changeName(newname);
        evt.stop();
    },
    
    changeName: function(newname) {
        this._changeState('changed name to ' + newname, true);
        this.username = newname;
    },
	
	changeRoom: function(room) {
		this._changeState('left room "' + this.room + '"', true);
		this.room = room;
		var fn = function(msg) { alert(msg); };
		this._changeState.bind(this, 'entered room "' + this.room + '"', true).delay(1);
	},

	_update: function(transport) {
		var msgs = transport.responseXML.getElementsByTagName('message');
		for (var idx = 0; idx < msgs.length; idx++) {
			var msg = msgs.item(idx);
			var ts = msg.getAttribute('timestamp');
			if (ts > this.timestamp) {
                // otherwise its an old, resent message
				if (msg.getAttribute('system') == "1") {
					this.msgsdiv.innerHTML += '<div class="systemmsg"><span class="author">' +
						msg.getAttribute('author') + '</span> ' + unescape(msg.firstChild.nodeValue) +
						'.</div>';
				} else {
					this.msgsdiv.innerHTML += '<p><span class="author">' + msg.getAttribute('author') +
						':</span> ' + unescape(msg.firstChild.nodeValue) + '</p>';
				}
				this.timestamp = ts;
			}
		}
		if (idx > 0)
			this.msgsdiv.scrollTop = this.msgsdiv.scrollHeight;
	},
	
	send: function() {
		this.form.disable();
		this.throbber.show();
		new Ajax.Request(this.php, {
			onSuccess: function(tr) {
				this._update(tr);
				this.form.reset();
			}.bindAsEventListener(this),
			onComplete: function() {
				this.throbber.hide();
				this.form.enable();
				this.input.focus();
			}.bindAsEventListener(this),
			parameters: {
				timestamp: this.timestamp,
				username: this.username,
				room: this.room,
				message: this.input.value
			}
		});
	},
	
	_changeState: function(state, update) {
		new Ajax.Request(this.php, {
			onSuccess: update ? this._update.bindAsEventListener(this) : null,
			parameters: {
				timestamp: this.timestamp,
				username: this.username,
				room: this.room,
				system: 1,
				message: state
			}
		});
	},

	_requestUpdate: function() {
		if (this.updating) return;
		this.updating = true;
		new Ajax.Request(this.php, {
			onSuccess: this._update.bindAsEventListener(this),
			onComplete: function() { this.updating = false; }.bindAsEventListener(this),
			parameters: {
				timestamp: this.timestamp,
				room: this.room
			}
		});
	}
});

