/** helper functions **/

function getAll( el ) { 
	if( el.all ) { 
		return el.all; 
	} else { 
		return el.getElementsByTagName("*"); 
	} 
}

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;
}
function delClass( el, className )
{
	var regex = new RegExp("\\b"+className+"\\b");
	var s = el.className;
	s = s.replace( regex, '' );
	return el.className = s;
}

function hasClass( el, className )
{
	var regex = new RegExp("\\b"+className+"\\b");
	return regex.exec( el.className );
}

function addStyles(obj,styles) {
	if(typeof obj.style.cssText != 'undefined') {
		obj.style.cssText=styles;
	} else if(typeof obj.style.cssText == 'undefined' && typeof obj.style != 'undefined') {
		obj.style=styles;
	} else {
		obj.setAttribute("style",styles);
	}
}
	
function appendQuery( url, qs )
{
	return url + (url.match(/\?/) ? '&' : '?') + qs;
}

function labelFor( id )
{
	var els = document.getElementsByTagName('label');
	for( var i=0; i<els.length; i++ )
	{
		if( els[i].htmlFor == id || els[i].getAttribute('for') == id )
		{
			return els[i];
		}
	}
	return null;
}

function roundElementHeight( o )
{
	/* Stop Mozilla from creating a body scrollbar when siblings
	have computed heights with decimal parts.
	offsetHeight is the style.height + borders + paddings; we
	work out the border and padding dimensions by first
	setting the style.height to our target and checking offsetHeight
	again:
		style.height = offsetHeight - border+padding
		-> border+padding = offsetHeight - style.height
	*/
	var tmp;
	var diff;
	o.style.height = '';
	tmp = Math.ceil( o.offsetHeight );
	if( tmp == o.offsetHeight )
	{
		return;
	}
	o.style.height = tmp + 'px';
	diff = o.offsetHeight - tmp;
	tmp -= diff;
	o.style.height = tmp + 'px';
}


var scrollbar_removed = false;

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 camelcase(str)
{
	str=str.split(/\b/);
	var outstr = str[0];
	for(i=1;i<str.length;i++){
		outstr=outstr+str[i].charAt(0).toUpperCase()+str[i].substring(1)
	}
	return outstr.replace(/[^\w]/g,'');
}

function hyphenate(s)
{
	sa=s.replace(/[^\w\s]/g,'').split(/\b/);
	t=Array();
	for(i=0;i<sa.length;i++){
		ss=sa[i].replace(/[^\w]/g,'');
		if( ss == '' )
			continue;
		t[t.length] = ss;
	}
	return t.join('-');
}

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);
}


/** src: http://www.netspade.com/articles/javascript/cookies.xml **/
/**
 * Sets a Cookie with the given name and value.
 *
 * name       Name of the cookie
 * value      Value of the cookie
 * [expires]  Expiration date of the cookie (default: end of current session)
 * [path]     Path where the cookie is valid (default: path of calling document)
 * [domain]   Domain where the cookie is valid
 *              (default: domain of calling document)
 * [secure]   Boolean value indicating if the cookie transmission requires a
 *              secure transmission
 */
function setCookie(name, value, expires, path, domain, secure)
{
    document.cookie= name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}

/**
 * Gets the value of the specified cookie.
 *
 * name  Name of the desired cookie.
 *
 * Returns a string containing value of specified cookie,
 *   or null if cookie does not exist.
 */
function getCookie(name)
{
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

/**
 * Deletes the specified cookie.
 *
 * name      name of the cookie
 * [path]    path of the cookie (must be same as path used to create cookie)
 * [domain]  domain of the cookie (must be same as domain used to create cookie)
 */
function deleteCookie(name, path, domain)
{
    if (getCookie(name))
    {
        document.cookie = name + "=" + 
            ((path) ? "; path=" + path : "") +
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

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

var g_triggers=null;
var g_trigger_direct = Array();
function trigger(fn,id,args)
{
	g_trigger_direct[g_trigger_direct.length] = Array(fn,id,args);
}

function triggers(el)
{
	var els = getAll(el);
	var regex = new RegExp(/\s(\w+)((\s(arg-[\w-]+\b))+|\b)/);
	var res;
	var parts;
	var k;
	var args;
	g_triggers = Array();
	
	for( var i=0; i<els.length; i++ )
	{
		// hack around IE's weird split
		x_class = ' ' + els[i].className;
		parts = x_class.split( /\bjs\b/ );
		for( var j=1; j<parts.length; j++ )
		{
			if( res = regex.exec(parts[j]) ) 
			{
				k = g_triggers.length;
				if( typeof eval( "window." + res[1] ) == 'function' ) {
					eval( "g_triggers[" + k + "] = new " + res[1] + "(" + k + ");" );
					g_triggers[k].init( els[i], res[2].replace( / arg-/g, ',' ).replace( /^,/, '' ) );
				}
			}
		}
	}
	
	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=0; i<g_trigger_direct.length; i++ )
	{
		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] );
	}
}

