function onLoadInit() {
	setRandomBodyBackground();
}

function realmIdToRealm(rid) {
	switch(rid) {
	case 1: return "Order";
	case 2: return "Destruction";
	}

	return null;
}

function realmToRealmId(realm) {
	switch(realm.toLowerCase()) {
	case 'order': return 1;
	case 'destruction': return 2;
	}

	return null;
}

function raceToRaceId(race) {
	switch(race.toLowerCase()) {
	case 'dwarfs': return 2;
	case 'empire': return 3;
	case 'high elves': return 4;
	case 'greenskins': return 5;
	case 'chaos': return 6;
	case 'dark elves': return 7;
	}

	return null;
}

function raceIdToRace(rid) {
	switch(rid) {
	case 2: return "Dwarfs";
	case 3: return "Empire";
	case 4: return "High Elves";
	case 5: return "Greenskins";
	case 6: return "Chaos";
	case 7: return "Dark Elves";
	}

	return null;
}

function setInnerHtml(eStr, html) {
	var e = YAHOO.util.Dom.get(eStr);
	if (e) {
		e.innerHTML = html;
	}
}

function setValue(eStr, html) {
	var e = YAHOO.util.Dom.get(eStr);
	if (e) {
		e.value = html;
	}
}

function debugDumpObj(name, o) {
	var str = name + " = ";

	if (o == null) { beejjs.debug.write("null"); return; }
	if (o == undefined) { beejjs.debug.write("undefined"); return; }

	for (var key in o) {
		var val;
		try {
			val = '' + o[key]; // ff2 sometimes throws an exception here
		} catch(err) {
			val = "EXCEPTION";
		}
		str += ("{" + key + ":" + val + "} ");
	}

	beejjs.debug.write(str);
}


/**
 * since the DB gives me PST8PDT times that look like UTC times, I have
 * to convert them to UTC before they can be converted to the user's
 * local timezone.  This would be easy if Javascript allowed you to
 * calculate the time offset for any timezone (namely PST), but it only
 * supports the user's local timezone.
 *
 * This function calculates the time offset in minutes, and accounts for
 * DST.  And it's a hack.
 *
 * WARNING: this function only works from 2008 to 2017.
 *
 * Note to future implementers: always export data in UTC if you ever
 * want it to change to another timezone. 
 */

_usTimezoneOffsetCache = null;

function usTimezoneOffset(d, loc) { // loc = 'pacific' or 'central'
	var dms = Number(d);

	if (_usTimezoneOffsetCache == null) {
		_usTimezoneOffsetCache = [
			Date.parse("Mar 9 2008 01:59:59") + 999,
			Date.parse("Nov 2 2008 01:59:59") + 999,
			Date.parse("Mar 8 2009 01:59:59") + 999,
			Date.parse("Nov 1 2009 01:59:59") + 999,
			Date.parse("Mar 14 2010 01:59:59") + 999,
			Date.parse("Nov 7 2010 01:59:59") + 999,
			Date.parse("Mar 13 2011 01:59:59") + 999,
			Date.parse("Nov 6 2011 01:59:59") + 999,
			Date.parse("Mar 11 2012 01:59:59") + 999,
			Date.parse("Nov 4 2012 01:59:59") + 999,
			Date.parse("Mar 10 2013 01:59:59") + 999,
			Date.parse("Nov 3 2013 01:59:59") + 999,
			Date.parse("Mar 9 2014 01:59:59") + 999,
			Date.parse("Nov 2 2014 01:59:59") + 999,
			Date.parse("Mar 8 2015 01:59:59") + 999,
			Date.parse("Nov 1 2015 01:59:59") + 999,
			Date.parse("Mar 13 2016 01:59:59") + 999,
			Date.parse("Nov 6 2016 01:59:59") + 999,
			Date.parse("Mar 12 2017 01:59:59") + 999,
			Date.parse("Nov 5 2017 01:59:59") + 999
		]
	}

	var dst = false;
	for (i = 0; i < _usTimezoneOffsetCache.length; i++) {
		if (dms <= _usTimezoneOffsetCache[i]) {
			break;
		}
		dst = !dst;
	}

	if (loc == 'central') {
		return dst? (5*60): (6*60);
	}

	return dst? (7*60): (8*60);
}

/**
* handle ISO8601 dates
* http://delete.me.uk/2005/03/iso8601.html
*
* this has been hacked to assume all non-tz'd dates are pst8pdt.
*
* var date = new Date();
* date.setISO8601("2005-03-26T19:51:34Z");
*/
Date.prototype.setISO8601 = function (string) {
	var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
		"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
		"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
	var d = string.match(new RegExp(regexp));

	var offset = 0;
	var date = new Date(d[1], 0, 1);

	if (d[3]) { date.setMonth(d[3] - 1); }
	if (d[5]) { date.setDate(d[5]); }
	if (d[7]) { date.setHours(d[7]); }
	if (d[8]) { date.setMinutes(d[8]); }
	if (d[10]) { date.setSeconds(d[10]); }
	if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
	if (d[14]) {
		offset = (Number(d[16]) * 60) + Number(d[17]);
		offset *= ((d[15] == '-') ? 1 : -1);
	} else {
		offset += usTimezoneOffset(date, 'pacific');
	}
	offset -= date.getTimezoneOffset();
	time = (Number(date) + (offset * 60 * 1000));
	this.setTime(Number(time));
}

