// Copyright 2004 Sven Neuhaus <sven@ping.de>. All rights reserved.

var txts = { // texts (for translation)
	// Appears in empty table
	pick_class     : "Pick a class from the list above",
	// Appears in select box
	pick_class_sel : "Pick a class",
	// Must match "N/A" string in abilities.html include file
	not_applicable : "N/A",
	// Appears in alert popup when you click an ability
	class_ability  : "Classes with this ability:\n",
	// Alert popup
	no_dom1        : "Your browser does not support DOM1.\n" +
		"Sorry, this page will not work with your browser.\n" +
		"Please try again with Mozilla, Konqueror 3+, Opera 7+, " +
		"Safari, Galeon, Firefox, Netscape 6+ or IE 5.5+...",
	// Appears on configurator page if there was no referrer
	no_referrer    : "If you bookmarked this page, please consider " +
		"bookmarking the <a href='./'>start page</a> instead.\n",
	// Display if foreign referrer is detected (deep linking)
	bad_referrer   : 'Visit the <a href="./">start page</a> for ' +
		"more information.",
	// Balloon help when hovering over ability level button
	extra_cost     : 'additional cost: ',
	// Alert box after loading configuration from cookie
	cookie_load    : 'Loading done.',
	// Alert box after no cookie found to be loaded.
	no_cookie      : 'No cookie found for this realm and class.'
	};

if (!window.Node)
	var Node = {
		ELEMENT_NODE: 1,
		ATTRIBUTE_NODE: 2,
		TEXT_NODE: 3,
		COMMENT_NODE: 8,
		DOCUMENT_NODE: 9,
		DOCUMENT_FRAGMENT_NODE: 11
	};

var realm;
var class_choice;
var abilities = new Object();
var level = 35;
var extra_level = 0;
var used = 0;
var popupw;
var start_time = new Date().getTime();

function realm_change () { 
	var choice = document.getElementById("realm").selectedIndex;
	realm = document.getElementById("realm").options[choice].value;
	create_class_options(realm);
	class_change();
}

function class_change () { 
	var choice = document.getElementById("classes").selectedIndex;
	class_choice = document.getElementById("classes").options[choice].value;
	remove_children(document.getElementById("abtbody"));
	compute_usage();
	var t = document.getElementById("abtbody");

	if (class_choice == "") {
		var tr = document.createElement("tr");
		t.appendChild(tr);	// New row
		var td = document.createElement("td");
		td.colSpan = 5;
		td.setAttribute("text-align", "center");
		var tx = document.createTextNode(txts.pick_class);
		tr.appendChild(td);
		td.appendChild(tx);
		return;
	}

	for (var ability in classes[realm][class_choice]) {
		var tr = document.createElement("tr");
		t.appendChild(tr);	// New row
		tr.appendChild(class_realm_ability(ability));
		tr.appendChild(class_ability_cost(ability));

		var td, tx;

/* No requirements in New Frontiers
		// Req. Skill
		td = document.createElement("td");
		tx = document.createTextNode(abilities[ability]["Req_Skill"]);
		if (abilities[ability]["Req_Skill"] != txts.not_applicable)
			td.setAttribute("title", 
				abilities[ abilities[ability]["Req_Skill"] ]["Description"]);
		tr.appendChild(td);
		td.appendChild(tx);

		// Req. Skill Level
		td = document.createElement("td");
		tx = document.createTextNode(abilities[ability]["Req_Lvl"]);
		tr.appendChild(td);
		td.appendChild(tx);
*/

		// Re-Use Timer
		td = document.createElement("td");
		tx = document.createTextNode(abilities[ability]["Timer"]);
		tr.appendChild(td);
		td.appendChild(tx);
	}
}

function class_realm_ability (ability) { // Realm Ability
	var td = document.createElement("td");
	var tx = document.createTextNode(ability);
	if (ability in abilities) {
		td.className = "type_" + abilities[ability]["Type"];
		td.onmouseover = balloon_help;
		td.onmouseout = balloon_help_off;
	} else { // inconsistency
		alert("Error: ability '" + ability + "' missing");
	}
	td.appendChild(tx);	// Text in cell
	return(td);
}