function minheight( trigger_id )
{
	this.trigger_id = trigger_id;
	
	this.init = function(el, args) {
		this.args = args;
		this.el = el;
		this.el.trigger = this;
		this.redraw();
	};
	
	this.redraw = function() {
		var res = this.args.split( /,/ );
		var min_h = this.el.offsetHeight;

		if( min_h < document.getElementById( res[0] ).offsetHeight ) {
			if( document.all ) {			
			    var agt=navigator.userAgent.toLowerCase();
				// ie 5.x has box model issues
				if( (parseInt(navigator.appVersion) == 4 && agt.indexOf("msie 5.0")!=-1) ||
					(parseInt(navigator.appVersion) == 4 && agt.indexOf("msie 5.5") !=-1) ) {
					res[1] = 0;
				}
				this.el.style.height = '' + (document.getElementById( res[0] ).offsetHeight - res[1]) + 'px';
			} else {
				this.el.style.minHeight = '' + (document.getElementById( res[0] ).offsetHeight - res[1]) + 'px';
			}
		}
		
		if( !scrollbar_removed ) {
			scrollbar_removed = true;
			removescrollbar();
		}
	};

}

function reltarget( trigger_id )
{
	this.trigger_id = trigger_id;
	this.target_id = null;
	this.state = 'init';
	this.xmlhttprequest = null;
	
	this.init = function( el, args )
	{
		this.el = el;
		this.args = args;
		this.el.trigger = this;
		this.el.onclick = function(e) { return this.trigger.onclick(e) };
		this.target_id = el.getAttribute('rel');
	}
	
	this.onclick = function(e) {
		
		if( this.state == 'loading' )
		{
			if( !this.abortrequest() )
			{
				return false;
			}
		}
		this.xmlhttprequest = new AJAX();
		el = document.getElementById( this.target_id );
		if( el == null )
		{
			return true;
		}
		this.state = 'loading';
		this.xmlhttprequest.open("GET", appendQuery(this.el.href,'js='+this.target_id), true);
		eval( 'this.xmlhttprequest.onreadystatechange = function() { g_triggers[' + this.trigger_id + '].onreadystatechange() }' );
		this.xmlhttprequest.send(null);
		setTimeout( "g_triggers[" + this.trigger_id + "].showloadmessage()", 400 );
		return false;
	};

	this.onreadystatechange = function(obj) {
		if( this.xmlhttprequest.readyState == 4 ) 
		{
			this.state = '';
			try
			{
				x_ajax = this.xmlhttprequest.getResponseHeader( 'x-ajax' );
			}
			catch(e)
			{
				window.location = this.el.href;
				return;
			}
			if( this.xmlhttprequest.responseText == '' )
			{
				return;
			}
			el = document.getElementById( this.target_id );
 			el.innerHTML = this.xmlhttprequest.responseText;
			triggers( document );
		}
	};
	
	this.showloadmessage = function() {
		if( 'loading' == this.state )
		{
			el = document.getElementById( this.target_id );
			el.innerHTML = '<p>Loading ...</p>';
		}
	};
	
	this.showabortmessage = function() {
		if( 'aborting' == this.state )
		{
			el = document.getElementById( this.target_id );
			el.innerHTML = '<p>Cancelled</p>';
		}
	};
	
	this.abortrequest = function() {
		this.state = 'aborting';
		this.showabortmessage();
		this.xmlhttprequest.abort();
		var abort_countdown = 5000;
		while( this.state != '' && abort_countdown-->0 );
		if( abort_countdown<0 )
		{
			return false;
		}
		return true;
	};
}

trigger_popup_window = false;
function popup(trigger_id)
{
	this.trigger_id = trigger_id;
	
	this.init = function( el, args )
	{
		el.trigger = this;
		el.onclick = function(e) { return this.trigger.onclick(this) }
	}
	
	this.onclick = function(a)
	{
		trigger_popup_window = window.open( a.href, 'trigger_popup_window', 'width=400,height=200,toolbar=no,directories=no,location=no,scrollbars=yes' );
		return false;
	}
}
function closepopup()
{
	if( trigger_popup_window )
	{
		trigger_popup_window.close();
	}
}

