var connection = null;
var nickname;
var now;

function showcustomroom() {
	$("#customroom").toggle();
}

function gettimestamp() {
	now = new Date();
	var CurHour = now.getHours();
	var CurMinute = now.getMinutes();
	if (CurHour <= 9) {
		CurHour = '0' + CurHour;
	}
	if (CurMinute <= 9) {
		CurMinute = '0' + CurMinute;
	}
	now = CurHour+":"+CurMinute;
}

function doLogin(aForm) {
	if ( aForm.room.value == "null") {
		alert("You did not choose a Room");
		return false;
	}
	if (!aForm.nickname.value)
		return false;
	try {
		connection = new Strophe.Connection(BOSH_LOCATION);
		connection.connect(jid, password, onConnect);
		if (aForm.customroom.value) {
			room = aForm.customroom.value;
		} else {
			room = aForm.room.value;
		}
		nickname = aForm.nickname.value;
		$('#title').html("<b><a href='xmpp:"+room+"?join' title='Open in a XMPP Client'>"+room+"</a> Chat room</b> &nbsp;&nbsp;&nbsp; <small>Your Nickname is <em><b>"+nickname+"</b></em>&nbsp;&nbsp;&nbsp;<a href='index.html'>Logout</a></small>");		
	} catch (e) {
		alert(e);
	} finally {
		return false;	
	}
}

function onConnect(status) {
	if (status == Strophe.Status.CONNFAIL) {
		handleError('Failed to connect');
	} else if (status == Strophe.Status.DISCONNECTED) {
		handleDisconnected();
	} else if (status == Strophe.Status.CONNECTED) {
		// Add handlers connection.addHandler(callback, namespace, stanza_name, type, id, from)
		connection.addHandler(handleMessage, null, 'message', null, null, null);
		connection.addHandler(handlePresence, null, 'presence', null, null, null);
		connection.addHandler(handleIQ, null, 'iq', null, null, null);

		connection.addHandler(handleIqVersion, Strophe.NS.VERSION, 'iq', null, null, null);
		connection.addHandler(handleIqVersion, 'urn:xmpp:time', 'iq', null, null, null);

		connection.send($pres().tree());
		connection.send($pres({to: room + '/' + nickname}).tree());

		// Make things (in)visible
		$('#login').hide();
		$('#chat').show();
		$('#roster').show();
		$('#entry').show();
		$('#chat').append("<br /><br />"); //append 2 blank lines so 1st entries won't disappear under title
	}
}

function handleError(error) {
	alert("An error occured:" + error);
	handleDisconnected();
}

function handleDisconnected() {
	// Make things (in)visible
	$('#login').show();
	$('#chat').hide();
	$('#roster').hide();
	$('#entry').hide();
}

function addBubble(nick) {
	id = nick + 'Bubble';
	if (!document.getElementById(id)) {
		var div = '';
		div += '<div id="' + id + '" class="bubble" onmousedown="startDrag(this)" style="display: none">';
		div += '<a href="#" onclick="' +"$('#" + id + "').hide('slow')" + '">Close</a>';
		div += '<div id="' + id + 'Chat" class="bubbleChat"></div>';
		div += '<form id="' + id + 'Form" class="bubbleForm" onsubmit="return sendChatMessage(this,' + "'" + nick + "');" + '" action="#">';
		div += '<input type="text" name="text" id="' + id + 'Text" class="bubbleForm"/>';
		div += '</form>';
		div += '</div>';
		$('body').append(div);
	}
	$('#'+id).show('slow');
}

function handleMessage(msg) {
	gettimestamp();
	var html = '';
	var sender = Strophe.getResourceFromJid(msg.getAttribute('from'));
	if (sender) {
		sender = Strophe.xmlescape(sender);
	} else {
		sender = false;
	}
	var type = msg.getAttribute('type');
	var body = msg.getElementsByTagName('body')[0];
	if (body) {
		body = Strophe.xmlescape(Strophe.getText(body));
	} else {
		body = false;
	}
	var subject = msg.getElementsByTagName('subject')[0];
	if (subject) {
		subject = Strophe.xmlescape(Strophe.getText(subject));
	} else {
		subject = false;
	}

	html += '<div class="msg">';
	if (body) {
		if (sender) {
		  if (sender == nickname) {
			addclass = 'myuser';
		  } else {
			addclass = '';
		  }
			if (body.search(/^\/me/) == 0) {
				body = body.replace(/^\/me/, sender);
				html += '<span class="sender '+ addclass + '">';
				html += '['+ now + '] ';
				html += body;
				html += '</span></div>';
			} else if (body.search(/(http|https):/) == 0) {

                                body = body.replace(/(http|https):\/\/[\S]+(\b|S)/gim,'<a href="$&" target="_blank">$&</a>');

				html += '<span class="sender '+ addclass + '">';
				html += '['+ now + '] ';
				html += sender;
				html += ':</span> ';
				html += body + '</div>';

			} else {
				html += '<span class="sender '+ addclass + '">';
				html += '['+ now + '] ';
				html += sender;
				html += ':</span> ';
				html += body + '</div>';
			}
		} else {
			html += '<span class="server">';
			html += body + '</span></div>';
		}
	} else if (subject) {
		html += '<span class="server">';
		html += "The subject is: " + subject + '</span></div>';
	} else {
		return true;
	}

	if (type == 'chat') {
		addBubble(sender);
		$('#' + id + 'Chat').append(html);
		document.getElementById(id + 'Chat').lastChild.scrollIntoView();
	} else {
		$('#chat').append(html);
		document.getElementById('chat').lastChild.scrollIntoView();
	}

	return true;
}

