// $Id: kinshipdogs.js,v 1.4 2006/12/13 02:19:51 ejd Exp $

var lastclick = 0;
function do_nothing() { return; }

ie4 = (document.all)? true:false;

var isIE = (typeof(document.documentElement) != 'undefined');
var isNS = (typeof(window.scrollX) != 'undefined');

var MRPath = window.MRPath || {};

var onload_functions = new Array;

function add_window_onload(function_call) {
	if (window.onload !== mrwindow_onload) {
		if (typeof(window.onload) === 'function')
			onload_functions[onload_functions.length] = window.onload;
		window.onload = mrwindow_onload;
	}
	onload_functions[onload_functions.length] = function_call;
}

function mrwindow_onload() {
	for (var i=0; i < onload_functions.length; i++) {
		onload_functions[i]();
	}
}

function confirm_url_change(url,msg) {
	if (confirm(msg))	
		window.location.href = url;
	else
		return;
}

var MR_alert_mappings = [];
var MR_alert_last_div = -1;
var MR_debugNames = [];

function MR_debug(debugName, _message) {
	var i;
	var oDebugInfo = null;
	var message = '' + _message;
	for (i = MR_debugNames.length - 1; i >= 0 && oDebugInfo === null; --i) {
		if (MR_debugNames[i].name === debugName) oDebugInfo = MR_debugNames[i];
	}
	if (oDebugInfo === null) {
		MR_debugNames[MR_debugNames.length] = oDebugInfo = {
			name: debugName,
			alertId: MR_add_alert('<div style="border:1px gray solid">' + debugName + ':<br>' + message + '</div>'),
			previousDebugs: [message, '', '', '', '','','',''],
			currentDebug: message
		};
		return;
	}
	if (message === oDebugInfo.currentDebug) {
		if (oDebugInfo.currentDebug === oDebugInfo.previousDebugs[0]) {
			oDebugInfo.previousDebugs[0] += '(2)';
		}else{
			oDebugInfo.previousDebugs[0] = oDebugInfo.previousDebugs[0].replace(/\(\d+\)$/, '(' + (parseInt(oDebugInfo.previousDebugs[0].match(/\(\d+\)$/)[0].slice(1,-1)) + 1) + ')');
		}
	}else{
		for (i = oDebugInfo.previousDebugs.length - 1; i > 0; --i) {
			oDebugInfo.previousDebugs[i] = oDebugInfo.previousDebugs[i - 1];
		}
		oDebugInfo.currentDebug = oDebugInfo.previousDebugs[0] = message;
	}
	MR_change_alert(oDebugInfo.alertId, '<div style="border:1px gray solid">' + debugName + ':<br>' + oDebugInfo.previousDebugs.join('<br>').replace(/(<br>)+/,'<br>') + '</div>');
}


function MR_add_alert(message/*, alert_id*/) {
	var alert_id;
	var div_id;
	if (MR_add_alert.arguments.length > 1) {
		alert_id = MR_add_alert.arguments[1];
		div_id = MR_alert_mappings[alert_id];
		if (div_id == -1) div_id = ++MR_alert_last_div;
	}else{
		alert_id = MR_alert_mappings.length;
		div_id = ++MR_alert_last_div;
	}
	var MR_alerts_div = document.getElementById('MR_alerts');
	if (!MR_alerts_div) {
		MR_alerts_div = document.createElement('div');
		MR_alerts_div.id = 'MR_alerts';
		document.body.appendChild(MR_alerts_div);
	}else if (div_id == 0) {
		MR_alerts_div.style.display = '';
	}
	if (!MR_alerts_div) {
		alert(message);
	}
	
	var div = document.getElementById('MR_alert' + div_id);
	if (!div) {
		MR_alerts_div.innerHTML += '<div class="MR_alert" onclick="MR_remove_alert(' + alert_id + ')" id="MR_alert' + div_id + '">' + message + '</div>';
		div = document.getElementById('MR_alert' + div_id);
	}else{
		div.innerHTML = message;
		div.setAttribute('onclick', 'MR_remove_alert(' + alert_id + ')');
		if (div.style.display == 'none') div.style.display = '';
	}
	MR_alert_mappings[alert_id] = div_id;
	return alert_id;
}

function MR_change_alert(alert_id, message) {
	if (alert_id < 0 || alert_id >= MR_alert_mappings.length) return;
	var div_id = MR_alert_mappings[alert_id];
	if (div_id == -1) {
		MR_add_alert(message, alert_id);
	}else{
		document.getElementById('MR_alert' + div_id).innerHTML = message;
	}
}

function MR_remove_alert(alert_id) {
	if (alert_id < 0 || alert_id >= MR_alert_mappings.length) return;
	if (MR_alert_mappings[alert_id] == -1) return;
	document.getElementById('MR_alert' + MR_alert_mappings[alert_id]).style.display = 'none';
	MR_alert_mappings[alert_id] = -1;

	while (MR_alert_last_div >= 0) {
		if (document.getElementById('MR_alert' + MR_alert_last_div).style.display == 'none') {
			MR_alert_last_div--;
		}else{
			break;
		}
	}
	if (MR_alert_last_div == -1) {
		document.getElementById('MR_alerts').style.display = 'none';
	}
}

var toggling_all = false;

function toggle(toggleId, e, skip_cookies, page_to_get_data)
{
	if (!document.all){
		//not IE, so doubleclicks are messed up differently...
		var d = new Date();
		if (d.getTime() - lastclick < 250) {
			//if the last click wasn't more than 250 ms ago, don't handle it...
			lastclick = d.getTime();
			return;
		}
		lastclick = d.getTime();
	} 

	if (!e) {e = window.event;}
	if (!document.getElementById) {return false;}
	
	var toggles = toggleId.split(',');
	var body, im;
	for (var i = 0; i < toggles.length; i++) {
		if (body = document.getElementById(toggles[i])) {
			if (body.innerHTML.match(/Loading\.\.\.$/) && page_to_get_data)
				load_subtable(page_to_get_data);
			im = toggles[i] + "_toggle";
			if (body.style.display == 'none') {
				body.style.display = '';
				if (document.images[im]) {document.images[im].src = "/voxbase/images/close.gif";}
				set_toggle_cookie(toggles[i], '', skip_cookies);
			} else {
				body.style.display = 'none';
				if (document.images[im]) {document.images[im].src = "/voxbase/images/open.gif";}
				set_toggle_cookie(toggles[i], 'none', skip_cookies);
			}
		}
	}
	if (cancel_click) cancel_click(e);
	if (hide_popup) hide_popup();
	if (resizeVoxport) resizeVoxport();
}

