$(function() {
	"use strict";

	var header = $('#header');
	var content = $('#content');
	var input = $('#input');
	var status = $('#status');
	var myName = false;
	var author = null;
	var logged = false;
	var socket = atmosphere;
	var subSocket;
	var transport = 'websocket';

	// We are now ready to cut the request
	var request = {
		url : '/chat',
		contentType : "application/json",
		logLevel : 'debug',
		transport : transport,
		trackMessageLength : true,
		reconnectInterval : 5000
	};

	request.onOpen = function(response) {
		content.html($('<p>', {
			text : 'Atmosphere connected using ' + response.transport
		}));
		input.removeAttr('disabled').focus();
		status.text('Choose name:');
		transport = response.transport;

		// Carry the UUID. This is required if you want to call
		// subscribe(request) again.
		request.uuid = response.request.uuid;
	};

	request.onClientTimeout = function(r) {
		content
				.html($(
						'<p>',
						{
							text : 'Client closed the connection after a timeout. Reconnecting in '
									+ request.reconnectInterval
						}));
		subSocket
				.push(atmosphere.util
						.stringifyJSON({
							author : author,
							message : 'is inactive and closed the connection. Will reconnect in '
									+ request.reconnectInterval
						}));
		input.attr('disabled', 'disabled');
		setTimeout(function() {
			subSocket = socket.subscribe(request);
		}, request.reconnectInterval);
	};

	request.onReopen = function(response) {
		input.removeAttr('disabled').focus();
		content.html($('<p>', {
			text : 'Atmosphere re-connected using ' + response.transport
		}));
	};

	// For demonstration of how you can customize the fallbackTransport using
	// the onTransportFailure function
	request.onTransportFailure = function(errorMsg, request) {
		atmosphere.util.info(errorMsg);
		request.fallbackTransport = "long-polling";
		header
				.html($(
						'<h3>',
						{
							text : 'Atmosphere Chat. Default transport is WebSocket, fallback is '
									+ request.fallbackTransport
						}));
	};

	request.onMessage = function(response) {

		var message = response.responseBody;
		try {
			var json = atmosphere.util.parseJSON(message);
		} catch (e) {
			console.log('This doesn\'t look like a valid JSON: ', message);
			return;
		}

		input.removeAttr('disabled').focus();
		if (!logged && myName) {
			logged = true;
			status.text(myName + ': ').css('color', 'blue');
		} else {
			var me = json.author == author;
			var date = typeof (json.time) == 'string' ? parseInt(json.time)
					: json.time;
			addMessage(json.author, json.message, me ? 'blue' : 'black',
					new Date(date));
		}
	};

	request.onClose = function(response) {
		content.html($('<p>', {
			text : 'Server closed the connection after a timeout'
		}));
		if (subSocket) {
			subSocket.push(atmosphere.util.stringifyJSON({
				author : author,
				message : 'disconnecting'
			}));
		}
		input.attr('disabled', 'disabled');
	};

	request.onError = function(response) {
		content.html($('<p>', {
			text : 'Sorry, but there\'s some problem with your '
					+ 'socket or the server is down'
		}));
		logged = false;
	};

	request.onReconnect = function(request, response) {
		content.html($('<p>', {
			text : 'Connection lost, trying to reconnect. Trying to reconnect '
					+ request.reconnectInterval
		}));
		input.attr('disabled', 'disabled');
	};

	subSocket = socket.subscribe(request);

	input.keydown(function(e) {
		if (e.keyCode === 13) {
			var msg = $(this).val();

			// First message is always the author's name
			if (author == null) {
				author = msg;
			}

			subSocket.push(atmosphere.util.stringifyJSON({
				author : author,
				message : msg
			}));
			$(this).val('');

			input.attr('disabled', 'disabled');
			if (myName === false) {
				myName = msg;
			}
		}
	});

	function addMessage(author, message, color, datetime) {
		content.append('<p><span style="color:'
				+ color
				+ '">'
				+ author
				+ '</span> @ '
				+ +(datetime.getHours() < 10 ? '0' + datetime.getHours()
						: datetime.getHours())
				+ ':'
				+ (datetime.getMinutes() < 10 ? '0' + datetime.getMinutes()
						: datetime.getMinutes()) + ': ' + message + '</p>');
	}
});