// Levels of individual Abilities
function class_ability_cost (ability) {
	td = document.createElement("td");

	// Special case: level 0
	var zero;
	var tx = document.createTextNode("0");
	if (classes[realm][class_choice][ability] == 0) {
		var zero = document.createElement("b");
		zero.className = "current";
	} else {
		var zero = document.createElement("a");
		zero.className = "points";
		zero.setAttribute("href", 
			'javascript:set_ability_level("' + ability + '",0)' );
	}
	td.appendChild(zero);
	zero.appendChild(tx);

	// Ability Levels 1-5
	var my_cost = 0;
	var use_modifier = class_choice in mod_cost[realm] &&
		ability in mod_cost[realm][class_choice];

	var num_levels = use_modifier
		? mod_cost[realm][class_choice][ability].length
		: abilities[ability]["Cost"].length;
	for(var i=0; i < num_levels; i++) {
		var abcost = use_modifier
			? mod_cost[realm][class_choice][ability][i]
			: abilities[ability]["Cost"][i];
		if (abcost == 0) break;
		if (classes[realm][class_choice][ability] <= i)
			my_cost += abcost - 0;

		var item;
		if (classes[realm][class_choice][ability]-1 == i) {
			item = document.createElement("b");
			item.className = "current";
		} else if (  /* not with New Frontiers:  check_requirements(ability) && */
				(classes[realm][class_choice][ability] > i ||
				my_cost <= (level + extra_level - used)) ) {
			item = document.createElement("a");
			item.className = "points";
			item.setAttribute("href", 'javascript:set_ability_level("' + 
				ability + '",' + (i+1) + ")" );
			if (my_cost != abcost) // improve this: it's always >= 0
				item.setAttribute("title", txts.extra_cost + my_cost);
		} else { // Not enough points
			item = document.createElement("span");
			item.className = "off";
		}
		var tx = document.createTextNode(abcost);
		td.appendChild(item);
		item.appendChild(tx);
	}
	return(td);
}

// No longer used in New Frontiers
function check_requirements (ability) {
	var req_ab = abilities[ability]["Req_Skill"];
	if (req_ab == txts.not_applicable) return true;
	var req_lvl = abilities[ability]["Req_Lvl"];
	if (req_ab in classes[realm][class_choice]) {
		if (req_lvl > classes[realm][class_choice][req_ab])
			return false;
		else
			return true;
	} else { // Prerequisite ability missing
		// alert("Prerequisite '"+req_ab+"' for '"+ability+"' missing in list");
		return false;
	}
}

function set_ability_level (ability, ablevel) {
	// var old = classes[realm][class_choice][ability];
	classes[realm][class_choice][ability] = ablevel;
	/* Check no longer required in New Frontiers. Should speed things up.
	if (ablevel < old) { // level was reduced, check requirements
		for (var i in abilities) { // look through all abilities
			if (abilities[i]["Req_Skill"] != ability) continue;
			if (abilities[i]["Req_Lvl"] <= ablevel) continue;
			if (i in classes[realm][class_choice]) {
				set_ability_level(i, 0); // recursion, might occur again
			} // else: required skill missing from class (!)
		}
	}
	*/
	class_change(); // refresh - TWEAKME
}

function compute_usage() {
	used = 0;
	if (class_choice != "") {
		for (var ability in classes[realm][class_choice]) {
			var use_modifier = class_choice in mod_cost[realm] &&
				ability in mod_cost[realm][class_choice];
			for (var i=0; i < classes[realm][class_choice][ability]; i++) {
				var abcost = use_modifier
					? mod_cost[realm][class_choice][ability][i]
					: abilities[ability]["Cost"][i];
				used += abcost - 0;
			}
		}
	}
	var r = document.getElementById("remaining").firstChild;
	r.data = level + extra_level - used;
	r = document.getElementById("used").firstChild;
	r.data = used;
}