function a_targetgroup(trigger_id)
{
	this.trigger_id = trigger_id;
	
	this.init = function( el, args )
	{
		this.anchors = el.getElementsByTagName( 'A' );
		this.args = args.split( /,/ );
		for( var i=0; i<this.anchors.length; i++ )
		{
			this.anchors[i].trigger = this;
			this.anchors[i].onclick = function(e) { return this.trigger.onclick(this) };
		}
		var regex = new RegExp(/\b([\w-]+)\b/);
		var res;
		if( res = regex.exec( this.args[0] ) )
		{
			this.target_id = res[1];
		}
		this.set_title = (this.args[1]=='title');
	}

	this.onclick = function(srcel) {
		if( this.state == 'loading' )
		{
			if( !this.abortrequest() )
			{
				return false;
			}
		}
		this.xmlhttprequest = new AJAX();
		el = document.getElementById( this.target_id );
		if( el == null )
		{
			return true;
		}
		this.state = 'loading';
		this.href = srcel.href;
		this.xmlhttprequest.open("GET", appendQuery(srcel.href,'js=' + this.target_id), true);
		eval( 'this.xmlhttprequest.onreadystatechange = function() { g_triggers[' + this.trigger_id + '].onreadystatechange() }' );
		this.xmlhttprequest.send(null);
		if( this.set_title && '' != srcel.title )
		{
			document.title = srcel.title;
		}
		setTimeout( "g_triggers[" + this.trigger_id + "].showloadmessage()", 400 );
		return false;
	};

	this.onreadystatechange = function(obj) {
		if( this.xmlhttprequest.readyState == 4 ) 
		{
			this.state = '';
			if( this.xmlhttprequest.responseText == '' )
			{
				return;
			}
			try
			{
				x_ajax = this.xmlhttprequest.getResponseHeader( 'x-ajax' );
			}
			catch(e)
			{
				window.location = this.href;
				return;
			}
			el = document.getElementById( this.target_id );
 			el.innerHTML = this.xmlhttprequest.responseText;
			triggers( document );
			
			el = document.getElementById( 'content' );
			/* TODO: works in Moz, but not IE */
			el.scrollTop = 0; // Moz
			//el.style.top = '0';
		}
	};
	
	this.showloadmessage = function() {
		if( 'loading' == this.state )
		{
			el = document.getElementById( this.target_id );
			el.innerHTML = '<p><img src="/_img/loading.gif" /></p>';
		}
	};
	
	this.showabortmessage = function() {
		if( 'aborting' == this.state )
		{
			el = document.getElementById( this.target_id );
			el.innerHTML = '<p>Cancelled</p>';
		}
	};
	
	this.abortrequest = function() {
		this.state = 'aborting';
		this.showabortmessage();
		this.xmlhttprequest.abort();
		var abort_countdown = 5000;
		while( this.state != '' && abort_countdown-->0 );
		if( abort_countdown<0 )
		{
			return false;
		}
		return true;
	};
}

function maxheight( trigger_id )
{
	this.trigger_id = trigger_id;
	
	this.init = function(el, args) {
		this.el = el;
		this.others = args;
		this.el.trigger = this;
		this.myheight = 0;
		this.redraw(1);
		eval( "addEvent( window, 'resize', function() { g_triggers["+ this.trigger_id +"].redraw(); }, false )" );
	};
	
	this.redraw = function(init) {
		calc_window_dimensions();
		if( this.myheight == window_height )
		{
			return;
		}
		this.myheight = window_height;
		var el_height = window_height;
		var res = this.others.split( /,/ );
		var i=0, screen=(res[0]=='screen');
		if (screen )
		{
			i++;
		}
		for( ; i<res.length; i++ )
		{
			if( init )
			{
				roundElementHeight(document.getElementById( res[i] ));
			}
			el_height -= document.getElementById( res[i] ).offsetHeight;
		}
		if( screen && init )
		{
			this.min_el_height = this.el.offsetHeight;
		}
		if( screen && this.min_el_height < el_height )
		{
			this.el.style.height = '' + el_height + 'px';
			
		}
		if( !screen )
		{
			this.el.style.height = '' + el_height + 'px';
			this.el.style.overflow = 'auto';
		}
	};

}

function scrollpos( trigger_id )
{
	this.trigger_id = trigger_id;
	
	this.init = function(el, args) {
		if( undefined == el.id )
			return;
		this.el = el;
		this.el.trigger = this;
		this.cookie = 'scrollpos_' + this.el.id;
		eval( 'addUnLoadEvent( function() { g_triggers['+this.trigger_id+'].unload() } )' );
		this.move();
		if( this.el.scrollTop != getCookie( this.cookie ) )
		{
			eval( 'setTimeout( function() { g_triggers['+this.trigger_id+'].move() }, 100 )' );
		}
	}
	
	this.unload = function() {
		setCookie( this.cookie, this.el.scrollTop );
	}
	
	this.move = function() {
		this.el.scrollTop = getCookie( this.cookie );
	}
}

function removescrollbar() {
	if( document.all ) {
		document.documentElement.style.overflow = 'hidden';
		document.documentElement.childNodes[1].style.overflow = 'hidden';
	}
}

/** FORM element validation **/
triggers_validate = new Array();
triggers_validate['notnull'] = /.+/;
triggers_validate['email'] = /.+@.+/;
triggers_validate['url'] = /^\/.+/;
triggers_validate['date'] = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
triggers_validate['color'] = /^#[a-f0-9A-F]{6}$/;
triggers_validate['number'] = /^[\d\.]*$/;
triggers_validate['number_notnull'] = /^[\d\.]+$/;

