var init_common = null, common_data = null; //global.js fires warning in strict mode debuging if this is not defined

if( typeof(globals) == 'undefined' ) // make sure we don't clobber existing globals array if this file is accidentally included twice
{
		/*
		Prevent global variables from colliding with global DOM objects
		idea from: 
		http://developer.apple.com/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/Advanced/Advanced.html
		Added 10:40pm Sunday Feb 24th 2007
		*/
		
	var globals = {};
}

function getElementsByClass(searchClass,node,tag)
{
	var classElements = [];
	
	// 25 July .... check for string and if so use getEl string
	
	if( node && typeof(node) == 'string' ) // if node is '' (empty string) truth value is false and this is skipped
	{
			node = getEl(node); // getEl returns null if node does not exist
	}
	
	if ( node == null || node == '' )
	{
		node = document;
	}
	
	if ( typeof(tag) == 'undefined' )
	{
		tag = '*';
	}
	
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	
	for (var i = 0, j = 0; i < elsLen; i++) 
	{
		if ( pattern.test(els[i].className) ) 
		{
			classElements[j] = els[i];
			j++;
		}
	}
	
	return classElements;
}

/* toggle an element's display */
function toggle(obj) 
{
	var el = document.getEl(obj);
	
	if( !el )
	{
		return;
	}
	
	if ( el.style.display != 'none' ) 
	{
		el.style.display = 'none';
	}
	else 
	{
		el.style.display = 'block';
	}
}

/* insert an element after a particular node */
function insertAfter(parent, node, referenceNode) 
{
	parent.insertBefore(node, referenceNode.nextSibling);
}

function is_array(a)
{
// Added 11:50 25th April 2007
// from: http://www.planetpdf.com/developer/article.asp?ContentID=testing_for_object_types_in_ja
	// return ( a.constructor.toString().match(/array/i));  <--- dropped due to Safari and Konq returning function for constructor
	return !!( a && a.constructor == Array ); // see  http://www.optimalworks.net/blog/2007/web-development/javascript/array-detection
}

/* Array prototype, matches value in array: returns bool */
Array.prototype.in_array = function(val) 
{
	var i;
	
	for(i=0, j=this.length; i < j; i++) 
	{
		if(this[i] === val)
		{
			return true;
		}
	}
	
	return false;
};

Array.prototype.reduce=function(templateFunction) 
{
  var s = '';
  var tmp = [];
  
  for (var i=0, j=this.length; i<j; i++)
  {
   	s += templateFunction(this[i]);
  }
  
  return s;
};

Array.prototype.walk=function(templateFunction) 
{
  var tmp = [];
  
  for (var i=0, j=this.length; i<j; i++)
  {
   	tmp[i] = templateFunction(this[i]);
  }
  
  return tmp;
};

// from  http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Array.prototype.shuffle = function ()
{ 
        for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);
};

function deal(n) 
{
	var j, k, q = [];
	
	for (j = 0; j < n; j++) 
	{
		k = random(j + 1);
		q[j] = q[k];
		q[k] = j;
	}
	
	return q;
}

function getEl(el)
{   
	   if(document.getElementById && document.getElementById(el))
       {
		    	return document.getElementById(el);
       }

	   	// 25 July 2006 changed return value from false to null
	    return null;
}

function createEl(type,el_id,el_class)
{

	 var element;
	 
     if( !document.createElement )
	 {
	    return null;
	 }
	 
	 if( !type )
	 {
	 	alert( 'No element type set' );
	 }
	 
	 element = document.createElement(type);
	 
	 if( el_id )
	 {
	   	element.id = el_id;
	 }
	 
	 if( el_class )
	 {
	 	 element.className = el_class;
	 }
	 
	 return element;
}