/**
* handle ISO8601 dates
* http://delete.me.uk/2005/03/iso8601.html
*
* this has been hacked to assume all non-tz'd dates are pst8pdt.
*
* var date = new Date();
* date.setISO8601Central("2005-03-26T19:51:34Z");
*/
Date.prototype.setISO8601Central = function (string) {
	var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
		"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
		"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
	var d = string.match(new RegExp(regexp));

	var offset = 0;
	var date = new Date(d[1], 0, 1);

	if (d[3]) { date.setMonth(d[3] - 1); }
	if (d[5]) { date.setDate(d[5]); }
	if (d[7]) { date.setHours(d[7]); }
	if (d[8]) { date.setMinutes(d[8]); }
	if (d[10]) { date.setSeconds(d[10]); }
	if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
	if (d[14]) {
		offset = (Number(d[16]) * 60) + Number(d[17]);
		offset *= ((d[15] == '-') ? 1 : -1);
	} else {
		offset += usTimezoneOffset(date, 'central');
	}
	offset -= date.getTimezoneOffset();
	time = (Number(date) + (offset * 60 * 1000));
	this.setTime(Number(time));
}

monthName = [ 'January', 'February', 'March', 'April', 'May', 'June',
	'July', 'August', 'September', 'October', 'November', 'December'];

function battleDateFormat(d1, d2) {
	var m1 = d1.getMonth();
	var m2 = d2.getMonth();

	if (m1 != m2) {
		return monthName[d1.getMonth()] + ' ' + (d1.getDate()) +
			'&mdash;' + monthName[d2.getMonth()] + ' ' + (d2.getDate());
	}

	return monthName[d1.getMonth()] + ' ' + (d1.getDate()) +
		'-' + (d2.getDate());
}

function singleDateFormat(d1) {
	return monthName[d1.getMonth()] + ' ' + (d1.getDate()) +
		', ' + (d1.getFullYear());
}

function singleDateFormatWithTime12(d1) {
	var hour = d1.getHours();
	var ampm = 'am';

	if (hour >= 12) {
		ampm = 'pm';
		hour -= 12;
	}
	
	if (hour == 0) {
		hour = 12;
	}

	return monthName[d1.getMonth()] + ' ' + (d1.getDate()) +
		', ' + (d1.getFullYear()) + ', ' + hour + ':' +
		beejjs.util.leadingZeroPad(''+d1.getMinutes(), 2) + ' ' + ampm;
}

function setRandomBodyBackground() {
	var e = YAHOO.util.Dom.get('bodyid');
	var bgnum = parseInt(Math.floor(Math.random()*3));
	beejjs.util.setElementClass(e, 'bg' + bgnum);
	bodyResize(); // just in case we didn't get one on start
}

var _oldwidth = null;
function bodyResize() {
	var e;

	if (navigator.appName.indexOf("Microsoft")!=-1) {
		e = YAHOO.util.Dom.get('bodyid');
		var windowWidth = document.body.offsetWidth;
		if (windowWidth == _oldwidth) { return; }
		_oldwidth = windowWidth;
		var offset = (windowWidth - 2400) / 2; // 2400 is width of image
		offset += 78; // fudge
		beejjs.util.setElementStyle(e, 'background-position:'+offset+'px 0px;');
		return; // putting this seemingly unnecessary return here makes ie6 happier
	} else {
		var e = YAHOO.util.Dom.get('mainbody');
		var windowWidth = e.offsetLeft;
		if (windowWidth == _oldwidth) { return; }
		_oldwidth = windowWidth;
		var offset = (windowWidth - 710);
		//alert(offset);
		e = YAHOO.util.Dom.get('bodyid');
		beejjs.util.setElementStyle(e, 'background-position:'+offset+'px 0px;');
		//alert(e.offsetLeft);
	}
}

