var Browser = {
	ie:     !!(window.attachEvent && !window.opera),
	opera:  !!window.opera,
	safari: navigator.userAgent.indexOf('Safari') != -1,
	gecko:  navigator.userAgent.indexOf('Gecko') != -1 && navigator.userAgent.indexOf('KHTML') == -1
};
Browser.ie7 = Browser.ie && navigator.userAgent.indexOf('MSIE 7.0') != -1;
Browser.ie6 = Browser.ie && navigator.userAgent.indexOf('MSIE 6.0') != -1 && !Browser.ie7;
navigator.userAgent.match(/Gecko\/([0-9]+)/);
Browser.geckoVersion = parseInt(RegExp.$1) | 0;

var $E = function(e) {
	if(!e) {
		if(typeof event != 'undefined')
			e = event;
		else
			return null;
	}

	// Netscape standard (1 = Left, 2 = Middle, 3 = Right)
	if(e.which) {
		e._button = e.which;
	}
	else {
		e._button = e.button;
		if(Browser.ie) {
			if(e._button & 4)
				e._button = 2; // Middle
			else if(e._button & 2)
				e._button = 3; // Right
		}
		else
			e._button = e.button + 1;
	}
	e._target = e.target ? e.target : e.srcElement;
	e._wheelDelta = e.wheelDelta ? e.wheelDelta : -e.detail;

	return e;
}

var str_replace = function(z,a,b){while(z.indexOf(a)!=-1)z=z.replace(a,b);return z}
var urlencode = function(z){z=encodeURIComponent(z);z=str_replace(z,'+','%2B');return z}

if (!String.prototype.ltrim)
	String.prototype.ltrim = function() { return this.replace(/^\s*/, ''); }
if (!String.prototype.rtrim)
	String.prototype.rtrim = function() { return this.replace(/\s*$/, ''); }
if (!String.prototype.trim)
	String.prototype.trim = function() { return this.ltrim().rtrim(); }
if (!String.prototype.removeAllWhitespace)
	String.prototype.removeAllWhitespace = function() { return this.replace('/\s+/g', ''); }

var ge = function(e) { return $(e); }
var ce = function(type) { return $(document.createElement(type)); };
var ae = function(parent, child) { parent.appendChild(child); };
var aef = function(parent, child) { parent.insertBefore(child, parent.firstChild); };
var de = function(element) { element.parentNode.removeChild(element); };
var ct = function(text) { return document.createTextNode(text); };
var ee = function(z,y){if(!y)y=0;while(z.childNodes[y])z.removeChild(z.childNodes[y])}
var rf = function() { return false; };
var aE = function(z,y,x){if(Browser.ie)z.attachEvent('on'+y,x);else z.addEventListener(y,x,false)}
var dE = function(z,y,x){if(Browser.ie)z.detachEvent('on'+y,x);else z.removeEventListener(y,x,false)}
var eO = function(z) { for(var p in z) delete z[p] }
var cO = function(d, s) { for(var p in s) d[p] = s[p] }
var cOr = function(d, s) {
	for (var p in s) {
		if(typeof s[p] == 'object') {
			if(!d[p]) d[p] = {};
			cOr(d[p], s[p]);
		}
		else
			d[p] = s[p];
	}
}
var ins = function(id, open, close) {
	var ele = $(id);
	ele.focus();

	if (ele.selectionStart != null) {
		var start = ele.selectionStart, end = ele.selectionEnd, sl = ele.scrollLeft, st = ele.scrollTop;
		var sel = ele.value.substring(start, end);

		ele.value = ele.value.substr(0, start) + open + sel + close + ele.value.substr(end);
		ele.selectionStart = ele.selectionEnd = end + open.length;

		ele.scrollLeft = sl;
		ele.scrollTop = st;
	}
	else if (document.selection && document.selection.createRange) {
		var range = document.selection.createRange();

		if (range.parentElement() != ele)
			return;

		var sel = range.text;

		range.text = open + sel + close;
	}
};
var nl = '\n';

var setFeatured = function(type, id) {
	var notes = prompt('Enter any notes for ' + id);
	new Ajax.Request('/?feature', {
		method: 'post',
		parameters: {
			type: type,
			id: id,
			notes: notes
		}
	});
};

var removeFeatured = function(type, id) {
	new Ajax.Request('/?feature', {
		method: 'post',
		parameters: {
			type: type,
			id: id,
			remove: 1
		}
	});
};