function validate( trigger_id )
{
	this.trigger_id = trigger_id;
	this.intimer = 0;

	this.init = function( el, args )
	{
		var regex = new RegExp("\\b([\\w-]+)\\b");
		if( res = regex.exec( args ) )
		{
			this.regex = new RegExp(triggers_validate[res[1]]);
			this.el = el;
			this.el.trigger = this;
			addEvent( this.el, 'keypress', function(e) { this.trigger.onkeypress(e); } );
			this.el.onchange = function(e) { return this.trigger.onchange(e) };
			this.el.onfocus = function(e) { return this.trigger.onfocus(e) };
			this.el.onblur = function(e) { return this.trigger.onblur(e) };
			this.el.insertstring = function(s) { return this.trigger.insertstring(this,s) };
			this.validate();
			if( this.el.form.onsubmit == undefined )
			{
				eval( 'this.el.form.onsubmit = function() { return g_triggers[' + this.trigger_id + '].onsubmit() }' );
			}
		}
	}
	
	this.validate = function()
	{
		if( this.regex.exec( this.el.value ) )
		{
			addClass( this.el, 'valid' );
			delClass( this.el, 'invalid' );
			
			var id = this.el.getAttribute('id')
			var msgel = document.getElementById( id + '_msg' )
			if( msgel )
			{
				addClass( msgel, 'validation' );
			}
			
			return true;
		}
		else
		{
			addClass( this.el, 'invalid' );
			delClass( this.el, 'valid' );
			return false;
		}
	}
	
	this.onchange = function(e)
	{
		this.validate();
	}
	this.onblur = function(e)
	{
		delClass( this.el, 'checking' );
		this.validate();
	}
	this.onfocus = function(e)
	{
		addClass( this.el, 'checking' );
		this.validate();
	}
	
	this.onkeypress = function(e)
	{
		if( !this.intimer )
		{
			this.intimer = 1;
			setTimeout( "g_triggers[" + this.trigger_id + "].keypresstimer()", 400 );
		}
	}
	this.keypresstimer = function()
	{
		this.intimer = 0;
		this.validate();
	}
	
	this.onsubmit = function()
	{
		var frm = this.el.form;
		var msg = '';
		var focussed = -1;
		var id;
		var msgel;
		mytypes = '';
		if( !hasClass(frm.clicked, 'validates') )
		{
			return true;
		}
		for( var i=0; i<frm.elements.length; i++ )
		{
			if( frm.elements[i].trigger != undefined )
			{
				id = frm.elements[i].getAttribute('id')
				msgel = document.getElementById( id + '_msg' )
				if( msgel )
				{
					if( frm.elements[i].trigger.validate() )
					{
						addClass( msgel, 'validation' );
					}
					else
					{
						delClass( msgel, 'validation' );
						if( focussed<0 )
						{
							focussed = i;
						}
					}
				}
				else
				{
					if( !frm.elements[i].trigger.validate() )
					{
						msg += '\n' + labelFor(frm.elements[i].getAttribute('id')).innerHTML + ' not entered correctly';
						if( focussed<0 )
						{
							focussed = i;
						}
					}
				}
			}
		}
		if( msg != '' )
		{
			alert( 'Please fix the following before submitting:' + msg );
		}
		frm.elements[focussed].focus();
		return false;
	}
	
	this.insertstring = function(el,s) {
		/* ref: http://www.howtocreate.co.uk/emails/Armand.html */
		el.focus();
		if( el.createTextRange ) 
		{
		   document.selection.createRange().text += s;
 		} else if( el.setSelectionRange ) 
		{
			var len = el.selectionEnd;
			el.value = el.value.substr( 0, len ) + s + el.value.substr( len );
			el.setSelectionRange(len+s.length,len+s.length);
		} else 
		{ 
			el.value += insText; 
		}
	}
}

