/** 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 appendQuery( url, qs )
{
	return url + (url.match(/\?/) ? '&' : '?') + qs;
}

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


/** 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";
    }
}

/** 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();
	
	var g = " js random arg-something js gibber args-other";
	var x = g.split( /\bjs\b/ );
	//alert( x );
	for( var j=1; j<x.length; j++ )
	{
		//alert( regex.exec(x[j]) );
	}
	
	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 = '';
			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;
	};
}

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.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;
			}
			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="/images/indicator.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.others = args;
		this.el = el;
		this.el.trigger = this;
		this.redraw();
		eval( "addEvent( window, 'resize', function() { g_triggers["+ this.trigger_id +"].redraw(); }, false )" );
	};
	
	this.redraw = function() {
		calc_window_dimensions();
		var el_height = window_height;
		var res = this.others.split( /,/ );
		for( var i=0; i<res.length; i++ )
		{
			el_height -= document.getElementById( res[i] ).offsetHeight;
			
		}
		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';
	}
}

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', 'menubar=yes,toolbar=no,directories=no,location=no,scrollbars=yes' );
		return false;
	}
}
function closepopup()
{
	if( trigger_popup_window )
	{
		trigger_popup_window.close();
	}
}
