function firstAncestorOfClass(element, ancestorClass)
{
	element = $(element);
	while (element = element.parentNode)
		if (element.className.match(ancestorClass)) return element;
	return null;
}

function firstAncestorOfType(element, ancestorType)
{
	element = $(element);
	while (element = element.parentNode)
		if (element.nodeName == ancestorType) return element;
	return null;
}

function ourForm(element) {
	return firstAncestorOfType(element, 'FORM');
}

function submit_containing_form(link) {
	var form = firstAncestorOfType(link, 'FORM');
	if (form != null) {form.submit();}
	else {throw "could not find form";}
}

function getPos(obj, container)
{
	var op = Position.cumulativeOffset(obj);
	
	if (container != null) {
		var cp = Position.cumulativeOffset(container);
		op[0] -= cp[0];
		op[1] -= cp[1];
	}
	return op;
}

function getSize(obj)
{
	var wasVisible = Element.visible(obj)
	var saveVisibility = obj.style.visibility
	var w = h = 0
	if (!wasVisible)
	{
		obj.style.visibility = "hidden"
		Element.show(obj)
	}
	w = obj.offsetWidth
	h = obj.offsetHeight
	if (!wasVisible)
	{
		Element.hide(obj)
		obj.style.visibility = saveVisibility
	}
	return [w, h]
}

function hiliteListItem(daSelector, daId) {
	$$(daSelector).each (function(v, i) {v.removeClassName('selected');});
	$(daId).addClassName('selected');
}

function scrollToListItem(itemId) {
	var item = $(itemId);
	var parent = firstAncestorOfClass(item, 'scroller');
	var ip = getPos(item);
	var pp = getPos(parent);
	var sz = getSize(parent);
	ip[1] = ip[1] - pp[1];
	if (ip[1] >= sz[1]) parent.scrollTop = ip[1];
}

function selectThang(thangId, forRemove) {
	hiliteListItem('.thang-item', 'item_' + thangId);
	$('thang_id').value = thangId;
	$('add-button').disabled = forRemove;
	$('remove-button').disabled = !forRemove;
}

function highlightMediaItem(key)
{
	$$('.media-item').each (function(value, index) {value.removeClassName('selected');});
	$('media-item-' + key).addClassName('selected');
}

function focusAndSelectAll(element)
{
	$(element).focus();
	$(element).select();
}

function showEntryInfoField(base_id, field) {
	var em = $(base_id + '-embed-field');
	var li = $(base_id + '-link-field');
	var emp = em.parentNode;
	var lip = li.parentNode;
	if (field == 'embed') {
		lip.style.display = 'none';
		emp.style.display = 'block';
		em.focus();
		em.select();
	} else if (field == 'link') {
		emp.style.display = 'none';
		lip.style.display = 'block';
		li.focus();
		li.select();
	} else {
		emp.style.display = 'none';
		lip.style.display = 'none';
	}
}

// Disable a link while displaying a confirm alert.
// If the user confirms, the link is not re-enabled!
// Pass a message string and a link object.
// In an onclick handler, call as: safeConfirm('message', this).
function safeConfirm(message, link) {
  var saveclick = link.onclick;
  link.onclick = function(){return false;};
  result = confirm(message);
  if (!result) {
    link.onclick = saveclick;
  }
  return result;
};

//*************************
function scrollGridSelect(gridid, entry_cell_id)
{
	if ($(entry_cell_id))
	{
		var selector = "#" + gridid + " .selected";
		$$(selector).each (function(value, index) {value.removeClassName("selected");});
		$(entry_cell_id).addClassName("selected");

		document.evscroller_selected_cell = entry_cell_id
	}
	else
	{
		var nxt = $("evscroller_next");
		if (!nxt)
			nxt = $("evscroller_prev");
		if (nxt)
		{
			/*var url = nxt.onclick/*.match("http\:\/\/[^\"]+");*/
			var url = nxt.onclick + "";
			var url = url.match("http\:\/\/[^\"\']+");

			var e_keys = entry_cell_id.match("[A-Z][A-Z_0-9]+$");
			if (e_keys)
				e_key = e_keys[0];

			url += "?e=" + e_key;
			new Ajax.Request(url, {asynchronous:true, evalScripts:true});
		}
	}
}