function resizebar( trigger_id )
{
	this.trigger_id = trigger_id;
	
	this.init = function( el, args ) {
		if( typeof(el.resizebar_trigger) == 'object' )
		{
			/* don't add resizebars twice */
			return;
		}
		el.resizebar_trigger = this;
		this.el = el;
		el.style.width = parseInt(el.offsetWidth) + 'px';
		this.bar = document.createElement('div');
		this.bar.objParent = el;
		this.bar.className = 'resizebar_handle';
		addStyles( this.bar, 'left:0;top:0;height:0;' );
		eval( "addEvent( this.bar, 'mousedown', function(e) {g_triggers[" + this.trigger_id + "].set_position(e)})" );
		this.el.parentNode.insertBefore(this.bar, this.el.nextSibling);
	
		eval( "addEvent( window, 'resize', function(e) {g_triggers[" + this.trigger_id + "].window_resize(e)})" );
		eval( "addEvent( document, 'mousemove', function(e) {g_triggers[" + this.trigger_id + "].get_position(e)})" );
		eval( "addEvent( document, 'mouseup', function(e) {g_triggers[" + this.trigger_id + "].resize_element=null})" );
		this.window_resize();
	}
	
	this.get_position = function(e) {
		if( this.resize_element != null ) {
			var curEvent = ((typeof event == "undefined")? e: event);
			var newX = curEvent.clientX;
			var pixelMovement = parseInt(newX - this.cur_x);
			var newWidth = parseInt(this.width + pixelMovement);
			var newPos = parseInt(this.pos_x + pixelMovement);
			this.resize_element.style.width = newWidth + "px";
			this.resize_target_element.style.left = newPos + "px";
		}
	}
	
	this.set_position = function(e) {
		curEvent = ((typeof event == "undefined")? e: event);
		this.resize_element = (curEvent["target"] ? curEvent["target"] : curEvent["srcElement"]).objParent;
		this.resize_target_element = curEvent["target"] ? curEvent["target"] : curEvent["srcElement"];
		this.cur_x = curEvent.clientX;
		var tempWidth = this.resize_element.style.width;
		var widthArray = tempWidth.split("p");
		this.width = parseInt(widthArray[0]);
		var tempPos = this.resize_target_element.style.left;
		var posArray = tempPos.split("p");
		var oldPos = parseInt(posArray[0]);
		this.pos_x = parseInt(posArray[0]);
	}

	this.resize_bar = function() {
		if( null == this.bar ) return;
		this.bar.style.height = this.el.offsetHeight + 'px';
		this.bar.style.top = this.el.offsetTop + 'px';
		this.bar.style.left = this.el.offsetLeft + this.el.offsetWidth + 'px';
// 		addStyles( this.bar, 'left:' + p_left + ';top:' + p_top + ';height:' + p_height + ';' );
	}

	this.window_resize = function(e) {
		this.resize_bar();
	}

}

g_open_folder = 0;
function open_folder( trigger_id )
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		if( g_open_folder != 0 )
		{
			img = document.getElementById( 'folder_' + g_open_folder );
			delClass( img, "open" )
		}
		g_open_folder = args;
		img = document.getElementById( 'folder_' + g_open_folder );
		addClass( img, "open" )
	}
}

function prevanswer( trigger_id )
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		this.el = el;
		this.el._trigger = this;
		this.inp = args;
		this.el.onclick = function() { return false; }; /* stop page scrolling */
		eval( "addEvent( this.el, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
		eval( "addEvent( this.el, 'mouseover', function(e) {g_triggers[" + this.trigger_id + "].onover(e)})" );
		eval( "addEvent( this.el, 'mouseout', function(e) {g_triggers[" + this.trigger_id + "].onout(e)})" );
		}
	this.getprevel = function() {
		var c = document.getElementById(this.inp).parentNode;
		var spans = c.getElementsByTagName( 'span' );
		for( var i=0; i<spans.length; i++ ) {
			if( hasClass(spans[i], 'previous') ) {
				return spans[i];
				}
			}
		}
	this.onclick = function(e) {
		document.getElementById(this.inp).value = this.getprevel().textContent;
		}
	this.onover = function(e) {
		addClass( this.getprevel(), 'hover' );
		}
	this.onout = function(e) {
		delClass( this.getprevel(), 'hover' );
		}
}