var setLoginPersist = function() {
	new Ajax.Request('/?stayloggedin', {
		method: 'get',
		onSuccess: function(transport) {
			var span = ge('loginpersist');
			if (span)
				de(span);
		}
	});
};

var AttachFormRequester = function(form, button, success, func) {
	$(button).onclick = function(e) {
		if (func)
			(func.bind(button))();
		new Ajax.Request(form.action, {
			method: form.method,
			parameters: $(form).serialize(true),
			onSuccess: function(transport) {
				window.location = success;
			}
		});
		return false;
	};
};

var Menu = function(opts) {
	cO(this, opts);

	this.activeMenu = {};
	this.menuCount = 0;
	this.create();
}

Menu.prototype = {
	create: function() {
		var parent = $(this.parent);
		if (!parent) return;

		for (var i in this.data) {
			var entry = this.data[i];
			var a = ce('a');
			a.rel = 'nott';
			a.menuDir = 'down';
			a.className = 'menuRoot';
			if (entry.url)
				a.href = entry.url;
			ae(a, ct(i));
			ae(parent, a);

			if (entry.menu) {
				a.child = this._createMenu(entry.menu, 1);
				a.child.parent = a;
				a.onmouseover = this.showMenu.bind(this, a.child, 1, a);
				a.onmouseout = this.hideMenu.bind(this, a.child);
			}
		}
	},

	_createMenu: function(menu, depth) {
		var div = ce('div');
		div.id = 'menu-' + (this.menuCount++);
		div.className = 'subMenu';
		for (var i = 0; i < menu.length; ++i) {
			var entry = menu[i];
			var a = ce('a');
			a.rel = 'nott';
			if (!entry.url)
				a.addClassName('header');
			else
				a.href = entry.url;

			if (entry.menu) {
				a.menuDir = 'right';
				a.addClassName('owner');
				a.child = this._createMenu(entry.menu, depth+1);
				a.child.parent = a;
				a.child.parentMenu = div;
				a.onmouseover = this.showMenu.bind(this, a.child, depth+1, div);
				a.onmouseout = this.hideMenu.bind(this, a.child);
			}

			ae(a, ct(entry.name));
			ae(div, a);
		}

		return div;
	},

	showMenu: function(menu, depth, parent) {
		var source = menu.parent;

		if (this.activeMenu[depth] && this.activeMenu[depth].id != menu.id) {
			var m = this.activeMenu[depth];
			if (m.parentNode)
				this.hideMenu(m, true);
		}
		this.activeMenu[depth] = menu;

		this.cancelHide(menu);
		this.cancelHide(parent);

		var pos = source.cumulativeOffset();
		if (source.menuDir == 'down') {
			pos.top += source.getHeight();
		}
		else if (source.menuDir == 'right') {
			pos.left += source.getWidth();
		}

		menu.style.position = 'absolute';
		menu.style.left = pos.left + 'px';
		menu.style.top = pos.top + 'px';
		ae(document.body, menu);

		menu.onmouseover = function(m, p) {
			m.hasMouse = true;
			this.cancelHide(m);
			this.cancelHide(p);
		}.bind(this, menu, parent);

		menu.onmouseout = function(m) {
			m.hasMouse = false;
			this.hideMenu(m);
		}.bind(this, menu);
	},

	hideMenu: function(menu, now) {
		this.cancelHide(menu);

		var timer = 200;
		if (now)
			timer = 0;

		menu.hideTimeout = setTimeout(function() {
			if (menu.parentNode)
				de(menu);
			if (menu.parentMenu && !menu.parentMenu.hasMouse)
				this.hideMenu(menu.parentMenu, true);
		}.bind(this), timer);
	},

	cancelHide: function(menu) {
		if (menu.hideTimeout)
			clearTimeout(menu.hideTimeout);
		menu.hideTimeout = null;
	}
};

var Tabs = function(parent) {
	this.parent = $(parent);
	this.initialize();
	this.tabs = [];
	this.selected = -1;
};

