/* $Id: menutool.js,v 1.6 2005/06/01 01:49:16 brad Exp $ */
/** begin menutool functions **/

function Rollover( base_name )
{
	this.name = base_name;
	this.image_dir = "/images";
	this.img = null;

	this.Load = doRollLoad;
	this.Over = doRollNull;
	this.Out = doRollNull;

}

function doRollNull() { ; }

function doRollLoad()
{
	this.img = new Array();
	this.img[0] = new Image();
	this.img[0].src = this.image_dir + "/" + this.name + ".gif";
	this.img[1] = new Image();
	this.img[1].src = this.image_dir + "/" + this.name + "_o.gif";
	this.Over = doRollOver;
	this.Out = doRollOut;
}

function doRollOver()
{
	if( document.images )
	{
		image = document.images[ this.name ];
		image.src = this.img[1].src;
	}
}

function doRollOut()
{
	if( document.images )
	{
		image = document.images[ this.name ];
		image.src = this.img[0].src;
	}
}

function doRollDown()
{
	if( document.images && (this.src3 != '') )
	{
		image = document.images[ this.name ];
		image.src = this.img[2].src;
	}
}

MenuRollovers = Array();
function MenuRollover( base_name, src1, src2, src3 )
{
	this.name = base_name;
	this.img = null;
	this.src1 = src1;
	this.src2 = src2;
	this.src3 = src3;

	if( this.src3 + "" == "undefined" )
	{
		this.src3 = "";
	}

	this.Load = doMenuRollLoad;
	this.Over = doRollNull;
	this.Out = doRollNull;
	this.Down = doRollNull;

	MenuRollovers[ MenuRollovers.length ] = this;
	this.loaded = false;

}

function doMenuRollLoad()
{
	this.img = new Array();
	this.img[0] = new Image();
	this.img[0].src = this.src1;
	this.img[1] = new Image();
	this.img[1].src = this.src2;
	if( this.src3 != "" )
	{
		this.img[2] = new Image();
		this.img[2].src = this.src3;
	}
	this.Over = doRollOver;
	this.Out = doRollOut;
	if( navigator.userAgent.indexOf('Mac') == -1 )
	{
		this.Down = doRollDown;
	}
}

function MenuRollover_OnLoad()
{
	for( i=0; i<MenuRollovers.length; i++ )
	{
		MenuRollovers[i].Load();
	}
	for( i=0; i<FormRollovers.length; i++ )
	{
		FormRollovers[i].Load();
	}
}

FormRollovers = Array();
function FormButton( src1, src2, src3 )
{
	this.img = null;
	this.src1 = src1;
	this.src2 = src2;
	this.src3 = src3;

	this.Load = doMenuRollLoad;
	this.Over = doRollNull;
	this.Out = doRollNull;
	this.Down = doRollNull;

	FormRollovers[ FormRollovers.length ] = this;
}

/* addEvent( element [object], type [string], function_to_call [function], capture_event [bool] ) */
function addEvent(elem, evType, func, useCapture) {
	if(typeof elem.addEventListener != 'undefined') {
		elem.addEventListener(evType, func, useCapture);
		return true;
	} else if( typeof elem.attachEvent != 'undefined' ) { 
		var r = elem.attachEvent("on" + evType, func);
		return r; 
	} else { 
		var onEvt = "on" + evType;
		var elOldEvFuncs = elem[onEvt];
		if( typeof elem[onEvt] != 'function' ) {
			elem[onEvt] = func; 
		} else {
			elem[onEvt] = function() { elOldEvFuncs(); func(); }
		}
	}
}

function addLoadEvent(x) {
	var y = window;
	if(typeof document.addEventListener != 'undefined' && window.addEventListener == 'undefined') {
		y = document;
	}
	addEvent(y,"load",x,false);
}

function addUnLoadEvent(x) {
	var y = window;
	if(typeof document.addEventListener != 'undefined' && window.addEventListener == 'undefined') {
		y = document;
	}
	addEvent(y,"unload",x,false);
}

addLoadEvent(MenuRollover_OnLoad);

/** end menutool functions **/
/** $Id: htmltools.js,v 1.18 2008/10/20 08:17:11 tt Exp $ **/
/** htmltools javascript functions **/