function htmlize(s) {
	if (typeof s == 'undefined' || s == null) { return; }
    s = s.replace(/&/g, "&amp;");
    s = s.replace(/'/g, "&apos;");
    s = s.replace(/"/g, "&quot;");
    s = s.replace(/</g, "&lt;");
    return s.replace(/>/g, "&gt;");
}

function dehtmlize(s) {
	if (typeof s == 'undefined' || s == null) { return; }
    s = s.replace(/&gt;/g, ">");
    s = s.replace(/&lt;/g, "<");
    s = s.replace(/&quot;/g, '"');
    s = s.replace(/&apos;/g, "'");
    return s.replace(/&amp;/g, "&");
}

function fixLeadingCaps(s) {
	var words = s.split(' ');
	for (var i = 0; i < words.length; i++) {
		var lowerWord = words[i].toLowerCase();
		if (lowerWord == 'and') { continue; }
		words[i] = words[i].charAt(0).toUpperCase() + lowerWord.slice(1);
	}
	return words.join(' ');
}

// helper function to safely extract text nodes out of dom element lists
function getFirstChildNodeValue(n) {
	if (n == null || n == undefined || n.length < 1) {
		return '';
	}

	n = n[0];

	if (n.firstChild == undefined || n.firstChild.nodeValue == undefined) {
		return '';
	}

	return n.firstChild.nodeValue;
}

function formatTrophyPath(battleId, raceId) {
	return 'trophy_' + battleId + '_' + raceId + '.png';
}

function setHidden(e, hide) {
	if (typeof e == 'string') {
		e = YAHOO.util.Dom.get(e);
	}

	if (e == null) { return false; }

	if (hide) { 
		YAHOO.util.Dom.addClass(e, 'hidden');
	} else {
		YAHOO.util.Dom.removeClass(e, 'hidden');
	}

	return true;
}

function setVisible(e, vis) {
	if (typeof e == 'string') {
		e = YAHOO.util.Dom.get(e);
	}

	if (e == null) { return false; }

	if (vis) { 
		YAHOO.util.Dom.removeClass(e, 'invisible');
	} else {
		YAHOO.util.Dom.addClass(e, 'invisible');
	}

	return true;
}

/**
 * turns something like this: http://example.com/whatever.xyz?foo=10&bar=baz
 * into an object like this:
 *
 * o = {
 *    foo: '10',
 *    bar: 'baz'
 * }
 */
function parseGetVars(s) {
	getVars = {};

	var i = s.indexOf('?');
	if (i != -1) {
		s = s.slice(i+1);
		var pairs = s.split('&');
		for (var k = 0; k < pairs.length; k++) {
			var nameVal = pairs[k].split('=');
			//alert(nameVal[0] + " <-- " + nameVal[1]);
			getVars[decodeURIComponent(nameVal[0])] = decodeURIComponent(nameVal[1]);
		}

	}

	return getVars;
}

// derived from phpBBhacks profane words list,
// http://www.phpbbhacks.com/download/8023
_profanePatterns = [
	'@\\$\\$', 'a\\$\\$', 'as\\$', 'a\\$s', '@\\$s', '@s\\$', 'a55',
	'arse', 'ass', 'bi\+ch', 'b\!\+ch', 'b\!tch', 'b\!7ch', 'bi7ch',
	'b17ch', 'b1\+ch', 'b[o0][o0]b', 'b1tch', 'bitch', 'bastard',
	'breasts', 'butt.?pirate', 'c[o0]ck', 'cawk', 'chink', 'clit',
	'cum', 'cun[t7]', 'damn', 'dammit', 'd4mn', 'dick', 'dike', 'dildo',
	'dyke', 'ejac', 'fag', 'fanny', 'fatass', 'fat@\\$\\$',
	'fata\\$\\$', 'fatas\\$', 'fata\\$s', 'fat@\\$s', 'fat@s\\$',
	'fatarse', 'fcuk', 'feces', 'felch', 'ficken', 'foreskin', 'fu\\(',
	'fuck', 'fuk', 'fux', 'friggin', 'gay', 'gook', 'h0r', 'hell[^o]',
	'hoer', 'honkey', '\\bhore', '[^a-z]hore', 'injun', 'jackass',
	'jism', 'jizz', 'kanker', 'kawk', 'kike', 'l3i\+ch', 'l3itch',
	'l3i7ch', 'l3\!tch', 'l3\!\+ch', 'lesbo', 'm[a4]st[ue]rbat[ei]?',
	'merd', 'mofo', 'nazi', 'nigg[a4]', 'nigger', 'nuts.[ck]', 'penis',
	'phu[ck]', 'piss', 'p[o0][o0]p', 'p[o0]rn', 'pr[o0]n', 'preteen',
	'prick', 'puss', 'queef', 'qweef', 'scheiss', 'scrotum', 'shit',
	'sh\!t', 'shemale', 'slut', 'smut', 'spic', 'splooge', 'teets',
	'testicle', 'titt', 'tits', 'twat', 'vagina', 'wetback', 'whoar',
	'whore', 'wop', 'wtf'
];

function profanityIndex(s) {
	s = s.toLowerCase();
	var result = 0;
	for(var i = 0; i < _profanePatterns.length; i++) {
		var pat = _profanePatterns[i];
		if (s.search(pat) != -1) {
			result++;
		}
	}

	return result;
}

function getKeycodeFromEvent(e) {
	if (window.event) { // IE
		return e.keyCode; 
	} else if (e.which) { // everyone else
		return e.which;
	}
	return -1;
}