function fieldhelp(  trigger_id )
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		this.el = el;
		this.el._trigger = this;
		this.inp = args;
		this.div = null;
		this.el.onclick = function() { return false; }; /* stop page scrolling */
		eval( "addEvent( this.el, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
		}
	this.onclick = function(e) {
		if( this.div != null ) {
			this.toggle();
			return;
		}
		curEvent = ((typeof event == "undefined")? e: event);
		this.cur_x = curEvent.clientX;
		this.cur_y = curEvent.clientY;
		this.move_element = null;
		this.busy = false;
		this.div = document.createElement('div');
		this.div.style.display = 'block';
		this.div.style.position = 'fixed';
		this.div.style.width = '400px';
		this.div.style.height = '300px';
		this.div.style.left = (this.cur_x-394) + 'px';
		this.div.style.top = (this.cur_y-12) + 'px';
		this.div.style.border= '1px solid ActiveBorder';
		this.div.style.backgroundColor = 'Window';
		this.titlebar = document.createElement('div');
		this.titlebar.style.width = '100%';
		this.titlebar.style.padding = '2px';
		this.titlebar.style.backgroundColor = 'ActiveCaption';
		this.titlebar.style.color = 'CaptionText';

		img = document.createElement( 'img' );
		img.src = '/_img/codel';
		img.align = 'right';
		eval( "addEvent( img, 'mousedown', function(e) {g_triggers[" + this.trigger_id + "].toggle(e)})" );
		
		caption = document.createElement( 'textNode' );
		caption.innerHTML = 'About';
		
		this.titlebar.appendChild( img );
		this.titlebar.appendChild( caption );
// 		this.titlebar.innerHTML += 'About';
		
		eval( "addEvent( this.titlebar, 'mousedown', function(e) {g_triggers[" + this.trigger_id + "].set_position(e)})" );
		eval( "addEvent( document, 'mousemove', function(e) {g_triggers[" + this.trigger_id + "].get_position(e)})" );
		eval( "addEvent( document, 'mouseup', function(e) {g_triggers[" + this.trigger_id + "].move_element=null})" );
		
		this.div.appendChild( this.titlebar );
		this.helpcontent = document.createElement('div');
		this.helpcontent.style.padding = '1em';
		this.helpcontent.innerHTML = '<p>Loading..</p>';
		this.div.appendChild( this.helpcontent );
		this.el.parentNode.appendChild( this.div );
		
		this.loadhelp();
		}
	
	this.toggle = function(e) {
		this.div.style.display = (this.div.style.display == 'block' ? 'none' : 'block');
	}
	this.hide = function(e) {
		this.div.style.display = 'none';
	}
	this.show = function(e) {
		this.div.style.display = 'block';
	}
		
	this.get_position = function(e) {
		if( this.move_element != null && !this.busy ) {
			this.busy = true;
			var curEvent = ((typeof event == "undefined")? e: event);
			var newX = curEvent.clientX;
			var newY = curEvent.clientY;
			var pixelMovementX = parseInt(newX - this.cur_x);
			var pixelMovementY = parseInt(newY - this.cur_y);
			var newPosX = parseInt(this.pos_x + pixelMovementX);
			var newPosY = parseInt(this.pos_y + pixelMovementY);
// 			this.cur_x = newX;
// 			this.cur_y = newY;
			
			this.move_element.style.left = newPosX + "px";
			this.move_element.style.top = newPosY + "px";
			this.busy = false;
			
			curEvent.stopPropagation();
		}
	}
	
	this.set_position = function(e) {
		curEvent = ((typeof event == "undefined")? e: event);
		this.cur_x = curEvent.clientX;
		this.cur_y = curEvent.clientY;
		this.move_element = this.div;//(curEvent["target"] ? curEvent["target"] : curEvent["srcElement"]).objParent;
	
		var tempPos = this.move_element.style.left;
		var posArray = tempPos.split("p");
		this.pos_x = parseInt(posArray[0]);
		
		var tempPos = this.move_element.style.top;
		var posArray = tempPos.split("p");
		this.pos_y = parseInt(posArray[0]);
		
	}

	this.loadhelp = function() {
		field = document.getElementById(this.inp).name;
		this.xmlhttprequest = new AJAX();
		this.xmlhttprequest.open("GET", appendQuery(this.el.href,'js=help'), true);
		eval( 'this.xmlhttprequest.onreadystatechange = function() { g_triggers[' + this.trigger_id + '].onreadystatechange() }' );
		this.xmlhttprequest.send(null);
		setTimeout( "g_triggers[" + this.trigger_id + "].showloadmessage()", 400 );
		return false;
	};

	this.onreadystatechange = function(obj) {
		if( this.xmlhttprequest.readyState == 4 ) 
		{
 			this.helpcontent.innerHTML = this.xmlhttprequest.responseText;
		}
	};
}

function add_setInnerHTML(trigger_id)
{
	this.trigger_id = trigger_id;
	this.seq = 0;
	this.init = function(el, args) {
		this.el = el;
		this.el.trigger = this;
		this.el.setInnerHTML = function(url) {
			var xhr = new AJAX();
			url = appendQuery(url,'js=' + (el.id));
			url = appendQuery(url,'jseq=' + (++this.trigger.seq));
			xhr.open("GET", url, true);
			xhr.onreadystatechange = function() {
				if( xhr.readyState == 4 )
				{
					try
					{
						var x_ajax = xhr.getResponseHeader( 'X-AJAX-SEQ' );
					}
					catch(e)
					{
						el.innerHTML = 'Error!';
						return;
					}
					if( parseInt(x_ajax) != el.trigger.seq ) {
						return;
					}
					el.innerHTML = xhr.responseText;
				};
			};
			xhr.send(null);
			el.innerHTML = "<img src='/_img/indicator' width='16' height='16' />";
		};
	};
}