/* stop pressing 'Return' submits forms */
var htmltools_form_focus = -1;
var htmltools_buttons = new Array();
var htmltools_forms = new Array();
function htmltools_onkeypress(e)
{
	var code = (window.Event) ? e.which : event.keyCode;
	j = htmltools_form_focus;
	if(code == "13" && j!=-1 )
	{
		l = htmltools_forms[j].length;
		if( l == 0 )
		{
			return true;
		}
		if( l == 1 )
		{
//			return true; /* enable this to get 'normal' behaviour for forms with 1 button */
		}
		if( typeof g_htmltools_active_combobox == 'object' )
		{
			htmltools_combobox_toggle( g_htmltools_active_combobox );
			return false;
		}
		el = document.getElementById( htmltools_forms[j][l-1] );
		if( el != null && el.nodeName=='INPUT') el.focus();
		return false;
	}
	return true;
}

function htmltools_init_forms()
{
	var frms = document.getElementsByTagName("FORM");

	for( var j=0; j<frms.length; j++ )
	{
		htmltools_forms[j] = new Array();
		for( var i=0; i<htmltools_buttons.length; i++ )
		{
			el = document.getElementById( htmltools_buttons[i] );
			if( el!=null && el.form == frms[j] )
			{
				k = htmltools_forms[j].length;
				htmltools_forms[j][k] = htmltools_buttons[i];
			}
		}
	}
	
	for (var i=0; i<frms.length; i++)
	{
		for( var j=0; j<frms[i].elements.length; j++ )
		{
			switch( frms[i].elements[j].type )
			{
			case "hidden" :
			case "textarea" :
				break;
			default:
				eval( "addOnFocusEvent(frms[" + i + "].elements[" + j + "], function() { htmltools_form_focus=" + i + ";})" );
				frms[i].elements[j].onblur = function() {
					htmltools_form_focus = -1;
				}
			}
		}
	}
	document.onkeypress = htmltools_onkeypress;
		
		el = document.getElementById( "text_1" );
		if( el )
		{
			el.focus();
		}
	
}

function htmltools_register_button( id )
{
	htmltools_buttons[htmltools_buttons.length] = id;
}

function htmltools_checkbox_controller( id1, id2, label, show_class, hide_class )
{
	id1 = document.getElementById( id1 );
	id2 = document.getElementById( id2 );
	label = document.getElementById( label );

	id1.controls = id2;
	id1.labels = label;
	id1.show_class = show_class;
	id1.hide_class = hide_class;
	id1.onclick = function() {
		htmltools_checkbox_controller_onclick( this, this.controls, this.labels, id1.show_class, id1.hide_class );
	}
	id2.checked_last_val = id2.checked;
	id2.checked = (!id1.checked) && id2.checked || (id1.checked && id2.checked);
	id2.disabled = !id1.checked;
	label.className = id1.checked ? show_class:hide_class;
}
	
function htmltools_checkbox_controller_onclick( id1, id2, label, show_class, hide_class )
{
	id2.disabled=!id1.checked;
	if( id1.checked )
	{
		id2.checked=id2.checked_last_val;
	}
	else
	{
		id2.checked_last_val=id2.checked;
		id2.checked=false;
	}
	label.className = (id1.checked ? show_class:hide_class);
}

function addOnFocusEvent(el,func)
{
	var oldonfocus = el.onfocus;
	if( typeof el.onfocus != 'function') {
		el.onfocus = func;
	} else {
		el.onfocus = function() {
			oldonfocus();
			func();
		}
	}
}

addLoadEvent(htmltools_init_forms);

/** end htmltools javascript functions **/
function getAll( el ) { 
	if( el.all ) { 
		return el.all; 
	} else { 
		return el.getElementsByTagName("*"); 
	} 
}

function delClass( el, className )
{
	var regex = new RegExp("\\b"+className+"\\b");
	var s = el.className;
	s = s.replace( regex, '' );
	return el.className = s;
}

/** search document for elements with triggers and initialise them **/
addLoadEvent( function() { triggers( document ) } );