// Compute realm points for a given realm level.
function realmpoints_level (level) {
	return (level == 1)
		? 1
		: Math.round(25/3 * Math.pow(level,3) - 
					 25/2 * Math.pow(level,2) + 
					 25/6 * level);
}

function coop_level_change () {
	extra_level = parseInt(document.getElementById("coop").value);
	if (isNaN(extra_level)) extra_level = 0;
	if (extra_level > 31) extra_level = 31;
	if (extra_level < 0) extra_level = 0;
	document.getElementById("coop").value = extra_level;
	var r = document.getElementById("remaining").firstChild;
	r.data = level + extra_level - used;

	class_change(); // refresh available levels - TWEAKME
}

function level_change (x) { 
	if (x == 0) { // manual input field change
		level = parseInt(document.getElementById("level").value);
		if (isNaN(level)) level = 0;
	} else {
		level += x - 0;
	}
	if (level > 100) level = 100;
	if (level < 0) level = 0;
	document.getElementById("level").value = level;
	var r = document.getElementById("remaining").firstChild;
	r.data = level + extra_level - used;

	document.getElementById("rp").firstChild.data = realmpoints_level(level);

	class_change(); // refresh available levels - TWEAKME
}

function create_class_options (realm) {
	var cls = document.getElementById("classes");
	cls.length = 0;
	var count = 0;
	var opt = new Option(txts.pick_class_sel, "");
	cls.options[count++] = opt;
	for (var i in classes[realm]) {
		opt = new Option(i,i);
		cls.options[count++] = opt;
	}
}

function remove_children(n) {
	for (var i = n.childNodes.length; i > 0; i--)
		n.removeChild(n.childNodes[0]);
}

function parse_abilities () {
	var x = document.getElementById("ablist");
	for (var a=0; a < x.childNodes.length; a++) {
		var y = x.childNodes[a];		// TR
		if (y.nodeType == Node.TEXT_NODE) continue;

		var cols = new Array(11);
		for (var b=0, c=0; b < y.childNodes.length; b++) {
			var z = y.childNodes[b];	// TD
			if (z.nodeType == Node.TEXT_NODE) continue;
			var t = z.firstChild;		// text
			if (t.nodeType != Node.TEXT_NODE) { // No Text??
				alert("text node missing..");
				continue;
			}
			cols[c] = t.data;
			if (c == 0) insert_search_link(t);
			c++;
		}
		abilities[cols[0]] = {
			Type:		cols[1],
			Timer:		cols[2],
			Cost:		cols.slice(3,8),
/* no longer used in New Frontiers
			Req_Skill:	cols[8],
			Req_Lvl:	cols[9], */
			Description:cols[8] // was: 10
		};
	}
}

function insert_search_link (node) {
	var a = document.createElement("a");
	a.setAttribute("href", 
		'javascript:find_class("' + node.data + '")' );
	var parent = node.parentNode;
	parent.replaceChild(a, node);
	a.appendChild(node);
}

function find_class (search_skill) {
	var x = txts.class_ability;
	for (var cl_realm in classes) {
		for (var cls in classes[cl_realm]) {
			for (var skill in classes[cl_realm][cls]) {
				if (skill == search_skill) {
					x += cl_realm + ": " + cls + "\n";
					break; // done with this class
				}
			}
		}
	}
	alert(x);
}

// Save chosen realm abilities for one class in one cookie
// The cookie will contain javascript
function cookie_save () {
	var cookie_name = realm + "_" + class_choice;
	var c = "level=" + level + ";" + // save realmlevel with char.
		"extra_level=" + extra_level + ";"; // and coop level
	var cx = classes[realm][class_choice];
	for (var c_ability in cx) {
		if (cx[c_ability] == 0)
			continue; // not changed
		// Create javascript source for eval() later on
		c += 'classes["' + realm + '"]["' + class_choice + '"]["' + c_ability + 
			'"]=' + cx[c_ability] + ";";
	}
	var exp = new Date((new Date()).getTime() + (150 * 86400000)); // 150 days
	document.cookie = escape(cookie_name) + "=" + escape(c) +
		"; expires=" + exp.toGMTString() +
		"; path=/~sven/";
	alert("Saving done.");
}