function calchelp(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		this.el = el;
		this.args = args.split( /,/ );
		this.win = document.createElement('div');
		this.titlebar = document.createElement('div');
		this.body = document.createElement('div');
		this.msg = document.createElement('div');
		
		var a = document.createElement('a');
		var l = labelFor(this.args[1]);
		while( l && l.firstChild.nodeName != '#text' ) {
			l = l.firstChild;
		}
		var t = document.createTextNode(l.innerHTML);
// 		t.value = labelFor(this.args[1]).innerHTML;
		this.titlebar.appendChild(a);
		this.titlebar.appendChild(t);
		this.body.appendChild(this.msg);
		this.win.appendChild(this.titlebar);
		this.win.appendChild(this.body);
		addClass( this.titlebar, 'calchelp-titlebar' );
		addClass( this.win, 'calchelp-popup' );
		addClass( this.body, 'calchelp-body' );
		addClass( this.msg, 'calchelp-msg' );
		addClass( this.win, 'hide' );
// 		this.el.parentNode.insertBefore(this.win, this.el.nextSibling);
		document.getElementById('calculator').parentNode.appendChild(this.win);
		
		eval( "addEvent( this.titlebar, 'mousedown', function(e) {g_triggers[" + this.trigger_id + "].start_drag(e)})" );
		eval( "addEvent( this.titlebar, 'mouseup', function(e) {g_triggers[" + this.trigger_id + "].end_drag(e)})" );
		eval( "addEvent( document, 'mousemove', function(e) {g_triggers[" + this.trigger_id + "].drag(e)})" );
		eval( "addEvent( a, 'click', function(e) {g_triggers[" + this.trigger_id + "].close(e)})" );
		eval( "addEvent( el, 'click', function(e) {g_triggers[" + this.trigger_id + "].open(e)})" );
	}
	
	this.open = function(e) {
		var frm = document.getElementById( this.args[0] );
		
		var url = document.location.toString();
		url = appendQuery(url, 'js=calchelp' );
		for( var i=1; i<this.args.length; i++ ) {
			if( frm.elements[this.args[i]] ) {
				url = appendQuery( url, encodeURIComponent(this.args[i]) + '=' + encodeURIComponent(frm.elements[this.args[i]].value) );
			} else if( frm.elements['input[' + this.args[i] + '][0]'] ) {
				var v = Array();
				for( var j=0; frm.elements['input[' + this.args[i] + ']['+j+']']; j++ ) {
					v[v.length] = frm.elements['input[' + this.args[i] + ']['+j+']'].value;
				}
				url = appendQuery( url, encodeURIComponent(this.args[i]) + '=' + encodeURIComponent( v.join(',') ) );
			}
		}
		var pos1 = findPos(document.getElementById('calculator'));
		var pos2 = findPos(this.el);
		this.win.style.top = '-500px';
		this.drag_clientX = -1;
		this.msg.innerHTML = 'loading..';
		delClass(this.win, 'hide');
		if( !this.def_win_height ) {
			this.def_win_height = this.win.clientHeight;
		}
		this.win.style.height = (this.titlebar.clientHeight + this.msg.clientHeight + 6) + 'px';
		this.win.style.left = (pos2[0]-pos1[0]-this.win.clientWidth-5) + 'px';
		this.win.style.top = (pos2[1]) + 'px';
		ajax_callback( url, this, 'popup' );
	};
	
	this.popup = function( s ) {
		this.msg.innerHTML = s;
		if( this.msg.clientHeight < this.def_win_height ) {
			this.win.style.height = (this.titlebar.clientHeight + this.msg.clientHeight + 6) + 'px';
		} else {
			this.win.style.height = this.def_win_height + 'px';
		}
	};
	
	this.close = function(e) {
		addClass(this.win, 'hide');
		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
		else if(e.preventDefault) e.preventDefault(); // for DOM-compatible
	};

	this.start_drag = function(e) {
		var curEvent = ((typeof event == "undefined")? e: event);
		this.drag_clientX = curEvent.clientX;
		this.drag_clientY = curEvent.clientY;
		var pos1 = findPos(document.getElementById('calculator'));
		var pos2 = findPos(this.win);
		this.start_posX = (pos2[0]-pos1[0]);
		this.start_posY = pos2[1];
		this.stopEvent(e);
	};
	this.end_drag = function(e) {
		this.drag_clientX = -1;
		this.stopEvent(e);
	};
	this.drag = function(e) {
		if( this.drag_clientX>=0 ) {
			var curEvent = ((typeof event == "undefined")? e: event);
			this.win.style.left = (this.start_posX + (curEvent.clientX - this.drag_clientX)) + 'px';
			this.win.style.top = (this.start_posY + (curEvent.clientY - this.drag_clientY)) + 'px';
			this.stopEvent(e);
		}
	};

	this.stopEvent = function(e) {
		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
		else if (e.preventDefault) e.preventDefault(); // for DOM-compatible
		if( e.stopPropagation ) e.stopPropagation();
	}

}

function fixheight(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el, args) {
		this.el = el;
		this.el.trigger = this.trigger_id;
		setTimeout( "g_triggers[" + this.trigger_id + "].fixheight(0)", 0 );
// 		this.fixheight();
	};
	
	this.fixheight = function(m) {
		var c = this.el;
		var h = 0;
		for( var j=0;j<c.childNodes.length; j++ ) {
			if(	(	(c.childNodes[j].nodeName=='DIV' && 
						(hasClass(c.childNodes[j], 'minislider') || 
						hasClass(c.childNodes[j], 'shortslider') || 
						hasClass(c.childNodes[j], 'slider' ))) ||
					( c.childNodes[j].nodeName == 'LABEL' )
			    ) &&
				(!hasClass(c.childNodes[j], m ? 'hide':'hideme') ))
			{
// 				alert( c.childNodes[j].id + ' ' + c.childNodes[j].clientHeight );
				h += c.childNodes[j].clientHeight;
			}
		}
		if( h>0 ) {
			c.style.height = (h+3) + 'px';
		}
	}
}