var g_triggers=Array();
var g_trigger_direct = Array();
function trigger(fn,id,args)
{
	g_trigger_direct.push( Array(fn,id,args) );
}

function triggers(el)
{
	var all = getAll(el);
	var regex = new RegExp(/\s+(\w+)((\s+(arg-[\w-]+\b))+|\b)/);
	var args;
// 	g_triggers = Array();
	
		var els = Array();
	for( var i=0, all_length=all.length; i<all_length; i++ ) {
		els.push(all[i]);
	}
	for( var i in els ) {
		if( typeof els[i] == 'undefined' )
			continue;
		// hack around IE's weird split
		var x_class = ' ' + els[i].className.toString().replace( /\s+/,' ' );
		var parts = x_class.split( /\bjs\b/ );
		parts.shift();
		for( var j in parts ) {
			var res = regex.exec(parts[j]);
			if( !res ) {
				continue;
			}
			if( typeof eval( "window." + res[1] ) != 'function' ) {
				continue;
			}
			var k = g_triggers.length;
			eval( "g_triggers[" + k + "] = new " + res[1] + "(" + k + ");" );
			g_triggers[k].init( els[i], res[2].replace( /\s+arg-/g, ',' ).replace( /^,/, '' ) );
			delClass( els[i], 'js' ); // so it doesn't get initialised again!
		}
	}
	
	var target_el;
	els = el.getElementsByTagName('script');
	regex = new RegExp("(\\w+)\\.(\\w+)\\(([^\\)]*)\\)");
	for( var i=0; i<els.length; i++ )
	{
		if( els[i].getAttribute('type') == 'text/x-trigger' )
		{
			if( res = regex.exec(els[i].innerHTML) )
			{
				switch( res[1] )
				{
				case 'next' :
					target_el = els[i].nextSibling;
					while( target_el.nodeName == '#text' )
						target_el = target_el.nextSibling;
					break;
				case 'previous' :
					target_el = els[i].previousSibling;
					while( target_el.nodeName == '#text' )
						target_el = target_el.previousSibling;
					break;
				case 'parent' :
					target_el = els[i].parentNode;
					break;
				default:
					target_el = document.getElementById( res[1] );
					break;
				}
				k = g_triggers.length;
				eval( "g_triggers[" + k + "] = new " + res[2] + "(" + k + ");" );
				g_triggers[k].init( target_el, res[3] );
			}
		}
	}
	
	for( i in g_trigger_direct )
	{
		target_el = document.getElementById( g_trigger_direct[i][1] );
		k = g_triggers.length;
		eval( "g_triggers[" + k + "] = new " + g_trigger_direct[i][0] + "(" + k + ");" );
		g_triggers[k].init( target_el, g_trigger_direct[i][2] );
	}
}
var window_width;
var window_height;
function calc_window_dimensions()
{
	if (self.innerWidth)
	{
		window_width = self.innerWidth;
		window_height = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientWidth)
	{
		window_width = document.documentElement.clientWidth;
		window_height = document.documentElement.clientHeight;
	}
	else if (document.body)
	{
		window_width = document.body.clientWidth;
		window_height = document.body.clientHeight;
	}
}

function AJAX() {
	var o = false;
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
 		try {
  			o = new ActiveXObject("Msxml2.XMLHTTP");
 		} catch (e) {
  			try {
   				o = new ActiveXObject("Microsoft.XMLHTTP");
  			} catch (E) {
   				o = false;
  			}
 		}
	@end @*/
	if (!o && typeof XMLHttpRequest!='undefined') {
		o = new XMLHttpRequest();
	}
	
	return o;
}

function ajax_callback(url, obj, fn)
{
	ajax = new AJAX();
	ajax.open("GET", url, true);
	ajax.onreadystatechange = function() { 
		if( ajax.readyState==4 ) {
			eval( 'obj.' + fn + '(ajax.responseText)' );
		}
	 };
	ajax.send(null);
}
function decodeFormData(str) {
	var res = new Object;
	var bits = str.split( /&/ );
	for( var i in bits ) {
		var nv = bits[i].split( /=/ );
		res[decodeURIComponent(nv[0])] = nv[1]!=null ? decodeURIComponent(nv[1]) : '';
	}
	return res;
}
function addClass( el, className )
{
	var regex = new RegExp("\\b"+className+"\\b");
	var s = el.className;
	if( regex.exec( s ) )
	{
		return;
	}
	if( s!='' )
	{
		s = s + ' ';
	}
	s = s + className;
	return el.className = s;
}

