// The Javascript Shell

/*** Constants: ***/
const KEY_BACKSPACE = 8;
const KEY_TAB = 9;
const KEY_ENTER = 13;
const KEY_UP = 38;
const KEY_DOWN = 40;

const PS1 = '<span class="jssh_prompt"><span class="jssh_separator">[</span>%u<span class="jssh_separator">@</span>omegav <span class="jssh_pwd">%w</span><span class="jssh_separator">]</span>$</span> ';
const CURSOR = '<span id="jssh_cmdline"></span><blink id="jssh_cmdblink">_</blink><span id="jssh_cmdauto"></span>';


/*** Global variables ***/
var env_user = 'http';
var env_pwd = '~';

var env_hist = [""];
var env_hist_index = 0;


/*** Events: ***/
function jssh_init() {
	var jssh = document.getElementById('jssh');
	if(jssh != null) {
		//document.body.addEventListener('keypress', jssh_handleKeyPress, false);
		var PS = PS1.replace("\%u", env_user).replace("\%w", env_pwd);
		echo(PS + CURSOR);
	}
}

function jssh_handleKeyPress(e) {
	var jssh = document.getElementById('jssh');
	if(jssh == null) {
		return e;
	}
	var k = e.keyCode;
	var c = e.charCode;
	var cmd = document.getElementById('jssh_cmdline');


	if(k == KEY_ENTER) {
		// Start Job
		handleEnter(cmd.innerHTML);

		// Save to history
		if(cmd.innerHTML != "") {
			env_hist_index = env_hist.push("");
		}

		// Clear prompt
		cmd.innerHTML = "";
	} else if(k == KEY_TAB) {
		// Autocomplete
		handleTab(cmd.innerHTML);
		return false;
	} else if(k == KEY_UP) {
		if(0 < env_hist_index) {
			env_hist_index--;
		}
		cmd.innerHTML = env_hist[env_hist_index];
	} else if(k == KEY_DOWN) {
		if(env_hist_index+1 < env_hist.lengt) {
			env_hist_index++;
		}
		cmd.innerHTML = env_hist[env_hist_index];
	} else if(k == KEY_BACKSPACE) {
		// Remove char
		var v = cmd.innerHTML;
		var last = true;
		if(v.length > 0) {
			last = false;
		}

		cmd.innerHTML = v.substring(0, v.length - 1);
		env_hist[env_hist.length-1] = cmd.innerHTML;

		if(!last) {
			// Don't go back one page
			return false;
		}
	} else {
		// A-z
		cmd.innerHTML += String.fromCharCode(c || k);
		env_hist[env_hist.length-1] = cmd.innerHTML;
	}


	return e;
}

function handleEnter(cmd) {
	// Remove cursor
	var out = document.getElementById('jssh_output');
	out.removeChild(document.getElementById('jssh_cmdline'));
	out.removeChild(document.getElementById('jssh_cmdblink'));
	out.removeChild(document.getElementById('jssh_cmdauto'));

	// Run the command
	echo(cmd + "<div class='jssh_cmd'>"); // hack - show old command
	exec(cmd);
	echo("</div>");

	var PS = PS1.replace("\%u", env_user).replace("\%w", env_pwd);
	echo(PS + CURSOR);
}

function handleTab(cmd) {

	var fNames = [];
	var html = "<br>";
	for (var f in window) {
		if (window.hasOwnProperty(f) && typeof window[f] === 'function' && f.indexOf(cmd) === 0) {
			html += f + "<br>";
			fNames.push(f);
		}
	}
	
	if(fNames.length == 1) {
		document.getElementById('jssh_cmdline').innerHTML = fNames[0] + " ";
	} else {
		document.getElementById('jssh_cmdauto').innerHTML = html;
	}
}


/*** Commands: ***/
function cd(arg) {
	var pwd = arg.split(" ")[0];
	if(pwd == "") {
		pwd = "~";
	}
	env_pwd = pwd;
	return true;
}

function clear(arg) {
	var out = document.getElementById('jssh_output');
	out.innerHTML = "";
}

function df(arg) {
	str = "<table>";
	str += "<tr> <th>Filesystem</th> <th>Size</th> <th>Used</th>  <th>Avail</th> <th>Use%</th> <th>Mounted on</th> </tr>";
	str += "<tr> <td>udev</td> <td>11m</td> <td>87k</td> <td>11m</td> <td>1%</td> <td>/dev</td> </tr>";
	str += "<tr> <td>none</td> <td>526M</td> <td>0</td> <td>526M</td> <td>0%</td> <td>/dev/shm</td> </tr>";
	str += "<tr> <td>/dev/sda1</td> <td>486M</td> <td>24M</td> <td>437M</td> <td>6%</td> <td>/boot</td> </tr>";
	str += "<tr> <td>/dev/sda2</td> <td>20G</td> <td>1.6G</td> <td>18G</td> <td>9%</td> <td>/</td> </tr>";
	str += "<tr> <td>/dev/sda3</td> <td>58G</td> <td>2.7G</td> <td>52G</td> <td>5%</td> <td>/home</td> </tr>";
	str += "<tr> <td>/dev/sdb1</td> <td>1.5T</td> <td>684G</td> <td>719G</td> <td>49%</td> <td>/srv</td> </tr>";
	str += "</table>";
	echo(str);
	return true;
}

function echo(arg) {
	var out = document.getElementById('jssh_output');
	out.innerHTML += arg;
	return true;
}