function hideme(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el, args) {
		this.el = el;
		setTimeout( "g_triggers[" + this.trigger_id + "].go()", 0 );
	}
	this.go = function() { 
		addClass(this.el, 'hide');
	};
}

function removemargin(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el, args) {
		this.el = el;
		setTimeout( "g_triggers[" + this.trigger_id + "].go()", 0 );
	}
	this.go = function() {
		this.el.style.marginLeft = '0';
	};
}

function row_remover(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		this.el = el;
		var ids = args.split(/,/);
		this.row = document.getElementById(ids[0]);
		this.prev_row = document.getElementById(ids[1]);
		this.inp = document.getElementById(ids[2]);
		eval( "addEvent( el, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
	}
	this.onclick = function(e) {
		addClass( this.row, 'hide' );
		g_triggers[this.row.parentNode.trigger].fixheight(1);
		delClass( this.row, 'active-row' );
		addClass( this.prev_row, 'active-row' );
		var curEvent = ((typeof event == "undefined")? e: event);
		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
		else if (e.preventDefault) e.preventDefault(); // for DOM-compatible
		this.inp.set(0);
		updatechart(this.inp);
	}
}
function row_adder(trigger_id)
{
	this.trigger_id = trigger_id;
	this.init = function(el,args) {
		this.el = el;
		var ids = args.split(/,/);
		this.row = document.getElementById(ids[0]);
		this.prev_row = document.getElementById(ids[1]);
		eval( "addEvent( el, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
	}
	this.onclick = function(e) {
		delClass( this.row, 'hide' );
		g_triggers[this.row.parentNode.trigger].fixheight(1);
		for( var i=0; i<this.row.parentNode.childNodes.length; i++ ) {
			if( this.row.parentNode.childNodes[i].nodeName=='DIV' ) delClass(this.row.parentNode.childNodes[i],'active-row');
		}
		addClass( this.row, 'active-row' );
		delClass( this.prev_row, 'active-row' );
		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
		else if (e.preventDefault) e.preventDefault(); // for DOM-compatible
	}
}

function calc_sliderlock(trigger_id)
{
	this.trigger_id = trigger_id;
	
	this.init = function( el, args ) {
		this.el = el;
		this.default_setting = this.el.checked;
		this.sl = document.getElementById(args);
		eval( "addEvent( this.el, 'change', function(e) {g_triggers[" + this.trigger_id + "].onchange(e)})" );
		eval( "addEvent( this.el.parentNode, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
		eval( "this.el.reset = function() {g_triggers[" + this.trigger_id + "].reset()}" );
		setTimeout( "g_triggers[" + this.trigger_id + "].onchange()",0 );
		if( this.el.checked ) {
			addClass( this.el.parentNode, 'deflock_checked' );
		} else {
			delClass( this.el.parentNode, 'deflock_checked' );
		}
	}
	
	this.onchange = function(e) {
		this.sl.trigger.disable( this.el.checked );
	}
	
	this.onclick = function(e) {
		this.el.checked = !this.el.checked;
		if( this.el.checked ) {
			addClass( this.el.parentNode, 'deflock_checked' );
			this.el.parentNode.setAttribute( 'title', "Locked" );
		} else {
			delClass( this.el.parentNode, 'deflock_checked' );
			this.el.parentNode.setAttribute( 'title', "Unlocked" );
		}
		this.onchange(e);
	}
	
	this.reset = function() {
		this.el.checked = !this.default_setting;
		this.onclick(false);
	}
}

function checkbox(trigger_id)
{
	this.trigger_id = trigger_id;
	
	this.init = function( el, args ) {
		this.el = el;
		eval( "addEvent( this.el, 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
		var inp = el.getElementsByTagName( 'input' );
		this.inp = inp[0];
		eval( "addEvent( inp[0], 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
		eval( "addEvent( inp[0], 'change', function(e) {g_triggers[" + this.trigger_id + "].onchange(e)})" );
		var lbl = el.getElementsByTagName( 'label' );
		this.label = lbl[0];
		eval( "addEvent( lbl[0], 'click', function(e) {g_triggers[" + this.trigger_id + "].onclick(e)})" );
	}
	
	this.onchange = function(e) {
		if( this.inp.checked ) {
			addClass( this.el, 'checkbox_checked' );
		} else {
			delClass( this.el, 'checkbox_checked' );
		}
	}
	this.onclick = function(e) {
		var curEvent = ((typeof event == "undefined")? e: event);
		var srce = curEvent.currentTarget ? curEvent.currentTarget : window.event.srcElement;
		if( srce.id != this.inp.id && srce.id != this.label.id ) {
			this.inp.checked = !this.inp.checked;
		}
		this.onchange(e);
// 		if( typeof window.event != "undefined" ) window.event.returnValue = false; // IE
// 		if (e.preventDefault) e.preventDefault(); // for DOM-compatible
		if (e.stopPropagation) e.stopPropagation(); // for DOM-compatible
	}
}