function handlePresence(presence) {
	gettimestamp();
	if (Strophe.getBareJidFromJid(presence.getAttribute('from')) != room)
		return true
	roster_list = document.getElementById('roster_list');
	nick = Strophe.getResourceFromJid(presence.getAttribute('from'));
	type = presence.getAttribute('type');
	if (type == 'unavailable') {
		element = document.getElementById(nick);
		roster_list.removeChild(element);
		$('#chat').append('<div class="msg"><span class="server">' + nick + ' left the groupchat</span></div>');
	} else {
		if (nick == nickname) {
			addclass = 'myuser';
		  } else {
			addclass = 'link';
		  }
		roster_list.innerHTML += '<li id="' + nick + '" onclick="addBubble(' + "'" + nick + "')" + '" class="'+addclass+'" title="Click to Private Chat">' + nick + '</li>';
		$('#chat').append('<div class="msg"><span class="server">['+ now +'] ' + nick + ' joined the groupchat</span></div>');
	}

	return true;
}

function handleIQ(iq) {
	var to = iq.getAttribute('to');
	var from = iq.getAttribute('from');
	var type = iq.getAttribute('type');

	//FIXME: Clients SHOULD send the content of the original stanza back for analysis

	var reply = $iq({to: from, from: to, type: 'error'}).c('error', {type: 'cancel'}).c('feature-not-implemented', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'});

	connection.send(reply.tree());

	return true;
}

function handleIqVersion(iq) {
	var to = iq.getAttribute('to');
	var from = iq.getAttribute('from');

	var reply = $iq({type: 'result', to: from, from: to}).c('query', {xmlns: Strophe.NS.VERSION}).c('name').t('XMPPChat').up().c('version').t('preAny').up().c('os').t(navigator.userAgent);

	connection.send(reply.tree());

	return true;
}

function handleIqTime(iq) {
	var now = new Date();
	var to = iq.getAttribute('to');
	var from = iq.getAttribute('from');

	var reply = $iq({type: 'result', from: to, to: from}).c('time', {xmlns: 'urn:xmpp:time'}).c('utc').t(now.getUTCFullYear() + '-' + now.getUTCMonth() + '-' + now.getUTCDate() + 'T' + now.getUTCHours() + ':' + now.getUTCMinutes() + ':' + now.getUTCSeconds + '.' + now.getUTCMilliseconds() + 'Z').up().c('tzo').t(now.getTimezoneOffset()/60 + ':' + now.getTimezoneOffset()%60);

	connection.send(reply.tree());

	return true;
}

function sendMessage(aForm) {
	if (aForm.text.value) {
		message = $msg({type: 'groupchat', to: room}).c('body').t(aForm.text.value);
		connection.send(message.tree());
		aForm.text.value = '';
	}
	return false;
}

function sendChatMessage(aForm, to) {
	gettimestamp()
	if (aForm.text.value) {
		body = aForm.text.value
		message = $msg({type: 'chat', to: room + '/' + to}).c('body').t(body);
		connection.send(message.tree());
		aForm.text.value = '';
		var html = '';
		html += '<div class="msg">';
		html += '<span class="sender">';
		html += '['+ now +'] ';
		html += nickname;
		html += ':</span> ';
		html += body + '</div>';
		document.getElementById(to + 'BubbleChat').innerHTML += html;
		document.getElementById(to + 'BubbleChat').lastChild.scrollIntoView();

	}
	return false;
}

var dragElement = null;
var mouseX = 0;
var mouseY = 0;
var offX = 0;
var offY = 0;

function startDrag(element) {
	dragElement = element;
	offX = mouseX - dragElement.offsetLeft;
	offY = mouseY - dragElement.offsetTop;
}

function doDrag(eve) {
	mouseX = eve.pageX;
	mouseY = eve.pageY;

	if (dragElement) {
		dragElement.style.left = (mouseX - offX) + 'px';
		dragElement.style.top = (mouseY - offY) + 'px';
	}
}

function stopDrag(eve) {
	dragElement = null;
}

onunload = function() {
	if (connection) {
		connection.disconnect();
	}
}

onmousemove = doDrag;

onmouseup = stopDrag;