function cookie_load () {
	var cookie_name = realm + "_" + class_choice;
	var c = get_cookie(cookie_name);
	if (c) {
		eval(c); // Cookie contains Javascript source
		document.getElementById("level").value = level;
		document.getElementById("coop").value = extra_level;
		level_change(0);
		class_change();
		alert(txts.cookie_load);
	} else {
		alert(txts.no_cookie);
	}
}

function get_cookie(cn) {
	var search = escape(cn) + "=";
	if (! document.cookie.length)
		return; // no cookie

	offset = document.cookie.indexOf(search)
	if (offset == -1) return; // no such cookie

	// set index of beginning of value
	offset += search.length;
	// set index of end of cookie value
	end = document.cookie.indexOf(";", offset);
	if (end == -1) end = document.cookie.length;
	return unescape(document.cookie.substring(offset, end));
}

function balloon_help (e) {
	var node;
	if (!e) { // IE
		e = window.event;
		node = e.srcElement;
	} else {
		node = e.target;
	}
	if (node.firstChild) node = node.firstChild; // get textnode inside td
	var b = document.getElementsByTagName("body")[0];
	if (popupw) balloon_help_off();
	popupw = document.createElement("div");
	popupw.className = "popup";
	var scr_left =
		window.pageXOffset ? // NS6
			window.pageXOffset :
			document.body && document.body.scrollLeft ? // IE 5
				document.body.scrollLeft :
				document.documentElement.scrollLeft; // IE 6
	var scr_top =
		window.pageYOffset ?
			window.pageYOffset :
			document.body && document.body.scrollTop ?
				document.body.scrollTop :
				document.documentElement.scrollTop;
	popupw.style.left = (scr_left + e.clientX + 8 - 0) + "px";
	popupw.style.top = (scr_top + e.clientY + 10 - 0) + "px";
	var tx = document.createTextNode(
		abilities[node.data]["Description"]);
	popupw.appendChild(tx);
	b.appendChild(popupw);
}

function balloon_help_off () {
	if (!popupw) return;
	popupw.parentNode.removeChild(popupw);
	popupw = void 0;
}

function check_referrer () {
	var out = '';
	if (document.referrer == undefined ||
		document.referrer == '') {
		out = txts.no_referrer;
	} else if (document.referrer.indexOf("//www.ping.de/") == -1) {
		out = txts.bad_referrer;
	}
	return(out);
}

function init () {
	if (!document.getElementById) {
		alert(txts.no_dom1);
		return;
	}
	parse_abilities();
	realm_change();
}

function good_bye() {
    var b = new Date();
    var stayed = Math.floor((b.getTime() - start_time) / 1000);
    var x = new Image(1,1);
    x.src="../pics/pixel.gif?"+stayed;
}
window.onunload = good_bye;

// Usage:
//	document.getElementById("ausgabe").innerHTML += "<PRE>" + 
//		dump_tree(document.getElementById("ablist"),0) + "</PRE>";
function dump_obj (x) {
	var out="<HR>Object " + x.id + " Properties:\n";
	for (var i in x) {
		if (typeof(x[i]) == "function" || i.indexOf("_NODE") != -1)
			continue;
		out += i + "(" + typeof(x[i]) + ")=" + x[i] + "\n";
	}
	document.getElementById("ausgabe").innerHTML += "<PRE>" + out + "</PRE>";
}

function dump_tree (m,n) {
	var out = m.nodeName + " (" + m.nodeType + ")";
	if (m.id) 
		out += ' ID="' + m.id + '"';
	if (m.nodeType == Node.TEXT_NODE && m.data != "\n\n") {
		var t = new String(m.data);
		out += " = '" + t.replace(/\n/g, "") + "'";
	}
	if (m.firstChild)
		out += " contains:\n";
	else
		out += "\n";
	for (var m = m.firstChild; m != null; m = m.nextSibling) {
		for (var o = 0; o <= n; o++) 
			out += " ";
		out += dump_tree(m,n+1);
	}
	return out;
}

//eof. This file has not been truncate