function browser_obj()
{
	var ua = navigator.userAgent.toLowerCase();

	this.opera = ua.indexOf('opera')!=-1;
	this.konqueror = ua.indexOf('konqueror')!= -1;
	this.gecko = ua.indexOf('gecko')!=-1;
	this.ie = !this.gecko && !this.opera && !this.konqueror && ua.indexOf('msie') !=-1;
	this.ie5 = this.ie && ua.indexOf('msie 5.0') !=-1;
	this.ie55 = this.ie && ua.indexOf('msie 5.5') !=-1;
	this.ie6 = this.ie && ua.indexOf('msie 6.') !=-1;
	this.ie7 = this.ie && ua.indexOf('msie 7.') !=-1;
	this.opera7 = ua.indexOf('opera/7')!=-1;
	this.opera8 = ua.indexOf('opera/8')!=-1;
	this.name = navigator.appName;
	this.agent = ua;
	return this;
}

var browser = new browser_obj();

function new_image(img_src)
{
	var x = new Image();
	x.src = img_src;
	return x;
}  

function alter_links()
{
	if( !document.links.length ) return;
	
	if(!document.links[0].setAttribute ) return;
	
	for (var i=0; i<document.links.length; i++)  
   	{		
		if (document.links[i].getAttribute('class') == 'newWindow' || document.links[i].className == 'newWindow') 
   		{
			changeAllLinksWithClassToTargetBlanks(document.links[i]) 
		}
		
		if (document.links[i].getAttribute('class') == 'crypto' || document.links[i].className == 'crypto') 
   		{
			decrypt_links(document.links[i]) 
		}
	}
	
}
function changeAllLinksWithClassToTargetBlanks(link) 
{
	// from http://development.incutio.com/simon/targetBlankExperiment.html
	
 		  	link.setAttribute('target', '_blank');
		   	link.setAttribute('title', 'opens in new window');
			
}

function decrypt_links(link)
{
		var link_href = link.title;
		
		if( !link_href )
		{
			return;
		}
		
		regexp = /^(.+)$/;
		matches = link_href.match(regexp);

		if( ! matches || ! matches.length > 1 ) 
		{
			return;
		}
		
		link_href = encode(matches[1]);
		var orginal_link_text = link.firstChild.nodeValue;
		link.href = link_href;
		link.firstChild.nodeValue = link_href.replace(encode(':LDA38m'),'');
		link.title = 'Email ' + orginal_link_text;
}

function get_evt_targ(e)
{
	var evt = e || window.event;
	
	if( evt )
	{
		return evt.target || evt.srcElement;
	}
	
	return null;
}
 
function get_evt_targ_id(e)
{
		var el = get_evt_targ(e);
				
		if( el && el.id )
		{
			return el.id
		}
		
		return null;	
}

function get_mouse_coords(e)
{
	var evt = v(e);
		
	var x_coord = null;
	var y_coord = null;
	/* To be tested:    x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, 
	 * 
	 * from: http://www.webreference.com/programming/javascript/mk/column2/
	 * */
	if(evt)
	{
		if (evt.pageX) 	
		{
			x_coord = evt.pageX;
			y_coord = evt.pageY;	
		}
		else if (evt.clientX)
		{
			x_coord = evt.clientX + Math.max(document.documentElement.scrollLeft,document.body.scrollLeft);
			y_coord = evt.clientY + Math.max(document.documentElement.scrollTop,document.body.scrollTop);
		}
		else
		{
			x_coord = null;
			y_coord = null;
		}
	}
	
	return { x : x_coord, y : y_coord };
}

			



function getStyleById(id,prop,propNS)
{
	var el = document.getElementById(id);

	if(!el) 
	{
		return null;
	}
	
	var s;

	if( el.style[prop] ) 
	{
		return el.style[prop] 
	}

	if(el.currentStyle) 
	{
		s = eval("el.currentStyle." + prop);
		
		if((s != "") && (s !== null)) 
		{
			return s;
		}
	}
	
	if(document.defaultView && document.defaultView.getComputedStyle)
	{

	s = (document.defaultView.getComputedStyle(el, '') ) ? document.defaultView.getComputedStyle(el,'').getPropertyValue(propNS) : "";
	
		if((s != "") && (s != null)) 
		{
			return s;
		}
	}
	
	return null;

}

