/* 1ec5.org
 * Console
 * Copyright © 2007-2009 Minh Nguyen. Some rights reserved under the Creative
 * Commons Attribution-ShareAlike 2.5 license. 
 */

var LOAD_INTERVAL = 1000;

function encodeHTML(str) {
	return str.replace(/&/g, "&amp;").replace(/</g, "&lt;")
			  .replace(/>/g, "&gt;");
}

function finishLoading() {
	clearInterval(loadNextLine.interval);
	$("#scroller").css("cursor", "default");
	$("#term-footer").show();
	$("#cmd").focus();
	document.title = "1ec5.org"
}

function loadNextLine() {
	$("#wait").hide();
	var line = $("#scroller > .term-intro:first");
	if (!line.length) {
		finishLoading();
		return;
	}
	line.removeClass("term-intro");
	line.show();
	scroll(0, $(document).height());
}

function goToUrl(url) {
	document.location = url;
}

function log(msg, type) {
	var classes = ["term"];
	if (typeof(type) == "string") classes.push(encodeHTML(type));
	$("#scrollback").append("<pre class='" + classes.join(" ") + "'>" + msg +
							"</pre>");
}
log.ERROR = "error";
log.INPUT = "input";

var sites = {
	www: "http://www.1ec5.org/",
	notes: "http://notes.1ec5.org/",
	panel: "http://panel.1ec5.org/",
	avim: "http://www.1ec5.org/software/avim/",
	mingerworld: "http://www.1ec5.org/3d/mingerworld/",
	px: "http://www.1ec5.org/planet/xavier/"
};
sites.planet = sites.px;

var apps = {
	www: {
		desc: "relaunch this shell",
		run: function() { goToUrl(sites.www); }
	},
	notes: {
		desc: "display most recent blog entries by Minh Nguy&#x1ec5;n",
		aliases: ["blog"],
		run: function() { goToUrl(sites.notes); }
	},
	avim: {
		desc: "type fully-accented Vietnamese using a standard keyboard",
		run: function() { goToUrl(sites.avim); }
	},
	mingerworld: {
		desc: "view Minh's artwork in a 3D environment",
		run: function() { goToUrl(sites.mingerworld); }
	},
	px: {
		desc: "display most recent blog entries by " + PX_AUTHORS +
			" <abbr title=\"Saint\">St.</abbr> Xavier bloggers",
		aliases: ["planet"],
		args: {
			"--year=<year>": "filter blogs by authors' graduation year"
		},
		run: function() { goToUrl(sites.px); }
	},
	panel: {
		desc: "not telling",
		run: function(args) {
			var url = "http://panel.1ec5.org/";
			for (var arg in args) {
				switch (arg) {
					case "mt": case "m": url += "mt/mt.cgi"; break;
				}
			}
			goToUrl(url);
		}
	},
	motd: {
		desc: "display the Message Of The Day",
		run: function() { log("Copyright &copy; 2007 Minh Nguyen. <a href=\"http://creativecommons.org/licenses/by-sa/2.5/\" rel=\"copyright\">Some rights reserved</a>."); }
	},
	copyright: {
		desc: "display copyright information",
		run: function() { log("Copyright &copy; 2007 Minh Nguyen. <a href=\"http://creativecommons.org/licenses/by-sa/2.5/\" rel=\"copyright\">Some rights reserved</a>."); }
	},
	help: {
		desc: "list available commands",
		args: {
			"<command>": "display help for a specific command"
		},
		run: function(argv) {
			var choices = apps;
			if (argv.length) {
				choices = {};
				for (var i = 0; i < argv.length; i++) {
					var app = apps[argv[i]];
					if (!app) noSuchCommand(argv[i]);
					else choices[argv[i]] = app;
				}
			}
			var msg = "";
			var maxAppNameLen = 0;
			for (appName in choices) {
				if (apps[appName].isAlias) continue;
				if (appName.length > maxAppNameLen) {
					maxAppNameLen = appName.length;
				}
			}
			for (appName in choices) {
				if (apps[appName].isAlias) continue;
				msg += "<b>" + appName + "</b>";
				for (var i = 0; i < maxAppNameLen - appName.length + 2; i++) {
					msg += " ";
				}
				msg += apps[appName].desc + "\n";
			}
			log(msg);
		}
	}
};
apps.blog = apps.notes;
apps.planet = apps.px;

function noSuchCommand(cmd) {
	log(encodeHTML(cmd) + ": command not found", log.ERROR);
}

function processCommand(cmd, argv) {
	$("#wait").hide();
	if (sites[cmd]) goToUrl(sites[cmd]);
	if (apps[cmd] && apps[cmd].run) {
		apps[cmd].run(argv);
		document.title = cmd + " \u2013 1ec5.org";
	}
	else noSuchCommand(cmd);
	finishLoading();
}

$(document).ready(function () {
	$(".term-intro").hide();
	$("#cmd").focus();
	var line = decodeURIComponent(document.location).replace(/\+/g, " ");
	line = /\?cmd=(.*)/g.exec(line);
	if (!line || !line[1]) {
		$("#term-footer").hide();
		loadNextLine.interval = setInterval(loadNextLine, LOAD_INTERVAL);
		return;
	}
	line = line[1].split(/\s*(?:;|&)\s*/g);
	for (var i = 0; i < line.length; i++) {
		log(">>> " + encodeHTML(line[i]), log.INPUT);
		var argv = line[i].split(/\s+/g);
		if (argv && argv[0] && argv[0] != "1ec5") {
			processCommand(argv[0].toLowerCase(), argv.slice(1));
		}
	}
});

$(document).click(function () {
	var cmd = $("#cmd");
	if (!$(this).is(cmd)) cmd.focus();
});

$(document).keydown(function (event) {
	if (event.keyCode == 27 /* Esc */) finishLoading();
	else $("#cmd").focus();
});