// Scroll grid functions ----------------------------------------------

// Create a sibling of the old table called newpagename
function prepareNextPage(parentname, newpagename)
{
	theParent = $(parentname);
	newPage = document.createElement('div');
	newPage.id = newpagename;
	theParent.appendChild(newPage);
}

function removeMeOnFinish(obj)
{
	oldObj = obj.element;
	theparent = oldObj.parentNode;
	theparent.removeChild(oldObj);
}

function setCellSelection(obj)
{
	if ($(document.evscroller_selected_cell)) $(document.evscroller_selected_cell).addClassName("selected");
}

function slideAndDelete(parentname, newpagename, dir, select_key)
{
	theParent = $(parentname);
	newPage = $(newpagename);
	oldPage = theParent.getElementsByTagName("table")[0].parentNode;

	oldPos = getPos(oldPage, oldPage.parentNode);
	oldSize = getSize(oldPage);

	newPage.id = newpagename;
	newPage.style.position = 'absolute';
	newPage.style.left = (oldPos[0] + oldSize[0]) + 'px';
	newPage.style.top = oldPos[1] + 'px';

	newPage.style.width = oldSize[0] + 'px';
	newPage.style.height = oldSize[1] + 'px';

	// Left
	if (dir == 0)
	{
		newPage.style.left = (oldPos[0] - oldSize[0]) + 'px';
		newX = oldSize[0];
		newY = oldPos[1];
		newPage.show();

		new Effect.Move(oldPage, {mode:"absolute", x:newX, y:newY, duration:0.3, afterFinish:removeMeOnFinish});
		new Effect.Move(newPage, {mode:"absolute", x:0, duration:0.3, afterFinish: setCellSelection});
	}
	// Right
	else if (dir == 1)
	{
		newX = -oldSize[0];
		newY = oldPos[1];
		newPage.show();

		new Effect.Move(oldPage, {mode:"absolute", x:newX, y:newY, duration:0.3, afterFinish:removeMeOnFinish});
		new Effect.Move(newPage, {mode:"absolute", x:0, duration:0.3, afterFinish: setCellSelection});
	}
	// Scrolling something into view from who knows where
	// Only used when the flash player tell us it's going from one track to another
	else
	{
		newPage.style.left = oldPos[0] + 'px';
		newPage.style.top = oldPos[1] + 'px';

		document.evscroller_selected_cell = "evscroller_cell_" + select_key;

		new Effect.Fade(oldPage, {duration:0.4, afterFinish: removeMeOnFinish});
		new Effect.Appear(newPage, {duration:0.3, afterFinish: setCellSelection});
	}
}

function thisMovie(movieName) {return $(movieName);}

function timerMouseOver(e) {
	var width = getPos($('tic'), $('timer-wrapper'))[0];
	var ol = $('timer-overlay');
	ol.style.width = width + 'px';
	new Effect.Appear(ol, {duration:0.2});
}

function timerMouseOut(e) {
	if (!e) var e = window.event;
	var tg = (window.event) ? e.srcElement : e.target;
	var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
	while (reltg != tg && reltg.nodeName != 'BODY')
		reltg = reltg.parentNode;
	if (reltg == tg) return;
	new Effect.Fade($('timer-overlay'), {duration:0.2});
}

function startTimer(element, remaining)
{
	var count = remaining;
	var seconds = count % 60;
	count = (count - seconds) / 60;
	var minutes = count % 60;
	count = (count - minutes) / 60;
	var hours = count % 24;
	var days = (count - hours) / 24;
	if (days > 9) {$('td1').className = 'd d' + Math.floor(days / 10);}
	else {$('td1').className = 'd dN';}
	$('td2').className = 'd d' + (days % 10);
	$('th1').className = 'd d' + Math.floor(hours / 10);
	$('th2').className = 'd d' + (hours % 10);
	$('tm1').className = 'd d' + Math.floor(minutes / 10);
	$('tm2').className = 'd d' + (minutes % 10);
	$('ts1').className = 'd d' + Math.floor(seconds / 10);
	$('ts2').className = 'd d' + (seconds % 10);
	if (remaining > 0) {
		var func = 'startTimer(\'' + element + '\', ' + (remaining - 1) + ');';
		setTimeout(func, 999);
	}
}