g_popins = new Array();
Popin = function() {
	this.create = function() {
		this.frame = document.createElement('DIV');
		this.frame.className = 'popin-frame';
		this.titlebar = document.createElement('DIV');
		this.titlebar.className = 'popin-titlebar';
		this.caption = document.createElement('DIV');
		this.caption.className = 'popin-caption';
		this.tools = document.createElement('DIV');
		this.tools.className = 'popin-tools';
		this.closeButton = document.createElement('DIV');
		this.closeButton.className = 'popin-button-close';
		this.content = document.createElement('DIV');
		this.content.className = 'popin-content';
		
		this.tools.appendChild( this.closeButton );
		this.titlebar.appendChild( this.caption );
		this.titlebar.appendChild( this.tools );
		this.frame.appendChild( this.titlebar );
		this.frame.appendChild( this.content );
		
		this.hide();
		
		this.popin_id = g_popins.length;
		g_popins[this.popin_id] = this;
		
		eval( "addEvent( this.titlebar, 'mousedown', function(e) { g_popins["+this.popin_id+"].startDrag(e) } )" );
		eval( "addEvent( this.closeButton, 'click', function(e) { g_popins["+this.popin_id+"].clickClose(e) } )" );
		eval( "addEvent( document, 'mousemove', function(e) { g_popins["+this.popin_id+"].doDrag(e) } )" );
		eval( "addEvent( document, 'mouseup', function(e) { g_popins["+this.popin_id+"].endDrag(e) } )" );
		
	};

	this.setParent = function(el) {
		el.appendChild( this.frame );
	};

	this.getPosition = function() {
		return [this.frame.offsetLeft, this.frame.offsetTop];
	}
	this.setPosition = function( pos )	{
		this.frame.style.left = pos[0] + 'px';
		this.frame.style.top = pos[1] + 'px';
	};
	this.referencePosition = function(el) {
		var pos = [0,0];
		while( el != this.frame.parentNode ) {
			pos[0] += el.offsetLeft;
			pos[1] += el.offsetTop;
			el = el.offsetParent;
		}
		return pos;
	}

	this.autoPosition = function( e, option ) {
		var x=0, y=0;
		var ev = ((typeof event == "undefined")? e: event);
		var mousePos = [ev.clientX, ev.clientY];
		
		if( option.around ) {
			calc_window_dimensions();
			
// 			alert( 'mp: ' + mousePos.join(',') + ' w=' + window_width + ' h=' + window_height );
			
			if( mousePos[0] < window_width/2 && mousePos[1] < window_height/2 ) {
				option.below = option.around;
				option.left = option.around;
			} else if( mousePos[0] < window_width/2 ) {
				option.above = option.around;
				option.left = option.around;
			} else if( mousePos[1] < window_height/2 ) {
				option.below = option.around;
				option.right = option.around;
			} else {
				option.above = option.around;
				option.right= option.around;
			}
		}
		
		if( option.below ) {
			var p = this.referencePosition(option.below);
			y = p[1] + option.below.offsetHeight;
		}
		if( option.left ) {
			var p = this.referencePosition(option.left);
			x = p[0];
		}
		if( option.above ) {
			var p = this.referencePosition(option.above);
			y = p[1] - this.frame.offsetHeight;
		}
		if( option.right ) {
			var p = this.referencePosition(option.right);
			x = p[0] + option.right.offsetWidth - this.frame.offsetWidth;
		}
		if( option.over ) {
			var p = this.referencePosition(option.over);
			x = p[0];
			y = p[1];
		}
		this.setPosition( [x,y] );
	};

	this.setClass = function( item, className ) {
		switch( item ) {
		case 'caption':
			addClass( this.caption, className );
			break;
		case 'body':
		case 'content':
			addClass( this.content, className );
			break;
		case 'frame':
			addClass( this.frame, className );
			break;
		};
	};
	this.setText = function( item, text ) {
		switch( item ) {
		case 'caption':
			this.caption.nodeValue = text;
			break;
		case 'body':
		case 'content':
			this.content.nodeValue = text;
			break;
		}
	};
	this.setHTML = function( item, html ) {
		switch( item ) {
		case 'caption':
			this.caption.innerHTML = html;
			break;
		case 'body':
		case 'content':
			this.content.innerHTML = html;
			break;
		}
	};
	this.loadURL = function( url ) {
	
		ajax_callback(url, this, 'loadURL_callback');
	
	};
	this.loadURL_callback = function( str ) {
		var data = decodeFormData(str);
		if( data.status != 'ok' ) {
			alert( "Invalid response" );
			return;
		}
		if( typeof data.caption == 'string' ) {
			this.setHTML( 'caption', data.caption );
		}
		if( typeof data.content == 'string' ) {
			this.setHTML( 'content', data.content );
		}
	}
	
	this.show = function() {
		this.frame.style.visibility = 'visible';
		this.visible = true;
	};
	
	this.hide = function() {
		this.frame.style.visibility = 'hidden';
		this.visible = false;
	}
	
	this.clickClose = function() {
		this.hide();
	}
	
	/***/
	this.startDrag = function(e) {
		this.drag = true;
		
		var ev = ((typeof event == "undefined")? e: event);
		this.drag_start_pos = [ev.clientX,ev.clientY];

	}
	this.doDrag = function(e) {
		if( !this.drag ) {
			return;
		}
		var ev = ((typeof event == "undefined")? e: event);
		var delta = [ev.clientX - this.drag_start_pos[0],ev.clientY - this.drag_start_pos[1]];
		var pos = this.getPosition();
		this.setPosition( [ pos[0]+delta[0], pos[1]+delta[1] ] );
		this.drag_start_pos = [ev.clientX,ev.clientY];
		
		this.stopEvent(e);
	}
	this.endDrag = function(e) {
		if( !this.drag ) {
			return;
		}
		this.drag = false;
	}
	
	
	this.stopEvent = function(e) {
		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
		else if (e.stopPropagation) e.stopPropagation(); // for DOM-compatible
	}
	
};
function formdata_callback() {
	this.xhr = null;
	this.xhr_seq = 0;
	
	this.init_ajax = function() {
		if( this.xhr != null ) {
			delete this.xhr;
		}
		this.xhr_seq++;
		this.xhr = new AJAX();
		eval( "this.xhr.onreadystatechange = function() { return g_triggers[" + this.trigger_id + "].xhr_readystatechange(" + this.xhr_seq + ") }" );
		return this.xhr;
	}

	this.xhr_readystatechange = function(xhr_seq) {
		if( xhr_seq != this.xhr_seq ) {
			// this is a callback from a cancelled operation
			return;
		}
		var xhr = this.xhr;
		if( xhr.readyState==4 ) {
			this.callback(xhr.responseText);
		}
	}
	
	this.callback = function(response) {
		var data = decodeFormData(response);
		if( typeof data.message == 'string' ) {
			this.callback_message( decodeFormData(data.message) );
		}
		switch( data.status )
		{
		default:
			alert(response);
			break;
		case 'ok':
			this.callback_ok( data );
			break;
		case 'error':
			this.callback_error( data );
			break;
		}
		this.callback_complete();
	}
		
}