Tabs.prototype = {
	initialize: function() {
		var _ = this.tabDiv = ce('div');
		_.className = 'tab-bar';
		ae(this.parent, _);

		_ = this.paneDiv = ce('div');
		_.className = 'tab-pane';
		ae(this.parent, _);
	},
	finalize: function() {
		var name = '';
		if (location.hash && (name = /#tab-([a-z0-9-]+)/i.exec(location.hash))) {
			for (var i = 0; i < this.tabs.length; ++i) {
				if (this.tabs[i].pane.id == name[1]) {
					this.select(i, true);
					break;
				}
			}
		}
	},
	add: function(id, name) {
		var _ = ce('div');
		_.className = 'tab-tab';

		var a = ce('a');
		a.href = 'javascript:;';
		a.onclick = function(tabs, idx) {
			if (this.selected)
				return;
			tabs.select(idx, true);
			this.selected = true;
		}.bind(a, this, this.tabs.length);

		ae(a, ct(name));
		ae(_, a);
		ae(this.tabDiv, _);

		var div = $(id);
		div.style.display = 'none';
		if (div.parentNode)
			de(div);

		this.tabs.push({ tab: _, pane: div});
		if(this.tabs.length == 1) {
			a.selected = true;
			this.select(0);
		}
	},
	select: function(tab, hash) {
		if (this.selected > -1) {
			var current = this.tabs[this.selected];
			current.tab.firstChild.selected = false;
			current.tab.className = 'tab-tab';
			de(current.pane);
		}
		this.selected = tab;
		var current = this.tabs[this.selected];
		ae(this.paneDiv, current.pane);
		current.pane.style.display = '';
		current.tab.className = 'tab-selected';

		if (hash)
			location.hash = '#tab-' + current.pane.id;
	}
};

var EditPost = function(thread, post, body) {
	var postDiv = $('post' + thread + '-' + post);
	if (postDiv.editing)
		return;
	postDiv.editing = true;

	var bodyDiv = postDiv.childNodes[1];
	bodyDiv.originalText = bodyDiv.innerHTML;
	ee(bodyDiv);

	var div = ce('div');
	var ta = ce('textarea');
	ta.style.width = '98%';
	ta.rows = 7;
	ta.value = body;
	ae(div, ta);

	var button = ce('button');
	ae(button, ct('Edit'));
	button.onclick = function() {
		if (ta.value.trim().length == 0) {
			alert('Post must not be empty!');
			return;
		}

		new Ajax.Request('/?forum=edit&id=' + post, {
			method: 'post',
			parameters: 'body=' + urlencode(ta.value.trim()),
			onSuccess: function(xhr) {
				var editLink = $('editpost' + thread + '-' + post);
				editLink.onclick = function() { EditPost(thread, post, ta.value.trim()); };
				bodyDiv.innerHTML = xhr.responseText;
				delete postDiv.editing;
			},
			onFailure: function(xhr) {
				alert('Failure while editing post.');
			}
		});
	};

	ae(div, ce('br'));
	ae(div, button);

	button = ce('button');
	ae(button, ct('Cancel'));
	button.onclick = function() {
		delete postDiv.editing;
		bodyDiv.innerHTML = bodyDiv.originalText;
	};
	ae(div, button);

	var space = ce('div');
	space.className = 'space';
	ae(div, space);

	var preview = ce('div');
	preview.className = 'inset';
	preview.style.padding = '4px';
	preview.innerHTML = bodyDiv.originalText;
	ae(div, ct('Preview'));
	ae(div, preview);

	new Form.Element.DelayedObserver(ta, 0.33, function(ele, value) {
		new Ajax.Updater(preview, '/?getmarkup', {
			parameters: 'text=' + urlencode(ta.value.trim())
		});
	});

	ae(bodyDiv, div);
};

var DeletePost = function(thread, post) {
	new Ajax.Request('/?forum=delete&id=' + post, {
		method: 'get',
		onSuccess: function(xhr) {
			if (xhr.responseText == '0') {
				var postDiv = $('post' + thread + '-' + post);
				de(postDiv);
			}
			else
				alert('Failed to delete post.');
		}
	});
};

var TextEditor = function(id, owner, value) {
	this.id = id;
	this.create(owner, value);
};

TextEditor.prototype = {
	create: function(owner, value) {
		var div = ce('div');
		div.id = this.id + '-container';

		var toolbar = ce('div');
		div.addClassName('toolbar');

		var bButton = ce('button');
		bButton.onclick = rf;
		bButton.title = 'Bold';
		Event.observe(bButton, 'click', function(id, e) {
			ins(id, '[b]', '[/b]');
		}.bind(bButton, this.id));
		var img = ce('img');
		img.src = '/img/icons/text_bold.png';
		img.alt = 'Bold';
		ae(bButton, img);

		var iButton = ce('button');
		iButton.onclick = rf;
		iButton.title = 'Italics';
		Event.observe(iButton, 'click', function(id, e) {
			ins(id, '[i]', '[/i]');
		}.bind(iButton, this.id));
		img = ce('img');
		img.src = '/img/icons/text_italic.png';
		img.alt = 'Italic';
		ae(iButton, img);

		var sButton = ce('button');
		sButton.onclick = rf;
		sButton.title = 'Strikethrough';
		Event.observe(sButton, 'click', function(id, e) {
			ins(id, '[s]', '[/s]');
		}.bind(sButton, this.id));
		img = ce('img');
		img.src = '/img/icons/text_strikethrough.png';
		img.alt = 'Strikethrough';
		ae(sButton, img);

		var uButton = ce('button');
		uButton.onclick = rf;
		uButton.title = 'Underline';
		Event.observe(uButton, 'click', function(id, e) {
			ins(id, '[u]', '[/u]');
		}.bind(uButton, this.id));
		img = ce('img');
		img.src = '/img/icons/text_underline.png';
		img.alt = 'Underline';
		ae(uButton, img);

		var aButton = ce('button');
		aButton.onclick = rf;
		aButton.title = 'Link';
		Event.observe(aButton, 'click', function(id, e) {
			ins(id, '[a=' + window.prompt('Enter the address you\'d like to link to:') + ']', '[/a]');
		}.bind(aButton, this.id));
		img = ce('img');
		img.src = '/img/icons/link.png';
		img.alt = 'Link';
		ae(aButton, img);

		var brButton = ce('button');
		brButton.onclick = rf;
		brButton.title = 'Line break';
		Event.observe(brButton, 'click', function(id, e) {
			ins(id, '[br]' + nl, '');
		}.bind(brButton, this.id));
		img = ce('img');
		img.src = '/img/icons/arrow_undo.png';
		img.alt = 'Line break';
		ae(brButton, img);

		var pButton = ce('button');
		pButton.onclick = rf;
		pButton.title = 'Paragraph';
		Event.observe(pButton, 'click', function(id, e) {
			ins(id, '[p]', '[/p]');
		}.bind(pButton, this.id));
		img = ce('img');
		img.src = '/img/icons/pilcrow.png';
		img.alt = 'Paragraph';
		ae(pButton, img);

		var ulButton = ce('button');
		ulButton.onclick = rf;
		ulButton.title = 'Unordered List';
		Event.observe(ulButton, 'click', function(id, e) {
			ins(id, '[ul]' + nl + '[li]', '[/li]' + nl + '[/ul]');
		}.bind(ulButton, this.id));
		img = ce('img');
		img.src = '/img/icons/text_list_bullets.png';
		img.alt = 'Unordered List';
		ae(ulButton, img);

		var liButton = ce('button');
		liButton.onclick = rf;
		liButton.title = 'Add List Item';
		Event.observe(liButton, 'click', function(id, e) {
			ins(id, '[li]', '[/li]');
		}.bind(liButton, this.id));
		img = ce('img');
		img.src = '/img/icons/bullet_add.png';
		img.alt = 'Add List Item';
		ae(liButton, img);

		ae(toolbar, bButton);
		ae(toolbar, iButton);
		ae(toolbar, uButton);
		ae(toolbar, sButton);
		ae(toolbar, aButton);
		ae(toolbar, pButton);
		ae(toolbar, brButton);
		ae(toolbar, ulButton);
		ae(toolbar, liButton);

		ae(div, toolbar);

		var text = ce('textarea');
		text.id = this.id;
		text.name = this.id;
		text.rows = 15;
		text.cols = 80;

		if (value != null)
			text.value = value;

		ae(div, text);

		ae($(owner), div);
	}
};

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
var Base64 = {
	// private property
	_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode: function(input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
		input = Base64._utf8_encode(input);

		while (i < input.length) {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			}
			else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
		}
		return output;
	},

	// public method for decoding
	decode: function(input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		}

		output = Base64._utf8_decode(output);
		return output;
	},

	// private method for UTF-8 encoding
	_utf8_encode: function(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
		}
		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode: function(utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	}
};

document.observe('dom:loaded', function() {
	
});