function force_int(text_field_obj){
	if(text_field_obj && text_field_obj.value){
		new_val = text_field_obj.value.replace(/[^0-9]*(\d*).*/,'$1');
		text_field_obj.value = new_val;
	}
}

function collapseTwisty(effect, twisty) {
	twisty = (twisty == null) ? $(effect.element.twisty) : $(twisty);
	twisty.addClassName('twisty-collapsed');
	twisty.innerHTML = '<span>expand</span>';
}

function expandTwisty(effect, twisty) {
	twisty = (twisty == null) ? $(effect.element.twisty) : $(twisty);
	twisty.removeClassName('twisty-collapsed');
	twisty.innerHTML = '<span>collapse</span>';
}

function toggleTwistyBox(boxid, animate)
{
	var box = $(boxid)
	if (animate == null) {animate = true;}
	box.twisty = boxid + "_twisty"
	if (box.visible()) {
		if (animate) {
			Effect.BlindUp(box, {duration:0.15, afterFinish:collapseTwisty});
		} else {
			box.hide(); collapseTwisty(null, box.twisty);
		}
	} else {
		if (animate) {
			Effect.BlindDown(box, {duration:0.15, afterFinish:expandTwisty});
		} else {
			box.show(); expandTwisty(null, box.twisty);
		}
	}
}

function safeSend(daid, cmd, newEj)
{
	ext = newEj ? '_flv_' : '_flv';
	try {eval(daid + ext + 'sendEvent(\'' + cmd + '\');');}
	catch (e) {}
}

function toggleEJ(boxid, newEj)
{
	var box = $(boxid);
	var col = $('ej_collapsed');
	var exp = $('ej_expanded');
	if (newEj == null) {newEj = false;}
	if (col.visible()) {
		col.hide();
		exp.show();
		box.addClassName('expanded');
		setTimeout("safeSend('" + boxid + "', 'startplay', " + newEj + ");", 250);
	} else {
		var booth = $('ej_booth');
		var links = $('ej_links');
		eval("safeSend('" + boxid + "', 'stopplay', " + newEj + ");");
		hideEJDrawer();
		exp.hide();
		col.show();
		box.removeClassName('expanded');
	}
}

function toggleEJMenu()
{
	try {
		var menu = $('ej_menu');
		var overlay = $('ej_menu_overlay');
		if (!menu.visible()) {
			var page = $('os-page')
			var button = $('ej_menu_button');
			var pos = getPos(button, page);
			var bsz = getSize(button);
			var msz = getSize(menu);
			var osz = getSize(page);
			pos[0] -= msz[0] - bsz[0];
			pos[1] += bsz[1];
			overlay.style.position = 'absolute';
			overlay.style.left = '0px';
			overlay.style.top = '0px';
			overlay.style.width = osz[0] + 'px';
			overlay.style.height = osz[1] + 'px';
			menu.style.position = 'absolute';
			menu.style.left = pos[0] + 'px';
			menu.style.top = pos[1] + 'px';
			overlay.show();
			menu.show();
		} else {
			menu.hide();
			overlay.hide();
		}
	} catch(e) {}
}

function hideEJDrawer()
{
	var dis = $('ej_links');
	var dislink = $('ej_links_tab');
	var dat = $('ej_booth');
	var datlink = $('ej_booth_tab');
	dis.hide();
	dislink.removeClassName('selected');
	dat.hide();
	datlink.removeClassName('selected');
}