formdata_callback.prototype.callback_ok = function(data) {
	if( typeof data.redirect == 'string' ) {
		document.location = data.redirect;
	}
	if( typeof data.reload == 'string' ) {
		document.location = document.location.toString();
	}
	if( typeof data.set == 'string' ) {
		var setdata = decodeFormData(data.set);
		setFormData( this.el, setdata );
	}
}
	
formdata_callback.prototype.callback_error = function(data) {
	if( typeof data.errors == 'string' ) {
		var errors = decodeFormData(data.errors);
		var inp;
		var msg;
		for( var i in errors ) {
			inp = this.el.elements[i];
			if( !inp ) {
				inp = this.el.elements[ i + '[]' ];
			}
			if( !inp ) {
				alert( 'Unknown form element: ' + i );
				continue;
			}
			msg = null;
			switch( typeof inp.type )
			{
			case 'undefined':
				// radio buttons return a nodeList
				inp = inp[0];
				msg = document.getElementById( inp.parentNode.parentNode.id + '_msg' );
				break;
			default:
				switch( inp.nodeName.toUpperCase() )
				{
				case 'INPUT':
					switch( inp.type.toLowerCase() )
					{
					case 'text':
					default:
						msg = document.getElementById( inp.id + '_msg' );
						break;
					case 'checkbox':
						msg = document.getElementById( inp.id + '_msg' );
						if( msg != null ) {
							break;
						}
						alert( msg );
						break;
					}
					break;
				case 'TEXTAREA':
				case 'SELECT':
					msg = document.getElementById( inp.id + '_msg' );
					break;
				default:
					alert( 'Unknown element type: ' + (inp.nodeName) + ' (for ' + i + ')' );
					break
				}
			}
			if( typeof inp.trigger != 'undefined' ) {
				inp.trigger.set();
			}
			if( msg == null )
				continue;
			msg.innerHTML = errors[i];
		}
	}
}
	