function exec(arg) {
	var cmd = arg;
	var args = "";
	
	var space = arg.search(" ");
	if(space != -1) {
		cmd = arg.substring(0, space);
		args = arg.substring(space+1);
	}
	
	try {
		if(cmd != "") {
			window[cmd](args);
		}
	} catch(err) {
		echo("Error executing: " + cmd + "(" + args + ")<br>");
	}
}

function go(arg) {
	var cmd = arg.split(" ");
	window.location = "http://www.google.com/search?q=" + cmd[0] + "\&sourceid=navclient\&btnI=1"; // I'm Feeling Lucky
	return true;
}

function help(arg) {
	var ret = "";
	switch(arg.split(" ")[0]) {
		case "ls":
			ret += "List stuff";
			break;
		default:
			ret += "<a href='http://sam.zoy.org/wtfpl/COPYING'>WTFPL</a> jssh, version 0.6<br>";
			ret += "These shell commands are defined internally.  Type 'help' to see this list.<br>";
			ret += "Type 'help name' to find out more about the function 'name'.<br> <ul>";
			ret += "<li> cd - Goes to specified page</li>";
			ret += "<li> clear - Clears the screen</li>";
			ret += "<li> df - Prints imaginary HD usage</li>";
			ret += "<li> exec - Execute the following command</li>";
			ret += "<li> help - this</li>";
			ret += "<li> history - shows user history</li>";
			ret += "<li> ifconfig - List network interface info</li>";
			ret += "<li> search - Searches for an omegaV component</li>";
			ret += "<li> ls - List stuff</li>";
			ret += "<li> reboot - reloads the page</li>";
			ret += "</ul>";
	}
	echo(ret);
	return true;
}

function history(arg) {
	for(var i in env_hist) {
		echo(i + " " + env_hist[i] + "<br>");
	}
}

function ifconfig(arg) {
	var str = "<table>";
	var iface = arg.split(" ")[1];
	if(iface != "lo" ) {
		str +="<tr> <th>eth0</th> <td>Link encap:Ethernet  HWaddr 00:0B:DB:3E:34:91</td> </tr>";
		str +="<tr> <td></td> <td>inet addr:129.241.205.138  Bcast:129.241.205.127  Mask:255.255.255.128</td> </tr>";
		str +="<tr> <td></td> <td>inet6 addr: 2001:700:300:1463:213:21ff:fec9:8b5a/64 Scope:Global</td> </tr>";
		str +="<tr> <td></td> <td>inet6 addr: fe80::213:21ff:fec9:8b5a/64 Scope:Link</td> </tr>";
		str +="<tr> <td></td> <td>UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1</td> </tr>";
		str +="<tr> <td></td> <td>RX packets:658564949 errors:0 dropped:0 overruns:0 frame:0</td> </tr>";
		str +="<tr> <td></td> <td>TX packets:1178323538 errors:0 dropped:0 overruns:0 carrier:0</td> </tr>";
		str +="<tr> <td></td> <td>collisions:0 txqueuelen:1000</td> </tr>";
		str +="<tr> <td></td> <td>RX bytes:1472803889 (1404.5 Mb)  TX bytes:2181601239 (2080.5 Mb)</td> </tr>";
		str +="<tr> <td colspan='2'>&nbsp;</td> </tr>";
	}

	if(iface != "eth0" ) {
		str +="<tr> <th>lo</th> <td>Link encap:Local Loopback</td> </tr>";
		str +="<tr> <td></td> <td>inet addr:127.0.0.1  Mask:255.0.0.0</td> </tr>";
		str +="<tr> <td></td> <td>inet6 addr: ::1/128 Scope:Host</td> </tr>";
		str +="<tr> <td></td> <td>UP LOOPBACK RUNNING  MTU:16436  Metric:1</td> </tr>";
		str +="<tr> <td></td> <td>RX packets:1721 errors:0 dropped:0 overruns:0 frame:0</td> </tr>";
		str +="<tr> <td></td> <td>TX packets:1721 errors:0 dropped:0 overruns:0 carrier:0</td> </tr>";
		str +="<tr> <td></td> <td>collisions:0 txqueuelen:0</td> </tr>";
		str +="<tr> <td></td> <td>RX bytes:162490 (158.6 Kb)  TX bytes:162490 (158.6 Kb)</td> </tr>";
	}
	str += "</table>";
	echo(str);
}

function ls(arg) {
	var str = "";
	if(arg.split(" ")[0] == "-l") {
		str += "<table>"
		str += "<tr> <th colspan='6'>total 4K</th> </tr>";
		str += "<tr> <td>drwxr-xr-x</td> <td>9</td> <td>http http</td>";
		str += "<td>4.0K</td> <td>Jan 01 00:00</td> <td><span class='folder'>svn</span>/</td> </tr>";
		str += "</table>";
	} else {
		str = "<span class='folder'>svn</span>/<br>";
	}

	echo(str);
	return true;
}

function reboot(arg) {
	window.location.reload();
}

function search(arg) {
	var cmd = arg.split(" ");
	window.location = "http://omegav.no/komp?search=" + cmd[0];
	return true;
}

function su(arg) {
	var user = arg.split(" ")[0];
	if(user == "") {
		user = "root";
	}
	env_user = user;
}

function vim(arg) {
	var jssh = document.getElementById('jssh');
	var save = jssh.innerHTML;

	var html = "<p> \&nbsp; 1<br>";
	for(var i=0; i<10; i++) {
		html += "~<br>";
	}
	html += "</p>";

	jssh.innerHTML = html;
	jssh.contentEditable='true';
	//document.designMode='on';
}