function toggleEJDrawer(thisID, thatID)
{
	var dis = $(thisID);
	var dislink = $(thisID + "_tab");
	var dat = $(thatID);
	var datlink = $(thatID + "_tab");
	if (dis.visible())
	{
		dat.hide();
		Effect.BlindUp(dis, {duration: 0.1});
		dislink.removeClassName('selected');
		datlink.removeClassName('selected');
	}
	else if (dat.visible())
	{
		dat.hide();
		datlink.removeClassName('selected');
		dis.show();
		dislink.addClassName('selected');
	}
	else
	{
		dat.hide();
		datlink.removeClassName('selected');
		Effect.BlindDown(dis, {duration: 0.1});
		dislink.addClassName('selected');
	}
}

function updateSizeInfo(divid, target_id)
{
	 var daDiv = $(divid);
	 var sz = getSize(daDiv);
	 var html = 'Size: ' + sz[0] + 'x' + sz[1];
	 var daSpot = $(target_id);
	 daSpot.innerHTML = html;
}

function showOverlay(layer, parent, animate)
{
	var page = $('os-page');
	var overlay = $('overlay');
	layer = $(layer);
	parent = $(parent);
	var pageSize = getSize(page);
	var layerSize = getSize(layer);
	var parentPos = getPos(parent, page);
	var parentSize = getSize(parent);
	var left = parentPos[0] + Math.floor((parentSize[0] - layerSize[0]) / 2);
	var top = parentPos[1] + Math.floor((parentSize[1] - layerSize[1]) / 2);
	overlay.style.position = 'absolute';
	overlay.style.top = '0px';
	overlay.style.left = '0px';
	overlay.style.width = pageSize[0] + 'px';
	overlay.style.height = pageSize[1] + 'px';
	layer.style.position = 'absolute';
	layer.style.top = top + 'px';
	layer.style.left = left + 'px';
	if (animate == null) {animate = true;}
	if (animate) {
		Effect.Appear(overlay, {duration:0.2});
		Effect.Appear(layer, {duration:0.2});
	} else {
		overlay.show();
		layer.show();
	}
}

function hideOverlay(layer, animate)
{
	var overlay = $('overlay');
	layer = $(layer);
	if (animate == null) {animate = true;}
	if (animate) {
		Effect.Fade(layer, {duration:0.2});
		Effect.Fade(overlay, {duration:0.2});
	} else {
		layer.hide();
		overlay.hide();
	}
}

function setupDescription()
{
	var desc = $('ev_info_desc');
	var dsz = getSize(desc);
	var psz = getSize(desc.parentNode);
	if (dsz[1] > psz[1]) {
		$('ev_info_box').isExpanded = false;
		$('ev_toggle_link').show();
	}
}

function moveTab(effect)
{
	var desc = $('ev_info_desc').parentNode;
	var link = $('ev_toggle_link');
	var info = $('ev_info_box');
	var p = getPos(desc, info);
	var s = getSize(desc);
	var y = p[1] + s[1] - 1;
	link.style.top = y + 'px';
}

function toggleDescription()
{
	var info = $('ev_info_box');
	var link = $('ev_toggle_link');
	var desc = $('ev_info_desc').parentNode;
	var exp = info.isExpanded;
	var pct = 314;
	if (exp == null) {exp = false;}
	if (exp) {
		new Effect.Scale(desc, 100, {scaleX:false, scaleContent:false, scaleMode:{originalHeight:85}, scaleFrom:pct, duration:0.2, afterUpdate:moveTab});
		info.removeClassName('expanded');
		info.isExpanded = false;
		link.innerHTML = '<span>expand</span>';
	} else {
		new Effect.Scale(desc, pct, {scaleX:false, scaleContent:false, scaleMode:{originalHeight:85}, scaleFrom:100, duration:0.2, afterUpdate:moveTab});
		info.addClassName('expanded');
		info.isExpanded = true;
		link.innerHTML = '<span>collapse</span>';
	}
}

function toolbarMouseOver(base_id, tooltip_class) {
	var tt = $(base_id + '-tip');
	tt.addClassName(tooltip_class);
	tt.show();
}

function toolbarMouseOut(base_id, tooltip_class) {
	var tt = $(base_id + '-tip');
	tt.removeClassName(tooltip_class);
	tt.hide();
}