formdata_callback.prototype.callback_message = function(data) {
	if( typeof data.alert == 'string' ) {
		alert( data.alert );
	}
}

formdata_callback.prototype.callback_complete = function() {
	return;
}
function appendQuery( url, qs )
{
	return url + (url.match(/\?/) ? '&' : '?') + qs;
}

function popin_link( trigger_id )
{
	this.trigger_id = trigger_id;

	this.init = function(el, args) {
		this.el = el;
		this.popin = null;
		this.args = args.split( /,/ );
		if (this.args[0] == 'at') {
			this.at_target = document.getElementById( this.args[1] );
			this.group_class = this.args[2];
		}
		else {
			this.group_class = this.args[0];
		}


		eval( "el.onclick = function(e) {return g_triggers["+this.trigger_id+"].click(e);}" );
	}
	
	this.click = function(e) {
		if( this.popin == null ) {
			this.popin = new Popin();
			this.popin.create();
			this.popin._group_class = this.group_class;

			var op = this.el.parentNode;
			while( op ) {
				if( op.offsetParent ) {
					op = op.offsetParent;
					var c = (op.currentStyle ? op.currentStyle : window.getComputedStyle(op,''));
					if( c.position == 'static' ) {
						/* seems impossible, right?... but this occurs in IE?? */
						continue;
					}
					break;
				} 
				op = op.parentNode;
			}
			this.popin.setParent( op );
		}

		for( var i in g_popins ) {
			if( g_popins[i]._group_class == this.popin._group_class ) {
				g_popins[i].hide();
			}
		}
		
		if (this.at_target) {
			this.popin.autoPosition(e, {'over':this.at_target} );
		}
		else {
 			this.popin.autoPosition(e, {'below':this.el.parentNode, 'left':this.el.parentNode} );
		}
		this.popin.setHTML( 'caption', 'Popin caption' );
		this.popin.setHTML( 'content', 'Loading' );
		this.popin.show();
		
		ajax_callback( appendQuery(this.el.href.toString(),'js=popin_link'), this, 'callback' );
		
		return false;
	}
	
	this.callback_ok = function(data) {
		if( typeof data['class'] == 'string' ) {
			this.popin.setClass( 'frame', data['class'] );
			data['class'] = null;
		}
		
		if( typeof data.caption == 'string' ) {
			this.popin.setHTML( 'caption', data.caption );
			data.caption = null;
		}
		if( typeof data.content == 'string' ) {
			this.popin.setHTML( 'content', data.content );
			var content_forms = this.popin.content.getElementsByTagName('form');
			for( var i=0,content_forms_length=content_forms.length; i<content_forms_length; i++ ) {
				content_forms[i].popin = this.popin;
			}
			data.content = null;
		}
		formdata_callback.prototype.callback_ok.call(this,data);
	}
	this.callback_error = function(data) {
		alert( "Error: Unhandled error condition" );
	}
	
	this.callback_complete = function() {
		formdata_callback.prototype.callback_complete.call(this);
		triggers(document);
	}
}
popin_link.prototype = new formdata_callback();	