/*****************
The purge function takes a reference to a DOM element as an argument. 
It loops through the element's attributes. If it finds any functions, 
it nulls them out. This breaks the cycle, allowing memory to be reclaimed. 
It will also look at all of the element's descendent elements, and clear 
out all of their cycles as well. The purge function is harmless on Mozilla 
and Opera. It is essential on IE. The purge function should be called before 
removing any element, either by the removeChild method, or by setting the 
innerHTML property.

http://www.crockford.com/javascript/memory/leak.html

****************/
function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}
function create_char_list()
{
	var str = '';
	char_list = [];
	var chars = " -.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_@abcdefghijklmnopqrstuvwxyz"
	
	for(var i=0;i<chars.length;i++)
	{
		char_list[char_list.length] = chars.charCodeAt(i);
	}
	
	return char_list;
}

function encode(str_to_encrypt)
{
	if( !str_to_encrypt ) 
	{
		return null;
	}
	var forward = create_char_list();
	var reversed = forward.join(','); // break reference to chars so reverse() method does not effect both original and copy of chars
	reversed = reversed.split(',');
	reversed.reverse();
	var ret_list = [];
	ret_str = '';
	
	for(var i=0; i<str_to_encrypt.length; i++)
	{
		var curr_char_code = str_to_encrypt.charCodeAt(i);
		var found = 0;
		
		for(j=0; j<forward.length; j++)
		{
			if( forward[j] == curr_char_code )
			{
				//ret_list[ret_list.length] =  String.fromCharCode(reversed[j]);
				ret_str +=  String.fromCharCode(reversed[j]);
				found = 1;
				break;
			}
		}
		
		if( !found )
		{
			//ret_list[ret_list.length] = str_to_encrypt.charAt(i);
			ret_str += str_to_encrypt.charAt(i);
		}	
	}
	//return ret_list;
	return ret_str;	
}

function change_opacity(el,level)
{
	if( typeof(el) == 'string' )
	{
		el = getEl(el);
	}

	if( el == null || typeof(el) != 'object' ) // in javascriipt null is of type object
	{
		return;
	}

	if( typeof(el.style.opacity) != 'undefined' )
	{
		el.style.opacity = level/10;
	}
	else if( typeof(el.style.MozOpacity) != 'undefined' )
	{
		el.style.MozOpacity = level/10;
	}
	else if( typeof(el.style.khtmlOpacity) != 'undefined' )
	{
		el.style.KhtmlOpacity = level/10;	
	}
	else if( typeof(el.style.filter) != 'undefined')
	{
		el.style.filter = 'alpha(opacity="' + (level * 10 ) + '")';
	}
}

function debug(func,var_name,var_val,do_alert)
{
	var type = typeof(var_val);
	
	ret_val = 'In function <span  class="function">' + func + '</span> variable <span class="variable">'
	 + var_name + '</span> is of type <span  class="object">' + type + '</span>\n and has value:\n';
	
	if( type  == 'string' && var_val.length > 20 )
	{
		ret_val += "\n " + var_val;
	}
	else if( type  == 'object' )
	{
		for (var i in var_val )
		{
			ret_val +=  '\t' + i + ': ' + var_val[i] + '\n';
		}
	}
	else
	{
		ret_val += var_val;
	}
	
	if( do_alert )
	{
		alert(ret_val);
		return null;
	}
	else
	{
		// add styling in external CSS file for #debug
		if( !getEl('debug') )
		{
			var debug_el = createEl('div','debug');
			document.body.appendChild(debug_el);
		}
		
		debug_el = getEl('debug');
		debug_el.innerHTML = ret_val;
		debug_el.style.display = 'block';
		debug_el.onclick = function() { this.style.display = 'none' };
		return '\n\n' + ret_val;
	}
}

function stop_bubble(evt)
{
//	var el = get_evt_targ(evt);
	evt = v(evt);
	
	if (!evt)
	{
		return;
	}
	
	evt.cancelBubble = true;
	evt.returnValue = false;
	
	if( evt.preventDefault ) 
	{
		evt.preventDefault();
	}
	
	if( evt.stopPropagation )
	{
		evt.stopPropagation(); 
	}
}

function first_to_upper(str)
{	
	    var first_char = str.substring(0,1);
        var rest = str.substring(1);
        return first_char.toUpperCase() + rest;
}