function toggle_all(toggleId, e, skip_cookies)
{
	var last_click = lastclick;
	toggling_all = true;
	if (!e) {e = window.event;}
	if (!document.getElementById) {return false;}
	var body = document.getElementById(toggleId);
	if (!body) {return false;}
	toggle_children(toggleId, body.childNodes, body.style.display, skip_cookies);

	if (e) {e.cancelBubble = true;
		if (e.stopPropagation) {e.stopPropagation();}
	}
	lastclick = last_click;
	resizeVoxport();
}

function toggle_all_children(toggleId, toggleBaseId, e, skip_cookies)
{
	if (!e) {e = window.event;}
	if (!document.getElementById) {return false;}
	var body = document.getElementById(toggleId);
	if (!body) {return false;}
	toggle_children(toggleBaseId, body.childNodes, body.style.display, skip_cookies);

	if (e) {e.cancelBubble = true;
		if (e.stopPropagation) {e.stopPropagation();}
	}
}

function toggle_children(toggleId, kids, state, skip_cookies) {
	var t;
	for (var i = 0; i < kids.length; i++) {
		if ((t = "" + kids[i].onclick)
		  // find the toggle id from the onclick
		  && (t = t.match(/toggle\([\"\'](\w*)[\"\']/))
		  //make sure it's not the parent toggle
		  && (t[1] != toggleId)
		  //make sure it's a child of the parent
		  && (t[1].indexOf(toggleId) == 0)//
		  //get the element to be toggled and see if it needs toggling
		  && (t = document.getElementById(t[1]))
		  && (t.style.display != state)
		) {
			//override the doubleclick timer (this should be reset by toggle_all)
			lastclick = 0;
			kids[i].onclick();
		}
		toggle_children(toggleId, kids[i].childNodes, state, skip_cookies);
	}
}

function set_toggle_cookie(id, state, skip_cookies) {
	if (skip_cookies) return;
	if (typeof(cookie_version) != 'undefined') {
		if (state == 'none')
			remove_column_filter('_',id.slice(1));
		else
			add_column_filter('_',id.slice(1));
		return;
	}
	
	var cookie = window.location.pathname;
	if (cookie.slice(-1) == '/' || cookie == '') {
		cookie = 'index';
	}else{
		cookie = cookie.substring(cookie.lastIndexOf('/')+1).replace(/\.php/,'');
	}
	var cookie_value = get_cookie(cookie);
	var expires = new Date()
	expires = new Date(expires.getTime() + 2592000000 /*30 days*/);
	if (cookie_value == null) {
		if (state != 'none') {
			unset_cookie(cookie);
			set_cookie(cookie, id,expires, '/');
		}
	} else {
		cookie_value = ',' + cookie_value + ',';
		if ((ix = cookie_value.indexOf(',' + id + ',')) == -1) { //cookie entry not found
			if (state != 'none') {//cookie entry needed
				unset_cookie(cookie);
				set_cookie(cookie, cookie_value.slice(1) + id,expires, '/');
			}
		} else { //cookie entry found
			if (state == 'none') {//cookie entry needs removing
				cookie_value = cookie_value.substr(0,ix) + cookie_value.substr(ix + id.length + 1);
				if (cookie_value == ',') {
					unset_cookie(cookie);
					unset_cookie(cookie, '/');
				}else {
					unset_cookie(cookie);
					set_cookie(cookie, cookie_value.slice(1,-1),expires, '/');
				}
			}
		}
	}
}

function hide_elements(element_ids) {
	//element_ids is a comma separated string of ids
	var elements = element_ids.split(',');
	var e;
	for (var i = 0; i < elements.length; i++) {
		e = document.getElementById(elements[i]);
		if (e) e.style.display = 'none';
	}
}

function getEventTarget(e) {
	if (e.target) return e.target;
	if (e.srcElement) return e.srcElement;
	return null;
}

// Cookie functions

function show_cookies(){
	var output = '';
	var cookieval = '';
	var mode = 0;
	for (var i=0;i < document.cookie.length; i++){
		if (mode == 0){
			if (document.cookie.substring(i,i+1) == '=')
				mode = 1;
			output += document.cookie.substring(i,i+1);
		}else{
			if (document.cookie.substring(i,i+1) == ';') {
				i++;
				output += unescape(cookieval) + "\n";
				cookieval = '';
				mode = 0;
			}else{
				cookieval += document.cookie.substring(i,i+1);
			}
		}
	}
	if (cookieval != '')
		output += unescape(cookieval);
	alert(output);
}

function set_subcookie(name, subname, value, expires, path, domain, secure){
	var cookie = get_cookie(name);
	if (!cookie) cookie = '';
	var subCookies = cookie.split(':');
	var _value = (value === null ? '' : escape(value));
	for (var i = 0; i < subCookies.length; i++) {
		if (subCookies[i].substring(0,subname.length+1) == subname + '=') {
			subCookies[i] = (_value == '' ? '' : subname + '=' + _value);
			i = subCookies.length;
		}
	}
	if (i == subCookies.length && _value !== '') {
		subCookies[subCookies.length] = subname + '=' + _value;
	}
	unset_cookie(name);
	set_cookie(name, subCookies.join(':').replace(/::/,':').replace(/^:|:$/,''), expires, path, domain, secure);
}

function get_subcookie(name, subname) {
	var cookie = get_cookie(name);
	if (cookie == null) return null;
	var subCookiePos = cookie.indexOf(':'+subname+'=');
	if (subCookiePos == -1 && subname+'=' != cookie.substring(0,subname.length+1)) return null;
	var valueStart = subCookiePos + subname.length + 2;
	var valueEnd = cookie.indexOf(':', valueStart);
	if (valueEnd == -1) valueEnd = cookie.length;
	return unescape(cookie.substring(valueStart, valueEnd));
}

function set_cookie(name, value, expires, path, domain, secure){
	document.cookie = name + '=' +
	  escape(value) +
	  ((expires) ? ';expires=' + expires.toGMTString() : '') +
	  ((path) ? ';path=' + path : '') +
	  ((domain) ? ';domain=' + domain : '') +
	  ((secure) ? ';secure' : '');
}

function get_cookie(name) {
	var cookiePos = document.cookie.indexOf('; '+name+"=");
	if (cookiePos == -1 && (name+'=' == document.cookie.substring(0,name.length+1))) {cookiePos = -2;}
	if (cookiePos == -1) {return null;}

	var valueStart = cookiePos + name.length + 3;
	var valueEnd = document.cookie.indexOf(';',valueStart);
	if (valueEnd == -1) {valueEnd = document.cookie.length;}
	return unescape(document.cookie.substring(valueStart, valueEnd));
}

function unset_cookie(name, path, domain) {
	if (get_cookie(name))
		document.cookie = name + '=' + 
		  ((path) ? ';path=' + path : '') +
		  ((domain) ? ';domain=' + domain : '') +
		  ';expires=Thu, 01 Jan 1976 00:00:01 GMT;';
}

// Arbitrary voxport specific functions

function add_attachment(studyid) {
	var w = window.open(
	  'upload_attachment.php?studyid='+studyid+'&popup=1',
	  'add_attachment',
	  'toolbar=no,menubar=no,width=350,height=150,resizable=yes'
	);
	w.focus();
}

function edit_attachment(studyid,id) {
	var w = window.open(
	  'edit_attachment.php?studyid='+studyid+'&popup=1&attachmentid='+id,
	  'edit_attachment',
	  'toolbar=no,menubar=no,width=450,height=300,resizable=yes'
	);
	w.focus();
}
//TODO want to try to get current Voxport size and then match its height.
//window.outerHeight?
function help_popup(url) {
	var w = window.open(
		url,
		'help_popup',
		'toolbar=no,menubar=no,scrollbars=yes,width=540,height=600,resizable=yes'
	);
	w.focus();
}

function cancel_click(e) {
	if (!(e) && ie4) e = event;
	if (e) {
		e.cancelBubble = true;
		if (e.stopPropagation) {e.stopPropagation();}
	}
}

// Debuggin' functions

var log_pre;
var log_window;

function log(data_) {
	var data = "" + data_;
	if (typeof(debug) == 'undefined' || !debug) return;
	if (ie4 || 1){
		if (log_window && !log_pre) {
			log_pre = log_window.document.getElementById('logs');
		}
		if (!log_pre || !log_window) {
			if (ie4 || typeof(log_window) == 'undefined') {
				log_window = window.open("about:blank","logger",'resizable=yes,scrollbars=yes');
			}/* else {
				x = w;
			}*/
			log_window.document.open();
			log_window.document.write('<html><head><title>voxport log window</title><link href="http://mr_an'
			  +'imal/voxbase/visiblemouse.css" rel="stylesheet" type="text/css"><link href="http://'
			  +'mr_animal/voxbase/debugger.css" rel="stylesheet" type="text/css"></head><body><styl'
			  +'e>img {border: none}</style><div style="font-size: x-small" id=logs>'
			  +'<table class=datagrid><tr><td>' + data.replace(/\x0D|\x0A/g,'<br />') + '</td></tr></table>'
			  +'<table class=datagrid width=100%><tr><th>Javascript Debug Window</th></tr></table><'
			  +'/div></body></html>');
			log_window.document.close();
			log_window.encode26 = window.encode26;
			log_window.do_nothing = window.do_nothing;
			log_pre = log_window.document.getElementById('logs');
		}else{
			log_pre.innerHTML = '<table class=datagrid><tr><td>' + data.replace(/\x0D|\x0A/g,'<br />') + '</td></tr></table>' + log_pre.innerHTML;
		}
	} else {
		window.status = data;
	}
}

MRPath.print_s_toggle_id = 0;

function logvar(_var) {
	log(MRPath.print_s(_var));
}

MRPath.print_s = function (_var/*, recurse_depth=0, recursed = false, color=true, toggles=true*/) {
	var recursed = false;
	var recurse_depth = 0;
	var color = true;
	var toggles = true;
	if (typeof(debug) == 'undefined') return;
	if (MRPath.print_s.arguments.length > 1)
		recurse_depth = MRPath.print_s.arguments[1];
	if (recurse_depth > 3) return '<font color=red>Recursed too deep</font>';
	if (MRPath.print_s.arguments.length > 2)
		recursed = MRPath.print_s.arguments[2];
	if (MRPath.print_s.arguments.length > 3)
		color = MRPath.print_s.arguments[3];
	if (MRPath.print_s.arguments.length > 4)
		toggles = MRPath.print_s.arguments[4];
	var b = '';
	var c;
	switch (typeof(_var)) {
		case 'string':
			b += color ? '<font class=s>' + _var.replace(/\</g,'&lt;') + '</font>' : _var.replace(/\</g,'&lt;');
			break;
		case 'number':
			b += color ? '<font class=i>' + _var + '</font>' : _var;
			break;
		case 'object':
			if (_var === null) { b += '<font class=n>null</font>'; break;
			}else if (_var.constructor == Array) {
				if (_var.length == 0) {
					b += 'Array()';
					break;
				}
				b += 'Array<ul>';
				for (c = 0; c < _var.length; c++) {
					b += '[' + c + '] = ' + MRPath.print_s(_var[c],recurse_depth+1,true, color, toggles) + '<br>';
				}
				b += '</ul>';
				break;
			}else if (_var.constructor == Boolean) { b += color ? '<font class=b>'+(_var ? 'true' : 'false')+'</font>' : (_var ? 'true' : 'false'); break;
			}else if (_var.constructor == Date) { b += 'Date (' + _var + ')'; break;
			}else if (_var.constructor == Error) { b += 'Error (' + _var + ')'; break;
			}else if (_var.constructor == Number) { b += color ? '<font class=i>' + _var + '</font>' : _var; break;
			}else if (_var.constructor == String) { b += color ? '<font class=s>' + _var.replace(/\</g,'&lt;') + '</font>' : _var.replace(/\</g,'&lt;'); break;
			}
			if (toggles) {
				b += 'object (' + _var + ')'
				 + '<a href="javascript:do_nothing()" onclick="document.getElementById(\'Tlv_' + encode26(MRPath.print_s_toggle_id) + '\').style.display = (document.getElementById(\'Tlv_' + encode26(MRPath.print_s_toggle_id) + '\').style.display == \'none\' ? \'\' : \'none\');document.images[\'Tlv_' + encode26(MRPath.print_s_toggle_id) + '_\'].src = \'/voxbase/images/\'+(document.getElementById(\'Tlv_' + encode26(MRPath.print_s_toggle_id) + '\').style.display==\'none\'?\'open\':\'close\')+\'.gif\';"><img src="/voxbase/images/open.gif" id="Tlv_' + encode26(MRPath.print_s_toggle_id) + '_"></a>'
				 + '<div id="Tlv_' + encode26(MRPath.print_s_toggle_id++) + '" style="display:none"><ul>';
			}else{
				b += 'object (' + _var + ')<ul>';
			}
			for (c in _var) {
				if (c === 'parentNode'
				  || c === 'ownerDocument'
				  || c === 'previousSibling'
				  || c === 'nextSibling'
				  || c === 'offsetParent'
				  || c === 'document'
				  || c === 'parentElement'
				  || c === 'parentTextEdit'
				) {
					b += '.' + c + (color ? ' = (<font color=red>skipped</font>)<br>' : ' = (skipped)<br>');
					continue;
				}
				try{
					b += '.' + c + ' = ' + MRPath.print_s(eval('_var.'+c),recurse_depth+1,true, color, toggles) + '<br>';
				}catch(e) {
					b += '.' + c + ' = ' + (color ? '<font class=e>Error</font>' : 'Error') + '<br>';
				}
			}
			b += '</ul>';
			if (toggles) b+= '</div>';
			break;
		case 'boolean':
			b += color ? '<font class=b>'+(_var ? 'true' : 'false')+'</font>' : (_var ? 'true' : 'false');
			break;
		case 'function':
			b = color ? '<font class=f>' + _var.toString() + '</font>()' : _var.toString();
			break
		case 'undefined':
			b += color ? '<font color=red>undefined</font>' : 'undefined';
			break;
	}
	return b;
}

MRPath.print_r = function (_var) {
	return MRPath.print_s(_var, 0, false, true, false);
}

function decompress(str,tokens) {
	var token_array = tokens.split('~');
	for (var i = token_array.length-1; i >= 0 ; i--) {
		str = str.replace(eval('/~'+i+'/g'),token_array[i]);
	}
	return str.replace(/~r/g,'~');
}

//  Delayed loading functions

var subtable_queue = new Array;
var subtable_last_load = new Date(0);

function load_subtable(page_/*, cut_in_line*/) {
	//subtable_queue[0] always holds the currently loading subtable.  Don't cut in front of it or you won't be loaded.
	var cut_in_line = false;
	if (load_subtable.arguments.length > 1)
		cut_in_line = load_subtable.arguments[1];

	var page = page_ + ((toggling_all && page_ != '') ? '&toggle_all=1' : '');
	var starting_queue_length = subtable_queue.length;
	var i;
	if (page != ''){
		if (starting_queue_length > 0
		  && page == subtable_queue[0]
		  && new Date() - subtable_last_load > 5000) {
			//if the requested page is currently loading and hasn't responded within 5 seconds
			load_hidden_iframe(page);
		}else if (starting_queue_length > 0
		  && new Date() - subtable_last_load > 10000){
			//if the currently loading page hasn't responded within 15 seconds
			//kick it to the end of the queue and start the requested page
			subtable_queue[subtable_queue.length] = subtable_queue[0];
			subtable_queue[0] = page;
			load_hidden_iframe(page);
		}else if (cut_in_line && starting_queue_length > 1
		  && subtable_queue.splice) {
			subtable_queue.splice(1,0,page);
			for (i = 2; i < subtable_queue.length; i++) {
				if (subtable_queue[i] == page) {
					subtable_queue.splice(i,1);
					return;
				}
			}
		}else{
			for (i = 0; i < subtable_queue.length; i++) {
				if (subtable_queue[i] == page)
					return;
			}
			subtable_queue[subtable_queue.length] = page;
		}
	}
	if (starting_queue_length == 0 && page != '') {
		load_hidden_iframe(page);
	} else if (starting_queue_length > 0 && page == '') {
		load_hidden_iframe(subtable_queue[0]);
	} else if (page == '' && subtable_queue.length == 0) {
		toggling_all = false;
		mask_links();
	}
}

function load_hidden_iframe(page){
		var i = document.getElementById('lsif');
		if (!i) {
			hidden_popup_window(null, '<iframe id="lsif" scrolling="no"></iframe>');
			i = document.getElementById('lsif');
		}
		i.src = page;
		subtable_last_load = new Date();
}

function subtable_loaded(subtable_id, guts) {
	var e = document.getElementById('T'+subtable_id);
	if (e)
		e.innerHTML = guts;
	subtable_queue = subtable_queue.slice(1);
	load_subtable('');
	resizeVoxport();
}

function popup_window(e, guts) {
	var p;
	p = hidden_popup_window(e, guts);
	p.style.visibility = '';
	skip_hide = true;
	return p;
}

function hidden_popup_window(e, guts) {
	var table_id;
	document.onclick = hide_popup;
	if (!(popup = document.getElementById('filter_popup'))) {
		if (ie4) {
			document.body.insertAdjacentHTML('beforeEnd','<div class="popup" id="filter_popup"></div>');
		}
		else {
			el = document.createElement('div');
			el.setAttribute('class','popup');
			el.setAttribute('id','filter_popup');
			document.body.appendChild(el);
		}
		popup = document.getElementById('filter_popup');
		popup.onclick = cancel_click;
		popup.onmousedown = filter_window_event;
	}
	if (e && ie4) {
		popup.style.posLeft = e.x;
		popup.style.posTop = e.y;
	} else if (e) {
		popup.style.left = e.pageX;
		popup.style.top = e.pageY;
	}
	popup.innerHTML = guts;
	return popup;
}

var skip_hide;

function hide_popup(e) {
	if (skip_hide) {
		skip_hide = false;
		return;
	}
	var w;
	if (w = document.getElementById('filter_popup')) {
		w.style.visibility = 'hidden';
	}
}

function filter_window_event(e) {
	if (!(e) && ie4) e = event;
	if (e) {
		if (dragging) {
			if (e.type == 'mouseout') drag_mode(false);
			else if (e.type == 'mouseup') drag_mode(false);
			else if (e.type == 'click') { drag_mode(false); cancel_click(e); }
			else if (e.type == 'mousemove') {
				var popup;
				if (!(popup = document.getElementById('filter_popup'))) return;
				if (ie4) {
					if (e.x - drag_last_x) popup.style.left = (parseInt(popup.style.left.slice(0,-2)) + e.x - drag_last_x) + 'px';
					if (e.y - drag_last_y) popup.style.top = (parseInt(popup.style.top.slice(0,-2)) + e.y - drag_last_y) + 'px';
					drag_last_x = e.x;
					drag_last_y = e.y;
				} else {
					if (e.pageX - drag_last_x) popup.style.left = (parseInt(popup.style.left.slice(0,-2)) + e.pageX - drag_last_x) + 'px';
					if (e.pageY - drag_last_y) popup.style.top = (parseInt(popup.style.top.slice(0,-2)) + e.pageY - drag_last_y) + 'px';
					drag_last_x = e.pageX;
					drag_last_y = e.pageY;
				}
				cancel_click(e);
			}
		}else{
			if (e.type == 'mousedown') {
				if (ie4 && e.button != 1) return;
				if (!ie4 && e.button != 0) return;
				if (ie4 && e.srcElement.nodeName == 'A') return;
				if (ie4 && e.srcElement.nodeName == 'INPUT' && e.srcElement.type == 'text') return;
				if (!ie4 && e.explicitOriginalTarget.parentNode && e.explicitOriginalTarget.parentNode.localName == 'A') return;
				if (!ie4 && e.explicitOriginalTarget.localName == 'INPUT' && e.explicitOriginalTarget.type == 'text') return;
				drag_mode(true);
				if (ie4) {
					drag_last_x = e.x;
					drag_last_y = e.y;
				} else {
					drag_last_x = e.pageX;
					drag_last_y = e.pageY;
				}
			}
		}
	}
}

function mask_links() {
	var tags = document.getElementsByTagName('a');
	var tag;
	for (var i=0; i < tags.length; i++) {
		tag = tags[i];
		if (tag.onmouseover !== mask_mouseover && 
		  (/javascript\:do_nothing()\;?/.test(tag.href) || tag.title)) {
			tag.onmouseover = mask_mouseover;
			tag.onmouseout = mask_mouseout;
		}
	}
}

add_window_onload(mask_links);

function mask_mouseover(e) {
	var s;
	if (!e && event) e = event;
	if (e && e.explicitOriginalTarget && e.explicitOriginalTarget.parentNode){
		if (e.explicitOriginalTarget.parentNode.title)
			window.status = e.explicitOriginalTarget.parentNode.title;
		else {
			s = "" + e.explicitOriginalTarget.parentNode.onclick;
			s = s.match(/[^\s].*[^\s]/g)[1];
			if (s)
				window.status = 'function:'+s;
			else
				window.status = e.explicitOriginalTarget.nodeValue;
		}
	}else if (e.srcElement.title || e.srcElement.innerHTML)
		(window.status = e.srcElement.title) || (window.status = e.srcElement.innerHTML);
	return true;
}

function mask_mouseout(e) {
	window.status = '';
}

function addEvent(event_container, event_name, func) {
	if (event_container === window && event_name === 'load') {
		add_window_onload(func);
	}else if (event_container.attachEvent) {
		event_container.attachEvent("on" + event_name, func);
	}else if (event_container.addEventListener) {
		event_container.addEventListener(event_name, func, null);
	}
}

function encode26(_in) {
	if (typeof(_in) === 'object' && _in.length > 0) {
		var sReturn = '';
		for(var i = _in.length - 1; i >= 0; --i) {
			sReturn = encode26(_in[i]) + sReturn;
		}
		return sReturn;
	}
	if (typeof(_in) != 'number') return '';
	var _int = parseInt(_in);
	if (_int < 0) return '';
	var ret = '';
	ret = String.fromCharCode(_int % 26 + 65) + ret;
	_int = Math.floor(_int / 26);
	while (_int > 0) {
		ret = String.fromCharCode(_int % 26 + 97) + ret;
		_int = Math.floor(_int / 26);
	}
	return ret;
}

function decode26(str) {
	var buffer = 0;
	var ret = new Array;
	var c;
	for (var i=0; i<str.length; i++) {
		c = str.charCodeAt(i);
		if (c >= 65 && c <= 90) {
			buffer += c - 65;
			ret[ret.length] = buffer;
			buffer = 0;
		} else if (c >= 97 && c <= 122) {
			buffer += c - 97;
			buffer *= 26;
		} else {
			ret[ret.length] = buffer;
			buffer = 0;
		}
	}
	return ret;
}

function jsStrParam(str) {
	if (str == null) return 'null';
	return '\''+str.replace(/\\/g,'\\\\').replace(/'/g,'\\\'').replace(/\n/g,'\\n')+'\'';
}

function insert_into_sorted_array(needle,haystack,allow_duplicates) {
	var start = 0;
	var end = haystack.length - 1;
	var mid;
	while (true) {
		if (start == end) {
			if (haystack[start] < needle) {
				mid = start + 1;
			}else
				mid = start;
			break;
		}
		mid = start + Math.floor((end - start) / 2);
		if (needle <= haystack[mid]){
			end = mid;
		}else
			start = mid + 1;
	}
	if (haystack[mid] == needle && !allow_duplicates)
		return haystack;
	var ret;
	if (mid > 0)
		ret = haystack.slice(0,mid);
	else
		ret = new Array;
	ret[ret.length] = needle;
	if (mid < haystack.length)
		ret = ret.concat(haystack.slice(mid));
	return ret;
}

function sorted_array_find(needle, haystack) {
	return sorted_bounded_array_find(needle, haystack, 0, haystack.length-1)
}

function sorted_bounded_array_find(needle, haystack, start, end) {
	if (start == end)
		return (needle == haystack[start] ? start : -1);
	if (start > end)
		return -1;
	var mid_key = start + Math.floor((end - start) / 2);
	if (needle == haystack[mid_key])
		return mid_key;
	if (needle > haystack[mid_key])
		return sorted_bounded_array_find(needle, haystack, mid_key+1, end);
	return sorted_bounded_array_find(needle, haystack, start, mid_key-1);
}

function coalesce() {
	for (var i = 0; i < coalesce.arguments.length; i++) {
		if (coalesce.arguments[i] != null)
			return coalesce.arguments[i];
	}
	return null;
}

function load_page(page) {
	window.location.replace(page);
}

//These store the cache of found style sheet rules
var classStyles = new Array;
var classStylesIndex = new Array;

function getClassStyle(_className) {
	var i, j, sheet;
	for (i = 0; i < classStylesIndex; i++) {
		//Check the cache first.
		if (classStylesIndex[i] === _className) return classStyles[i];
	}
	if (navigator.appVersion.indexOf('Safari') !== -1 && _className.indexOf('#') !== -1) {
		//Safari rewrites the #id style rules to be in *[ID"id"] format
		className = _className.replace(/#([a-zA-Z_0-9]*)/, '*[ID"$1"]');
	}else{
		className = _className;
	}
	for (i = document.styleSheets.length - 1; i >= 0; i--) {
		sheet = document.styleSheets[i];
		if (sheet.rules) { // ie
			for (j=0; j < sheet.rules.length; j++) {
				if (sheet.rules[j].selectorText.toLowerCase() === className.toLowerCase()) {
					classStylesIndex[classStyles.length] = className;
					classStyles[classStyles.length] = sheet.rules[j].style;
					return sheet.rules[j].style;
			}	}
		}else if (sheet.cssRules) { //moz
			for (j=0; j < sheet.cssRules.length; j++) {
				if (sheet.cssRules[j].selectorText === className) {
					classStylesIndex[classStyles.length] = className;
					classStyles[classStyles.length] = sheet.cssRules[j].style;
					return sheet.cssRules[j].style;
	}	}	}	}
/*	//If not found
	//TODO: make it handle unfound classes in a friendly way (and that works in Safari)
	sheet = document.styleSheets[document.styleSheets.length - 1];
	if (sheet.addRule) {
	alert(className);
		sheet.addRule('TD', 'color: red;', 0);
	}else if (sheet.insertRule) {
	}*/
}

function setClassStyle(className, styleName, value) {
	var style = getClassStyle(className);
	if (!style) {
		/*alert (className)*/;
		return;
	}
	if (style.setProperty) {
		style.setProperty(styleName, value, null);
	}else{
		var styleProperty = '';
		for (var i = 0; i < styleName.length; i++) {
			if (styleName.substring(i, i + 1) === '-') {
				styleProperty += styleName.substring(i + 1, i + 2).toUpperCase();
				i ++;
			}else{
				styleProperty += styleName.substring(i, i + 1);
			}
		}
		style[styleProperty] = value;
	}
}

function setElementXY(e, xy) {
	var left;
	var top;
	if (e.offsetParent) {
		left = (xy.x !== null) ? xy.x - getElementLeft(e.offsetParent) : null;
		top = (xy.y !== null) ? xy.y - getElementTop(e.offsetParent) : null;
	}else{
		left = (xy.x !== null) ? xy.x : null;
		top = (xy.y !== null) ? xy.y : null;
	}
	if (left !== null && e.style.left != left) e.style.left = left;
	if (top !== null && e.style.top != top) e.style.top = top;
}

function getElementRight(e) {
	return getElementWidth(e) + getElementLeft(e);
}

function getElementLeft(e) {
	var left = 0;
	var _e = e;
	if (_e.offsetParent) {
		while (_e.offsetParent) {
			left += parseInt(_e.offsetLeft);
			_e = _e.offsetParent;
		}
	}else if (e.x) {
		return parseInt(e.x);
	}
	return left;
}

function getElementWidth(e) {
	return e.offsetWidth;
}

function getElementHeight(e) {
	return e.offsetHeight;
}

function getElementTop(e) {
	var top = 0;
	var _e = e;
	if (_e && _e.offsetParent) {
		while (_e.offsetParent) {
			top += parseInt(_e.offsetTop);
			_e = _e.offsetParent;
		}
	}else if (e.y) {
		return parseInt(e.y);
	}
	return top;
}

function getElementBottom(e) {
	return getElementTop(e) + getElementHeight(e);
}

function getElementRegion(e) {
	var region = {
		left: getElementLeft(e),
		top: getElementTop(e),
		width: getElementWidth(e),
		height: getElementHeight(e)
	}
	region.right = region.left + region.width - 1;
	region.bottom = region.top + region.height - 1;
	return region;
}

function getEventXY(e) {
	var event;
	if (typeof(e) !== 'undefined') {
		event = e;
	}else if(typeof(window.event) !== 'undefined') {
		event = window.event;
	}else{
		return null;
	}
	if (typeof(window.scrollX) !== 'undefined') {
		return { x : (event.clientX + window.scrollX), y: (event.clientY + window.scrollY) }
	}else if (typeof(document.body.scrollLeft) !== 'undefined') {
		return {
			x : (event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft),
			y : (event.clientY + document.documentElement.scrollTop + document.body.scrollTop)
		};
	}
	return null;
}

function resizeVoxport() {
	var width = getWindowWidth();
	var height = getWindowHeight();
	if (width && height)
		resizeVoxportSidebar(width, height);
}

function kinshipPageLoad() {
	scheduleFRM=document.getElementById('schedule');
	if (scheduleFRM) {
		scheduleFRM.src='http://www.google.com/calendar/embed?src=vcbglj64sfda3pbkl7t3gkm0os%40group.calendar.google.com&bgcolor=%23FFFFE1&height=690';
	}
	photosFRM=document.getElementById('photos');
	if (photosFRM) {
//		alert(photosFrameWidth);
//		alert(photosFrameHeight);
//		photos.width=photosFrameWidth;
//		photos.height=photosFrameHeight;	
		photosFRM.src='http://albums-test.housenet.org/voxbase/view_datasets_thumbnails.php?studyid=2&fullscreen=1';
	}
}

function getWindowWidth() {
	if (window.innerWidth) return window.innerWidth;
	if (document.body && document.body.clientWidth) return document.body.clientWidth;
	return;
}

function getWindowHeight() {
	if (window.innerHeight) return window.innerHeight;
	if (document.body && document.body.clientHeight) return document.body.clientHeight;
	return;
}
// resizing functions

var resizeVoxportSidebarLastWidth = 0;
var resizeVoxportLastWidth = 0;
var resizeVoxportSidebarLastHeight = 0;
var resizeVoxportTitleLastIndent = 100;
var photosFrameWidth = 0;
var photosFrameHeight = 0;

function resizeVoxportSidebar(windowWidth, windowHeight) {
	//get elements	
	if (!windowWidth || !windowHeight) return;
	var corner = document.getElementById('corner');
	var sidebaredge = document.getElementById('sidebaredge');
	var sidebar = document.getElementById('sidebar');
	var sidebarlinks = document.getElementById('sidebarlinks');
	var sidebargraphicend = document.getElementById('sidebargraphicend');
	var sidebargraphicbottom = document.getElementById('sidebargraphicbottom');
	var main = document.getElementById('main');
	var logo = document.getElementById('logo');
	var currentstudy = document.getElementById('currentstudy');
	var sidebarbottommark = document.getElementById('sidebarbottommark');
	var menubargraphic = document.getElementById('menubargraphic');
	var menubargraphicend = document.getElementById('menubargraphicend');
	var title = document.getElementById('title');
	var title2 = document.getElementById('title2');
	var title3 = document.getElementById('title3');
	var menubartext = document.getElementById('menubartext');
	
//	var photos = document.getElementById('photots');
	
	if (!corner || !sidebaredge || !sidebar || !sidebarlinks
	  || !sidebargraphicend || !sidebargraphicbottom || !main
	  || !logo || !sidebarbottommark || !menubargraphic
	  || !menubargraphicend || !title || !title2) return;
	// Adjust width
	// picked so initially, when the window passes 1000px wide, the sidebar takes 25%
	// of the space increase, but taking less and less as the window grows.
	var width = Math.max(1000, windowWidth - 20);
	var sidebarWidth = Math.max(125, Math.floor(200 * Math.atan(3*windowWidth / 2000) - 71));
	if (currentstudy && (getElementWidth(currentstudy) + 17 > sidebarWidth)) {
		currentstudy.style.width = 1;
		sidebarWidth = Math.max(sidebarWidth, getElementWidth(currentstudy) + 17);
	}
	if (width !== resizeVoxportLastWidth | sidebarWidth !== resizeVoxportSidebarLastWidth) {
		menubargraphic.style.width = width - 300;
		title4.style.width = width - 300 + 175;
//		head_hr.style.width = width - 300 + 175;
		var sigwidth = Math.round((width - 300 + 175) *.95);
		signature.style.width = sigwidth;
		signature.style.left = Math.round( (width - 300 + 175 - sigwidth)/2 );				
		signaturetext.style.width = width - 300 + 175 - 20;		
		signaturetext2.style.width = width - 300 + 175 - 20;				
		menubartext2.style.width = width - 300;
		main.style.width = width - 300;
//		kinshipfooter.style.width = width - 300;
		menubargraphicend.style.left = width - 100;

		menubarblock.style.left = width - 300;
//alert(menubarpic.width);				
		menubarpic.style.left = width - 200 - menubarpic.width;
		menubarblock.style.visibility = "visible";		
		menubarpic.style.visibility = "visible";		
		
				photosFrameWidth = main.style.width;
		
				
//		if (menubartext) {
//			var titleWrapIndent = Math.max(100, getElementWidth(menubartext) + 5);
//			if (resizeVoxportTitleLastIndent !== titleWrapIndent) {
//				setClassStyle('#title', 'text-indent', -titleWrapIndent);
//				setClassStyle('#title2', 'text-indent', -titleWrapIndent);
//				setClassStyle('#title3', 'text-indent', -titleWrapIndent);
//				setClassStyle('#title', 'margin-left', titleWrapIndent);
//				setClassStyle('#title2', 'margin-left', titleWrapIndent);
//				setClassStyle('#title3', 'margin-left', titleWrapIndent);
//				setClassStyle('#title', 'padding-left', titleWrapIndent);
//				setClassStyle('#title2', 'padding-left', titleWrapIndent);
//				setClassStyle('#title3', 'padding-left', titleWrapIndent);
//				title.style.left = 170 - titleWrapIndent; 
//				title2.style.left = 171 - titleWrapIndent; 
//				title3.style.left = 172 - titleWrapIndent; 
//				resizeVoxportTitleLastIndent = titleWrapIndent;
//			}
//		}else{
//			var titleWrapIndent = 100;
//		}
//		title.style.width = width - titleWrapIndent - 90 - (document.all ? 0 : 100);
//		title2.style.width = width - titleWrapIndent - 90 - (document.all ? 0 : 100);
//		title3.style.width = width - titleWrapIndent - 90 - (document.all ? 0 : 100);

		//sidebar
		corner.style.left = sidebarWidth - 125;
		sidebaredge.style.left = sidebarWidth - 16;
		sidebar.style.width = sidebarWidth;
		logo.style.left = 7 + ((sidebarWidth - 125) / 2) ;
		sidebargraphicend.style.left = sidebarWidth - 125;
		sidebargraphicbottom.style.width = sidebarWidth - 125;
		sidebarlinks.style.width = sidebarWidth - 17 - Math.min(9,Math.floor((sidebarWidth - 125) / 10));
		if (currentstudy) //currentstudy.style.width = sidebarWidth - 20;
			currentstudy.style.width = sidebarWidth - 17 - Math.min(9,Math.floor((sidebarWidth - 125) / 10))
		setClassStyle('#sidebarlinks ul ul', 'margin-left', Math.min(8,Math.max(-2, Math.floor((sidebarWidth - 133) / 4))));
		setClassStyle('#sidebarlinks ul', 'margin-left', Math.min(10,Math.max(1, Math.floor((sidebarWidth - 127) / 4))));
		main.style.left = sidebarWidth + 5;
		set_subcookie('layout', 'sw', sidebarWidth, '', '/');
		resizeVoxportLastWidth = width;
		set_subcookie('layout', 'w', width, '', '/');
	}

	// Adjust height
	var height = Math.max(windowHeight, getElementTop(sidebarbottommark) + 40); //, getElementBottom(main));
//	if (resizeVoxportSidebarLastHeight !== height) {
		var tHeight = height;
//		if (MENUBARTHIN) {
//			tHeight = height - 75;
//		}
/*
		sidebargraphicbottom.style.top = tHeight - 120;
//		kinshipfooter.style.top = tHeight - 60;
		sidebargraphicend.style.top = tHeight - 72;
		sidebar.style.height = tHeight - 72;
		sidebaredge.style.height = height - 222;
		resizeVoxportSidebarLastHeight = height;
		set_subcookie('layout', 'sh', height, '', '/');
*/

		var topMin = 500;

		sidebargraphicbottom.style.top = 	Math.max(topMin, tHeight - 420);
		sidebargraphicend.style.top = 		Math.max(topMin+48, tHeight - 372);
		sidebar.style.height = 				Math.max(topMin+48, tHeight - 372);
		sidebaredge.style.height = 			Math.max(topMin-102, height - 522);
		resizeVoxportSidebarLastHeight = height;
		set_subcookie('layout', 'sh', height, '', '/');


//		var sigTopMin = getElementBottom(main);
		var sigTopMin = Math.max(getElementBottom(sidebargraphicbottom)+20,getElementBottom(main)+20);	
		var sigTop = Math.max(height-45, sigTopMin );	
		signature.style.top = sigTop;
		signature.style.visibility = "visible";		
		signaturetext.style.top = sigTop+16;
		signaturetext.style.visibility = "visible";
		signaturetext2.style.top = sigTop+16;
		signaturetext2.style.visibility = "visible";
		
		photosFrameHeight = height - 180 - 45 - 16;

//	}
}

var mousemove_debug_alert_id = -1;
function mousemove_debug(e) {
	var text = '';
	var target;
	if (e.target) target = e.target;
	else if (e.srcElement) target = e.srcElement;
	else return;
	
	for (var i = 0; i < 30 && target.parentNode; i++) {
		text += '&lt;' + target.nodeName;
		if (target.id) text += ' id=' + target.id;
		if (target.className) text += ' class=' + target.className;
		if (target.isDragSource) text += ' isDragSource';
		if (target.isDragTarget) text += ' isDragTarget';
		text += '&gt;<br>';
		target = target.parentNode ? target.parentNode : false;
	}
	
	if (mousemove_debug_alert_id == -1) {
		mousemove_debug_alert_id = MR_add_alert(text);
	}else{
		MR_change_alert(mousemove_debug_alert_id, text);
	}
}

var show_mouse_element_stack_done = false;
function show_mouse_element_stack() {
	if (show_mouse_element_stack_done) return;
	show_mouse_element_stack_done = true;
	addEvent(document, 'mousemove', mousemove_debug);
}

addEvent(window, 'resize', resizeVoxport);
addEvent(window, 'load', resizeVoxport);
//addEvent(window, 'load', resizeVoxport);
addEvent(window, 'load', kinshipPageLoad);

MRPath.monitorStatement = function(statement, title) {
	if (typeof(MRPath.monitoredVariables) == 'undefined') {
		MRPath.monitoredVariables = [];
	}
	var monitor = { statement: statement, title: title };
	var output = '';
	try {
		output = '<ul>' + eval(statement) + '</ul>';
	}catch(err) {
		output = 'Error: ' + err.message;
	}
	monitor.alertId = MR_add_alert('<font color=red>' + title + ':</font><br>' + output);
	MRPath.monitoredVariables[MRPath.monitoredVariables.length] = monitor;
	if (typeof(MRPath.monitorVariablesInit) == 'undefined') {
		addEvent(window, 'mousemove', MRPath.monitorVariables);
		MRPath.monitorVariablesInit = 'done';
	}
}

MRPath.monitorVariable = function(variable, title) {
	if (typeof(MRPath.monitoredVariables) == 'undefined') {
		MRPath.monitoredVariables = [];
	}
	var monitor = { variable: variable, title: title };
	monitor.alertId = MR_add_alert('<font color=green>' + title + ':</font><br>' + variable.toString());
	MRPath.monitoredVariables[MRPath.monitoredVariables.length] = monitor;
	if (typeof(MRPath.monitorVariablesInit) == 'undefined') {
		addEvent(window, 'mousemove', MRPath.monitorVariables);
		MRPath.monitorVariablesInit = 'done';
	}
}

MRPath.monitorVariables = function() {
	var output;
	for (var i = MRPath.monitoredVariables.length - 1; i >= 0; i--) {
		output = '';
		if (typeof(MRPath.monitoredVariables[i].statement) != 'undefined') {
			try {
				output = '<ul>' + eval(MRPath.monitoredVariables[i].statement) + '</ul>';
			}catch(err) {
				output = 'Error: ' + err.message;
			}
		}else if (typeof(MRPath.monitoredVariables[i].variable) != 'undefined') {
			output = MRPath.monitoredVariables[i].variable.toString();
		}else{
			output = '<font color=red>Error</font>';
		}
		MR_change_alert(MRPath.monitoredVariables[i].alertId, '<font color=green>' + MRPath.monitoredVariables[i].title + ':</font><br>' + output);
	}
}