function updateSelectContestHeight()
{
	var ls = getSize($('left-col'));
	var ms = getSize($('mid-col'));
	var rs = getSize($('right-col'));
	var h = ls[1];
	if (ms[1] > h) {h = ms[1];}
	if (rs[1] > h) {h = rs[1];}
	$('wrapper').style.height = h + 'px';
}

function thanksForJudging()
{
	 $("judgethanks").show();
	 setTimeout("Effect.Fade($('judgethanks'), {duration:1})", 1000);
}

function enableJudgeBar() {
	if (++document.playerReadyCount == 2) {		
		$$(".rb").invoke('enable');
	}
}

function disableJudgeBar() {
	document.playerReadyCount = 0;
	$$(".rb").invoke('disable');
}

function good_to_go(view_verb, item_term, item_terms, view_time_left_str, view_time_right_str)
{
	var		left_ok = leftwatched_long_enough();
	var		right_ok = rightwatched_long_enough();
	var		good_to_go = false;
	var		checked = false;

	leftsendEvent('pause');
	rightsendEvent('pause');

	$$(".rb").each(function(value, index) {if (value.checked) checked = true;});

	if (!checked)
	{
		alert("Please use the judging buttons to compare the two " + item_terms);
		return false;
	}

	if (!left_ok && !right_ok)
		alert("You must "+view_verb+" each "+item_term+" before judging them");
	else if (!left_ok)
		alert("You must "+view_verb+" the "+item_term+" on the left for at least "+view_time_left_str);
	else if (!right_ok)
		alert("You must "+view_verb+" the "+item_term+" on the right for at least "+view_time_right_str);
	else
		good_to_go = true;

	if (good_to_go)
	{
		if ($("judgethanks"))
			Effect.Appear($('judgethanks'), {duration:0.25});
	}
	else
		$$(".rb").each(function(value, index) {if (value.checked) value.checked = false;});

	return good_to_go;
}

function updateErrorField(elt)
{
	var par = null;
	try{par = firstAncestorOfClass(elt, 'field');}catch(e){}
	try{if (par == null) {par = firstAncestorOfClass(elt, 'checkbox');}}catch(e){}
	try{if (par == null) {par = firstAncestorOfClass(elt, 'buttons');}}catch(e){}
	try{if (par == null) {par = firstAncestorOfClass(elt, 'captcha');}}catch(e){}
	if (par != null) {
		par.addClassName("errorField");
	}
}

function updateFieldErrors()
{
	$$(".fieldWithErrors").each(updateErrorField);
}

/* Checks for too much text in a text AREA (text fields have built in checks)
	returns an array containing a boolean and a string: [success,message]
	The message is only really informative under error conditions (success == false)
*/
function check_text_area_size( text_box, maxchars, show_alert, display_name)
{
	if(text_box.value.length > maxchars)
	{
		msg = 'Too much data in the ' + display_name + ' text box! Please remove '+(text_box.value.length - maxchars)+ ' characters';
		if (show_alert)
			alert(msg);
		return [false,msg];
	}
	else
		return [true,'OK'];
}

function faq_goto(faqtag)
{
	try {$(faqtag).visualEffect('pulsate', {pulses: 3, duration: 1.0, from: 0.5});} 
	catch (e) {}
	return true;
}

function toggle_tab() {
	//placing these inline caused an error in Firefox so here is a function wrapper for it.
	Element.toggle('appstate_help');
	Element.toggle('appstate_tab');
}

function showit(elementid, duration, delay) {
	var duration = (duration == null) ? 0.25 : duration;
	var delay = (delay == null) ? 0 : delay;	
	Effect.Appear($(elementid), {duration:duration, delay:delay}); 
}

function hideit(elementid, duration, delay) {
	var duration = (duration == null) ? 0.25 : duration;
	var delay = (delay == null) ? 0 : delay;	
	Effect.Fade($(elementid), {duration:duration, delay:delay}); 
}

function fbs_open(u) {
	var t = 'OurStage';
	var p = 'http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t);
	window.open(p,'sharer','toolbar=0,status=0,width=626,height=436');
}

var reloadOpener = function() {
	try {window.opener.location.reload(false);}
	catch (e) {}
}