function disable_text_selection(el)
{
	if( typeof(el) == 'string' )
	{
		el = getEl(el);
	}
	
	if( typeof(el) == null || typeof(el) != 'object' )
	{
		return;
	}

	if( typeof(el.onselectstart) != "undefined" )
	{
		el.onselectstart = function()
		{
			return false
		}
	}
	else if( typeof(el.style.MozUserSelect) != "undefined" )
	{
			el.style.MozUserSelect = 'none';
	} 
	else if( typeof(el.unselectable) != "undefined" )
	{
		el.unselectable = 'on';	
	}
	else
	{
		
	}
}
/*
As from Nov 11th 2007 trim functions now based on those found at 
http://www.hunlock.com/blogs/Ten_Javascript_Tools_Everyone_Should_Have

Added token replace as well as \s as above url
*/

String.prototype.trim = function(token) 
{
	if( typeof(token) == 'undefined' )
	{
		//s = '\\s'; // Sun 27th May 2007. Changed default val from ' ' to '\\s' so new lines are replaced in addition to spaces
		return this.replace(/^\s+|\s+$/g, "");
	}
	else
	{
		var regexp = new RegExp('^' + token + '+|' + token + '+$', 'g');
		return this.replace(regexp, "");
	}
}

String.prototype.ltrim = function(token) 
{
	if( typeof(token) == 'undefined' )
	{
		//s = '\\s'; // Sun 27th May 2007. Changed default val from ' ' to '\\s' so new lines are replaced in addition to spaces
		return this.replace(/^\s+/, "");
	}
	else
	{
		var regexp = new RegExp('^' + token + '+');
		return this.replace(regexp,"");
	}
}

String.prototype.rtrim = function(token)
{
   	if( typeof(token) == 'undefined' )
	{
		//s = '\\s'; // Sun 27th May 2007. Changed default val from ' ' to '\\s' so new lines are replaced in addition to spaces
		return this.replace(/\s+$/,"");
	}
	else
	{
		var regexp = new RegExp(token + '+$');
		return this.replace(regexp,"");
	}
}

// random funcs from http://www.merlyn.demon.co.uk/js-randm.htm
function random(x) 
{
    return Math.floor(x * (Math.random() % 1));
}

function random_num(min,max)
{
 	return min + random(max - min + 1);
}

function include_js_file(script_src)
{
	reg_exp = /\/([^\/]+)\..+$/; // match file basename without extension
	var script_id = script_src.match(reg_exp)[1];
	var head = document.getElementsByTagName('head')[0];
	
	if( (script = getEl(script_id)) )
	{
		if( navigator.userAgent.toLowerCase().indexOf('msie') != -1 )
		{
			purge(script); // see Crockford note in common.css
		}
		
		head.removeChild(script);
	}
	
	script = createEl('script',script_id ,'');
	script.type="text/javascript";
	script.defer = true;
	script.src = script_src;
	head.appendChild(script);
}

function v(ev) // returns event object. added Friday Nov 16 2007
{
	var e = null;
	try {e = ev || event;} catch(err){}	
	return e;
}

function GET(key) 
{
	 /** 
	 * returns query string values ala PHP's $_GET array.
	 * globals['_GET'] object created in /engine/js/data.php from $_GET array if present
	 * Returns empty string if globals['_GET'] object is not present or key is not present in globals['_GET']
	 */
	var val = '';
	
	if( typeof(globals) == 'object' )
	{
		var get_obj = globals['_GET'];
		
		if( get_obj && typeof(get_obj[key]) != 'undefined' )
		{
			val = decodeURIComponent(get_obj[key]);
			val = val.replace('+',' ');	
		}
	}
	
	return val;
}

if( typeof(window.encodeURIComponent) == 'undefined' && window.escape ) // for IE 5.0 which doesn't support encodeURIComponent()
{
	window.encodeURIComponent = function(str)
	{
		return escape(str);
	}
	
	window.decodeURIComponent = function(str)
	{
		return unescape(str);
	}
}

function check_default(val, type, default_val) // added April 2nd 2009
{
	return (typeof(val) == type) ? val : default_val;
}


if(!Array.prototype.push)
{
    Array.prototype.push = function(elem)
    {
        this[this.length] = elem;
    }
}
