


// --- Tooltip Setup --- //

var tr_leftOffset = 57; //Distant of carrot point on toolbar graphic from left edge
var tr_tt_max_time = 8; //Max time tooltip will stay open
var tr_tt_to;
var tr_tt;
var tr_tt_parent;

function setupTooltips(ctn_id, obj) {
	if (ctn_id) {
		ctn = $i( ctn_id );
	} else if (obj) {
		ctn = obj;	
	} else {
		ctn = $i('tr_main');	
	}
	tooltip = getElementsByClassName( $i( ((ctn_id)?(ctn_id):('tr_main')) ) , 'span' , 'tr_tooltip' );
	for(var i=0; i<tooltip.length; i++) {
		if (tooltip[i] && tooltip[i].getAttribute('rendered')!='true') {
			tooltip[i].setAttribute('rendered', true);
			t = tooltip[i].innerHTML;
			tooltip[i].innerHTML = '';
			tooltip[i].appendChild( createNode('div', {'class':'tr_tooltip_mid','innerHTML':t}) );
			tooltip[i].appendChild( createNode('div', {'class':'tr_tooltip_btm'}) );
			tooltip[i].parentNode.onmouseover = showTooltip;
			tooltip[i].parentNode.onmousemove = moveTooltip;
			tooltip[i].parentNode.onmouseout = closeTooltip;
			tooltip[i].parentNode.className += ' tr_tooltip_parent';
		}
	}
}
function showTooltip(e) {
	tooltip = getElementsByClassName( this , 'span' , 'tr_tooltip' );
	
	if (tooltip[0]) {
		if (tooltip[0] != tr_tt) {
			closeTooltip();
			tooltip[0].style.display = 'block';
			tooltip[0].className = 'tr_tooltip_on';
			tr_tt = tooltip[0];
			
			//move to top level of DOM
			tr_tt_parent = this;
			document.body.appendChild(tr_tt);
		}
		clearTimeout(tr_tt_to);
		tr_tt_to = setTimeout('closeTooltip()', tr_tt_max_time * 1000);
	}
}
function moveTooltip(e){
	xcoord=15; //offset from cursor
	ycoord=15; //offset from cursor
	if (typeof e != "undefined"){
		xcoord+=e.pageX;
		ycoord+=e.pageY;
	}
	else if (typeof window.event !="undefined"){
		xcoord+=truebody().scrollLeft+event.clientX;
		ycoord+=truebody().scrollTop+event.clientY;
	}
	if (tr_tt && tooltip[0]) {
		var maxRight = document.body.clientWidth - tooltip[0].clientWidth;
		if (xcoord > maxRight) {
			xcoord = maxRight;
		}
		
		tooltip[0].style.left 	= xcoord + 'px';
		tooltip[0].style.top 	= ycoord + 'px';
	}
}
function closeTooltip() {
	if (tr_tt) {
		tr_tt_parent.appendChild(tr_tt);
		tr_tt.className = 'tr_tooltip';
		tr_tt.style.display = 'none';
		tr_tt = null;
	}
}
function truebody(){
	return (!window.opera && document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}




// --- Tab Setup --- //
function tr_Dataset_Tabs(id, url, postVars, o) {
	this.id = id;
	this.dset = $i(id);
	this.self = this;
	this.content = new Object();
	this.tabs = new Object();
	this.dropdowns = new Object();
	this.calendars = new Object();
	this.o = o;
	this.init();
	
	this.url = ((url)?(url):('/get_tab.php')); //default ajax handler
	
	this.postVars = postVars;
}
tr_Dataset_Tabs.prototype = {
	
	init : function() {
		// Set Events for when tabs are clicked
		var tabBars = getElementsByClassName( this.dset , 'div' , 'tr_tabbar' );
		var tabBar = tabBars[0];
		
		if (tabBar) {
			var tabUL = tabBar.getElementsByTagName('UL');
			if (!tabUL[0]) {
				this.tabs['default'] = false;
				this.selectedContentName = 'default';
			} else {
				var tabs = tabUL[0].getElementsByTagName('LI');
				for(var i=0; i<tabs.length; i++) {
					if (tabs[i]) {
						var selfSet = this.self;
						tabs[i].onclick = function() { selfSet.SelectTab(this, selfSet) }
						this.tabs[ tabs[i].getAttribute('content') ] = tabs[i];
						
						if (tabs[i].className.match('tr_selected')) {
							this.selectedTab = tabs[i];
							this.selectedContentName = tabs[i].getAttribute('content');
						}
					}
				}
			}
		}
		
		//Get Current Content Referance
		if (this.selectedContentName) {
			var Panels = getElementsByClassName( this.dset , 'div' , 'tr_set_panel' );
			var contentContainer = Panels[0];
			
			//Wrap a referanceable wrapper around the current content
			if (contentContainer.getAttribute('tabs') == 'preset') {				
				//Prefill existing tab content
				for(i in this.tabs) {
					if ( $i('tr_tab_'+i) ) {
						this.content[ i ] = $i('tr_tab_'+i);
					}
				}
				
				//Set starting values			
				this.content[this.selectedContentName].style.display = 'block';
				this.contentContainer = contentContainer;
			} else {
				var newContentContainer = createNode('div', {'class':'tr_set_panel'});
				this.dset.appendChild( newContentContainer );
				newContentContainer.appendChild( contentContainer );
				contentContainer.className = '';
			
				this.content[this.selectedContentName] = contentContainer;
				this.contentContainer = newContentContainer;
			}
		}
		
		if (this.o && this.o.eventInitFinished) { this.o.eventInitFinished(this); }
	},
	
	SelectTab : function(li, obj) {
		var contentName = li.getAttribute('content');
		if (contentName != obj.selectedContentName) {
			if (!obj.content[ contentName ] || this.tabs[contentName].getAttribute('d')=='true') {
				obj.LoadTab( contentName );
			} else {
				obj.SwitchToTab(contentName);
			}
		}
	},
	
	SwitchToTab : function(c) {
		this.selectedTab.className = this.selectedTab.className.replace('tr_selected', '');
		this.content[ this.selectedContentName ].style.display = 'none';
		
		this.selectedTab = this.tabs[ c ];
		this.selectedTab.className += ' tr_selected';
		this.selectedContentName = c;
		this.content[ c ].style.display = 'block';

		if (this.o && this.o.eventSwitchToTab) { this.o.eventSwitchToTab(this); }
	},
	
	LoadTab : function(c, url, noSpinner) {
		if (!this.loadingContent) {
			if (!noSpinner) {
				this.Spinner = this.CreateSpinner( this.contentContainer, ((this.tabs[c])?(this.tabs[c].firstChild.innerHTML):('')) );
			}
			
			this.loadingContent = c;
			var selfSet = this.self;
			var A = new Ajax();
			A.fire( ((url)?(url):(this.url)) , function(r) { selfSet.LoadTabReceived(r, selfSet) }, this.postVarStr());
		}
	},
	
	LoadTabReceived : function(r, obj) {
		if (r != '-1') {
			if (!obj.content[ obj.loadingContent ]) {
				var newContent = createNode('div');
				newContent.style.display = 'none';
				obj.contentContainer.appendChild( newContent );
				obj.content[ obj.loadingContent	] = newContent;
			}	
			obj.content[ obj.loadingContent	].innerHTML = r;
			obj.SwitchToTab(obj.loadingContent);	
			setupTooltips( null, obj.content[ obj.loadingContent ] );
			
			if (obj.Spinner) { obj.Spinner.parentNode.removeChild(obj.Spinner); obj.Spinner = null; }
			
			obj.tabs[ obj.loadingContent ].setAttribute('d', false);
			obj.loadingContent = null;
		}
	},
	
	postVarStr : function() {			
		var qStr = 'c='+this.loadingContent;
		for(i in this.dropdowns) {
			qStr += '&' + i + '=' + this.dropdowns[i].obj.value;
		}
		for(i in this.calendars) {
			dateParts = this.calendars[i].cal.o;
			qStr += '&' + i + '_y' + '=' + dateParts.y;
			qStr += '&' + i + '_m' + '=' + dateParts.m;
			qStr += '&' + i + '_d' + '=' + dateParts.d;
		}		
		postVars = this.postVars;
		for(var i in postVars) {
			qStr += '&' + i + '=' + postVars[i];
		}
		return qStr;
	},
	
	CreateSpinner : function(ctn, name) {	
		if (!this.Spinner) {
			
			ctn.style.position = 'relative';
			
			var width = ctn.offsetWidth;
			var height = ctn.offsetHeight;
			var sty = 'width:'+width+'px;height:'+height+'px';
		
			var Spinner = createNode('div', {'class':'tr_loading','style':sty});
			var SpinnerFill = createNode('div', {'class':'tr_loading_fill','style':sty});
			var SpinnerSpin = createNode('div', {'class':'tr_loading_spinner','style':sty});
			var SpinnerTxt = createNode('div', {'class':'tr_loading_txt','style':'top:'+(height / 2 + 10)+'px;width:'+width+'px;'});
			
			SpinnerTxt.innerHTML = 'Loading '+name+'...';
			Spinner.appendChild( SpinnerFill );
			Spinner.appendChild( SpinnerSpin );
			Spinner.appendChild( SpinnerTxt );
			ctn.appendChild( Spinner );
			
			return Spinner;
		} else {
			return this.Spinner;
		}
	},
	
	
	// --- Handle Dropdowns --- //
	
	/*
	_init_dropdown
	Arguments:
	id - id of select element
	method - what to do onchange
		'reload' => reloads page or posts GET to page supplied by url in action (default)
		'ajax'	=> replaces content inside currently opened tab content
		'function' => run javascript supplied by action
	action - 
		if method = reload
			str URL (default: current page)
		if method = ajax
			str URL (default: dataset's url)
		if method = function
			function
	*/	
	_init_dropdown : function(id, method, action, postVars) {
		newDrop = new Object();
		newDrop.id = id;
		newDrop.obj = $i(id);
		newDrop.method = ((method)?(method):('reload'));
		if (action) {
			newDrop.action = action;
		} else {
			switch(newDrop.method) {
				case('reload'):
					var l = document.location.href.split('?');
					newDrop.action = l[0];
					break;
				case('ajax'):
					newDrop.action = this.url;
					break;
			}
		}
		newDrop.postVars = ((postVars)?(postVars):(new Object()));
		
		var selfSet = this.self;
		newDrop.obj.onchange = function(e) { selfSet.dropdownChange(this, selfSet); }
		
		this.dropdowns[ id ] = newDrop;
	},
	
	dropdownChange : function(el, Obj) {
		var o = Obj.dropdowns[el.id];
		switch(o.method) {
			case('reload'):
				this.loadingContent = this.selectedContentName;
				document.location.href = o.action + '?' + Obj.postVarStr(  );
				break;
			case('ajax'):
				Obj.DirtyTabs();
				Obj.LoadTab( Obj.selectedContentName , o.action );
				break;
			case('function'):
				o.action(el.value);
				break;
		}
	},

	_init_date : function(id, method, action, opts, postVars) {
		newDate = new Object();
		newDate.id = id;
		newDate.obj = $i(id);
		newDate.method = ((method)?(method):('reload'));
		newDate.o = opts;		
		
		if (action) {
			newDate.action = action;
		} else {
			switch(newDate.method) {
				case('reload'):
					var l = document.location.href.split('?');
					newDate.action = l[0];
					break;
				case('ajax'):
					newDate.action = this.url;
					break;
			}
		}
		newDate.postVars = ((postVars)?(postVars):(new Object()));
		
		
		//Get Valid Dates
		newDate.times = parseTimes(opts.times);
		
		//Init Calendar		
		newDate.cal = new shower_calendar( {
			autofill:false,
			output:$i(id+'_cal_wrapper'),
			openclose_toggle:$i(id+'_field'),
			dateInput:$i(id+'_input'),
			filters:{a:dateFilter},			
			clickEvent:this.dateChange,
			eventArgs:{tabObj:this,dateObj:newDate}
		} );

		
		this.calendars[ id ] = newDate;
	},
	
	selectDate : function(id, y, m, d) {
		this.calendars[ id ].cal.o.y = y;
		this.calendars[ id ].cal.o.m = m;
		this.calendars[ id ].cal.o.d = d;
		this.dateChange(null, null, null, null, null, {dateObj:this.calendars[ id ],tabObj:this}, true);
	},
	
	dateChange : function(y, m, d, a, calObj, eventArgs, force) {
		A = eventArgs;
		if (force || a.className.match('tr_active')) {
			
			if (calObj) {
				calObj.o.y = y;
				calObj.o.m = m;
				calObj.o.d = d;
			}
			
			switch(A.dateObj.method) {
				case('reload'):
					A.tabObj.loadingContent = A.tabObj.selectedContentName;
					document.location.href = A.dateObj.action + '?' + A.tabObj.postVarStr(  );
					break;
				case('ajax'):
					A.tabObj.DirtyTabs();
					A.tabObj.LoadTab( A.tabObj.selectedContentName , A.dateObj.action );
					break;
				case('function'):
					A.dateObj.action(y,m,d);
					break;
			}
			return false;
		}
		return true;
	},
	
	dateFilter : function(a, A) {
		var Y = a.getAttribute('year');
		var m = a.getAttribute('month');
		var d = a.getAttribute('day');
	
		if (A.dateObj.times[Y] && A.dateObj.times[Y][m] && A.dateObj.times[Y][m][d]) {
			a.className = 'tr_active';
		}

        return a;
	},
	
	DirtyTabs : function() {
		for(i in this.tabs) {
			if (this.tabs[i]) {
				this.tabs[i].setAttribute('d', true);
			}
		}
	}
}

var filteredRowsGroupLinks = {};
function tr_FilterRowsByColumnIndex(groupName, ctn, index, value, filterLink) {
	var curSelected = getElementsByClassName(filterLink.parentNode.parentNode, 'li', 'tr_selected')[0];
	if (curSelected) { Removeclass( curSelected, 'tr_selected' ); }
	Addclass(filterLink.parentNode, 'tr_selected');
	
	filteredRowsGroupLinks[ groupName ] = {
		link	:	filterLink,
		index	:	index,
		value	:	value
	};
	
	var TRs = ctn.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
	var nullValue = navigator.appName == 'Microsoft Internet Explorer' ? 'block' : null;
	for(var i in TRs) {
		if (TRs[i].cells) {
			TRs[i].style.display = (!value || TRs[i].cells[index].innerHTML == value) ? nullValue : 'none';
		}
	}
}

// -- Accordion -- //

if ($i('tr_sidebar')) { 
	var sets, i, j, bar, chooser, items, folding;
	if (getElementsByClassName($i('tr_sidebar'), 'div', 'tr_folding')[0]) {
		sets = getElementsByClassName($i('tr_sidebar'), 'div', 'tr_dataset');
		for(i in sets) {
			bar = getElementsByClassName(sets[i], 'a', 'tr_show')[0];
			chooser = getElementsByClassName(sets[i], 'ul', 'tr_chooser')[0];
			toggle = getElementsByClassName(bar.parentNode, 'span', 'tr_toggle')[0];
			
			//starting
			if (sets[i].className.match('tr_hide')) {
				toggle.innerHTML = 'show';
			} else {
				toggle.innerHTML = 'hide';
			}
			
			bar.onclick = function(e) { 
				var set = this.parentNode.parentNode; 
				var toggle = getElementsByClassName(this.parentNode, 'span', 'tr_toggle')[0];
				if (set.className.match('tr_hide')) {
					toggle.innerHTML = 'hide';
					set.className = set.className.replace('tr_hide', '');
				} else {
					toggle.innerHTML = 'show';
					set.className += ' tr_hide';	
				}
			}
			
			//disable text selection/highlight
			bar.onselectstart = function() {
				return false;
			};
			bar.unselectable = "on";
			bar.style.MozUserSelect = "none";
		}
	}
}


// -- Sortable Tables -- //

function sortableTable(id, o) {
	this.id = id;
	this.table = $i(id);
	this.o = o;
	this.thead = this.table.getElementsByTagName('thead')[0];
	this.tbody = this.table.getElementsByTagName('tbody')[0];
	
	this.sortDirDefault = 'ASC';
	this.sortDirIndex = {DESC:-1, ASC:1}
	this.sortDir = this.o.startDir ? this.o.startDir * -1 : this.sortDirIndex[ this.sortDirDefault ];
	
	if (!this.o.zebraCustom)
		this.o.zebraCustom = function(el){return true;}

	this.headerLinks = {};
	
	this._init();
}
sortableTable.prototype = {
	
	_init : function() {
		var self = this;
		var sortLink, firstSortLink, index;
		var As = this.thead.getElementsByTagName('a');
		for(var i=0; i < As.length; i++) {
			if (As[i] && As[i].parentNode.tagName == 'TH') {
				As[i].onclick = function() { self.sort(this); }
				index = As[i].parentNode.cellIndex + ( As[i].getAttribute('sortIndexOffset') ? As[i].getAttribute('sortIndexOffset') * 1 : 0 );
				this.headerLinks[index] = As[i];
				
				if (As[i].getAttribute('sortDefault') || this.o.defaultSortIndex == index) {					
					sortLink = As[i];
				}
				if (!firstSortLink) { firstSortLink = As[i]; }
			}
		}
		if (sortLink) { this.sort(sortLink, true); } else {
		this.sort(firstSortLink, null, true); }
	},
	
	sort : function(sortLink, index, skipSorting) { //sortDirDefault
		if (!sortLink) { 
			sortLink = this.headerLinks[ index ];
		}
		
		var sortArray = [];
		var value, valueSecond, i;
		
		var index = sortLink.parentNode.cellIndex + ( sortLink.getAttribute('sortIndexOffset') ? sortLink.getAttribute('sortIndexOffset') * 1 : 0 );
		var indexSecond = sortLink.getAttribute('sortSecondary');
		var numeric = sortLink.getAttribute('sortNumeric');
		
		//remove header styles
		if (this.currentTH) {
			Removeclass( this.currentTH , 'tr_sort_' + this.sortDir );	
		}
		
		
		//Get Data		
		var TRs = this.tbody.getElementsByTagName('tr');
		for(i=0; i < TRs.length; i++) {
			//set up new classes - remove old classes
			if (this.currentColumn != index) {
				if (this.currentColumn >= 0) {
					Removeclass( TRs[i].cells[this.currentColumn] , 'tr_sorted' );
				}
				Addclass( TRs[i].cells[index] , 'tr_sorted' );
			}
						
			//prepare for sorting
			value = TRs[i].cells[index].getAttribute('sortValue');
			if ( indexSecond ) {
				valueSecond = TRs[i].cells[indexSecond].getAttribute('sortValue');
			}
			if (numeric) { value *= 1; }
			
			sortArray[ i ] = { 
				value		:	(value || value == 0) ? value : TRs[i].cells[index].innerHTML ,
				valueSecond : 	indexSecond ? valueSecond : null,
				tr			:	TRs[i],
				self		:	this
			};
		}
		
		//Sort Data
		if (!skipSorting) {
			if (this.currentColumn == index) {
				this.sortDir *= -1;
			} else {
				this.sortDir = this.sortDirIndex[ sortLink.getAttribute('sortDirDefault') ? sortLink.getAttribute('sortDirDefault') : this.sortDirDefault ];
			}
			
			if (sortLink.getAttribute('sortSecondary')) {
				this.sortSecondary = sortLink.getAttribute('sortSecondary');
				sortArray.sort( this.sort_funcWithDepth );				
			} else {
				sortArray.sort( this.sort_func );
			}
			
			//Rearrange Rows
			for(i=0; i < sortArray.length; i++) {
				this.tbody.appendChild( sortArray[i].tr );	
			}
		
			//Update Table Coloring
			if (!this.o.skipAltShading) this.reZebra();
		}
		
		//Update header
		Addclass( sortLink.parentNode , 'tr_sort_' + this.sortDir );
		
		//Store Currents
		this.currentColumn = index;
		this.currentTH = sortLink.parentNode;
		
		//Event
		if (this.o && this.o.eventSorted) { this.o.eventSorted(this); }
	},
	
	sort_func : function(a,b) {
		return ((a.value < b.value) ? -1 : ((a.value > b.value) ? 1 : 0)) * a.self.sortDir;
	},	
	
	sort_funcWithDepth : function(a,b) { //could use some optimization all over
		var r = ((a.value < b.value) ? -1 : ((a.value > b.value) ? 1 : 0)) * a.self.sortDir;
		if (r == 0) {
			((a.valueSecond < b.valueSecond) ? -1 : ((a.valueSecond > b.valueSecond) ? 1 : 0)) * a.self.sortDir;
		}
		return r;
	},	
	
	reZebra : function() {			
		// do alt shading
		var TRs = this.tbody.getElementsByTagName('tr');
		var n = 0;
		for(var i in TRs) {
			if (TRs[i].tagName == 'TR' && this.o.zebraCustom(TRs[i])) {
				if ( n%2 != 0) {
					Addclass( TRs[i] , 'tr_alt' );
				} else {
					Removeclass( TRs[i] , 'tr_alt' );
				}
				n++;
			}
		}
	}
	
}


// --- Ajax --- //
function Ajax() {}
Ajax.prototype = {
	
	GetXmlHttp : function () {
		{var ajax=null;try{ajax=new XMLHttpRequest();}
		catch(e){ajax=null;}
		try{if(!ajax)ajax=new ActiveXObject("Msxml2.XMLHTTP");}
		catch(e){ajax=null;}
		try{if(!ajax)ajax=new ActiveXObject("Microsoft.XMLHTTP");}
		catch(e){ajax=null;}
		return ajax;}
	},
	
	fire : function (uri, callback, parameters) {
		this.callback = callback;
		this.transport = this.GetXmlHttp();
		this.osc(this);
		this.transport.open("POST",uri,true);
		this.transport.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.transport.send(parameters);
	},
	
	osc : function (ajaxObj) {
		ajaxObj.transport.onreadystatechange = function() {
			try {
				switch(ajaxObj.transport.readyState) {
					case(4): ajaxObj.callback(ajaxObj.transport.responseText );
				}
			}
			catch( e ) { //server error
			}
		}	
	},
	 
	fireForm : function (id, callback) {
		if ($(id).getAttribute('enctype') == 'multipart/form-data') {
			alert('Use cProcess for file transfers');
		} else {
			this.fire( $(id).action, callback, this.formParse( id ) );		
		}
	},
	
	abort : function() {
		if (this.transport && this.transport.readyState != 0) { //abort current run and overwrite
			this.transport.onreadystatechange = function(){};
			this.transport.abort();
		}
	}
}

// --- Promo Content Setup --- //
function tr_Promo(id, attributes, postVars) {
	this.id = id;
	this.promo = $i(id);
	this.self = this;	
	this.attributes = attributes;
	this.postVars = postVars;
	this.url = this.attributes.url ? this.attributes.url : '/get_promo.php'; //default ajax handler	
	this.name = this.attributes.name ? this.attributes.name : 'game'; //default label for spinner
	this.pointer = this.attributes.pointer ? this.attributes.pointer : 0;
	
	this.items = new Object();
	
	this.init();
}
tr_Promo.prototype = {
	
	init : function() {
		this.prev = getElementsByClassName( this.promo , 'a' , 'tr_promo_prev' )[0];
		this.next = getElementsByClassName( this.promo , 'a' , 'tr_promo_next' )[0];
		
		var self = this.self;
		this.next.onclick = function(e){ self.move(this); };
		this.prev.onclick = function(e){ self.move(this); };
		
		
		this.list = this.promo.getElementsByTagName('UL')[0];
		var lis = this.promo.getElementsByTagName('LI');
		this.listSize = lis.length;
	},
	
	move : function(obj) {
		if (obj == this.next) {
			var p = this.pointer + this.listSize;			
		} else if (obj == this.prev) {
			var p = this.pointer - this.listSize;
		}
		
		var self = this.self;
		var A = new Ajax();
		this.pointerSet = p;
		
		LIs = this.promo.getElementsByTagName('LI');
		for(i in LIs) {
			if (LIs[i].tagName == 'LI') {
				this.CreateSpinner(LIs[i], this.name);
			}
		}
		
		A.fire( this.url , function(r) { self.databack(r, self) }, 'p='+p+'&n='+this.listSize+this.postVarStr());
	},	
	
	databack : function(r, self) {
		this.list.innerHTML = r;
		this.pointer = this.pointerSet;
	},
	
	postVarStr : function() {			
		var qStr = '';
		for(var i in  this.postVars) {
			qStr += '&' + i + '=' +  this.postVars[i];
		}
		return qStr;
	},
	
	CreateSpinner : function(ctn, name) {	
		if (!this.Spinner) {
			
			ctn.style.position = 'relative';
			
			var width = ctn.offsetWidth;
			var height = ctn.offsetHeight;
			var sty = 'width:'+width+'px;height:'+height+'px';
			
			var txtTop = (header / 2) + 10;
			if (txtTop > 200) { txtTop = 200; }
		
			var Spinner = createNode('div', {'class':'tr_loading','style':sty});
			var SpinnerFill = createNode('div', {'class':'tr_loading_fill','style':sty});
			var SpinnerSpin = createNode('div', {'class':'tr_loading_spinner','style':sty});
			var SpinnerTxt = createNode('div', {'class':'tr_loading_txt','style':'top:'+txtTop+'px;width:'+width+'px;'});
			
			SpinnerTxt.innerHTML = 'Loading '+name+'...';
			Spinner.appendChild( SpinnerFill );
			Spinner.appendChild( SpinnerSpin );
			Spinner.appendChild( SpinnerTxt );
			ctn.appendChild( Spinner );
			
			return Spinner;
		} else {
			return this.Spinner;
		}
	}
	
}

// -- Spinner Object -- //

function Spinner(ctn, label, noPrefix) {
	this.ctn = ctn;
	this.label = (!noPrefix ? 'Loading ' : '') + (label?label:'') + '...';
	this.create();
}

Spinner.prototype = {

	create : function() {
			
		this.ctn.style.position = 'relative';
		
		var width = this.ctn.offsetWidth ? this.ctn.offsetWidth : this.ctn.defaultWidth ?  this.ctn.defaultWidth : 0;
		var height = this.ctn.offsetHeight ? this.ctn.offsetHeight : this.ctn.defaultHeight ?  this.ctn.defaultHeight : 0;
		var sty = 'width:'+width+'px;height:'+height+'px';
	
		var y = 38; //(height / 2 + 10);
		var Spinner = createNode('div', {'class':'tr_loading','style':sty});
		var SpinnerFill = createNode('div', {'class':'tr_loading_fill','style':sty});
		var SpinnerSpin = createNode('div', {'class':'tr_loading_spinner','style':'width:'+width+'px;height:55px'});
		var SpinnerTxt = createNode('div', {'class':'tr_loading_txt','style':'top:'+y+'px;width:'+width+'px;'});
		
		SpinnerTxt.innerHTML = this.label;
		Spinner.appendChild( SpinnerFill );
		Spinner.appendChild( SpinnerSpin );
		Spinner.appendChild( SpinnerTxt );
		this.ctn.appendChild( Spinner );
		
		this.spinner = Spinner;
		this.loading = true;
	},
	
	destroy : function() { 
		this.loading = false;
		try {
			return this.ctn.removeChild( this.spinner );
		} catch(err) { }
	}
	
}

// --- Chooser --- //


function GC( vars ) {
	this.gc = $i( vars.id );
	this.scroll_length = vars.scroll_length ? vars.scroll_length : 0.3; //length of scroll in seconds
	this.offset = 0;
	this.dest = 0;
	this.dim = 'tr_dim';
	this.o = vars;
	this.nav = {};
	this.tiles = {};
	this.c = 0;
	
	this._init();
}
GC.prototype = {
	
	_init : function() {
		var self = this;
		
		this.wrapper = getElementsByClassName( this.gc, 'div', 'tr_gc_wrapper' )[0];
		this.next = getElementsByClassName( this.gc, 'a', 'tr_gc_next' )[0];
		this.prev = getElementsByClassName( this.gc, 'a', 'tr_gc_prev' )[0];
		this.list = this.gc.getElementsByTagName( 'UL' )[0];
		
		if (this.o.navId) {
			var c = 0;
			var LIs = $i(this.o.navId).getElementsByTagName('a');
			for(var i in LIs) {
				if (LIs[i] && LIs[i].tagName == 'A') {
					this.nav[c] = LIs[i];
					this.nav[c].setAttribute('c', c); 
					this.nav[c].onclick = function() { self.navClick(this);	clearInterval( self.auto_TO ); }
					c++;
				}
			}
		}
		var c = 0;
		var LIs = this.list.getElementsByTagName('li');
		for(var i in LIs) {
			if (LIs[i] && LIs[i].parentNode == this.list) {
				this.tiles[c] = LIs[i];
				this.tiles[c].setAttribute('c', c);
				c++;
			}
		}
		this.total = c;
		
		this.next.onclick = function() { if (self.isLongEnough()) { self.scrollGo(-1);	clearInterval( self.auto_TO ); } }
		this.prev.onclick = function() { if (self.isLongEnough()) {  self.scrollGo(1);	clearInterval( self.auto_TO ); } }
		
		this.T = new Tween(this.list.style,'left',Tween.regularEaseOut,this.list.style.left.replace('px','')*1,this.list.style.left.replace('px','')*1,0.3,'px');
		
		this.scrollGoSelected();
		
		if (this.o.autoAdvance) {
			this.auto_TO = setInterval(function() { self.scrollGo(-1); },this.o.autoAdvance);				
		}
		
	},
	
	scrollGo : function(direction, d) {

		if (this.T) {
			this.offset = this.dest;
			this.list.style.left = this.offset + 'px';
		}
		
		if (direction) {
			this.updateC( this.c + direction*-1 );
		}
	
		this.dest = d || d==0 ? d : this.wrapper.offsetWidth * direction + this.offset; 	
	
		this.gameWidth = this.tiles[0].offsetWidth; 	
		this.maxWidth = this.total * this.tiles[0].offsetWidth - this.wrapper.offsetWidth;	

		if (this.dest > 0) { this.dest = 0; }	
		if (this.dest < -1 * this.maxWidth ) { this.dest = -1 * this.maxWidth; }
		
		var self = this;
		var dest = this.dest;
		
		this.T.onMotionFinished = function() { self.scrollCheckSides(); }
		this.T.continueTo(this.dest, 0.3);	
		
	},

	scrollCheckSides : function() {
		this.offset = this.list.style.left.replace('px','') * 1;
		
		if (this.offset  >= 0) {	
			Addclass( this.prev, this.dim );	
		} else {
			Removeclass( this.prev, this.dim );	
		}

		if ( this.offset <= -1 * this.maxWidth) {	
			Addclass( this.next, this.dim );	
		} else {	
			Removeclass( this.next, this.dim );	
		}
		
		if ( !this.isLongEnough() ) {
			Addclass( this.next, this.dim );			
		}
		
		this.wrapper.style.visibility = 'visible';	
	},	

	scrollGoSelected : function() {
	
		var sel = getElementsByClassName( this.list, 'li', 'tr_selected' )[0];
	
		if (sel && this.isLongEnough()) {
			
			this.scrollGoTo( sel );
	
		}
		
		this.scrollCheckSides();
	
	},
	
	scrollGoTo : function(sel) {
		width = this.list.getElementsByTagName('LI')[0].offsetWidth;
		ParCoords = findPos( this.wrapper );	
		coords = findPos( sel );	
		//alert( '('+ParCoords[0] +'-'+ coords[0] + ' | ' + this.wrapper.offsetWidth + ' / ' +  2 + ' - ' + width + ' / ' + 2 + ')' );	
		this.scrollGo(null,  this.offset + (ParCoords[0] - coords[0] + this.wrapper.offsetWidth / 2 - width/2) );
		
		this.updateC( sel.getAttribute('c') );
	},
	
	updateC : function(c) {
		if (this.nav && this.nav[ c ]) {
			Removeclass(this.nav[ this.c ] , 'tr_selected' );
			Addclass(this.nav[ c ] , 'tr_selected' );
			this.c = c*1;
		}
	},
	
	//
	
	isLongEnough : function() {
		return !( this.o.maxShow && this.total < this.o.maxShow );
	},
	
	//
	
	navClick : function(a) { //alert(a.getAttribute('c') + ' | ' + this.tiles[ a.getAttribute('c') ].innerHTML);
		this.scrollGoTo( this.tiles[ a.getAttribute('c') ] );
	}

	
}


// - Split Selector - //

function Split_Selector(vars) {
	this.wrapper = $i( vars.id );
	this._init();
}
Split_Selector.prototype = {

	_init: function() {
		var self = this;
		
		this.selectors = {};
		var LI = this.wrapper.getElementsByTagName('LI');
		
		for(var i in LI) {
			if (LI[i].parentNode && LI[i].parentNode.tagName == 'UL') {
				if (LI[i].className.match('tr_selected')) {
					this.selected = LI[i];
					this.selected.style.borderRightWidth='0px';
				}
				LI[i].onmouseover = function() { self.select(this); }
			}
		}
	},
	
	select : function(obj) { 
		var maxCheckDepth = 10;
		var i = 0;
		while(obj.tagName != 'LI' && i < maxCheckDepth) {
			obj = obj.parentNode;
			i++;
		}
		if (obj.tagName == 'LI') {
			if (this.selected) { 
				Removeclass( this.selected , 'tr_selected' );
				this.selected.style.borderRightWidth='1px';
			}
			Addclass( obj , 'tr_selected' );
			obj.style.borderRightWidth='0px';
			this.selected = obj;
		}		
	}
	

}



// -- Popup -- //

function tr_pop(o) {
	
	// Set Defaults
	this.o = {
		autoShow 		:	true,
		showClose		:	true,
		showBlack		:	true,
		frameBorder		:	4,
		absolute		:	false,
		//parent		:   defaults to use the window, set this (supply element) to make popup appear inside an element only
				
		type			:	'blank' //see below for types in format of function: loadType_TYPENAME 
	}
	// Override Defaults
	for(var i in o) {
		this.o[i] = o[i];	
	}
	
	// Init Objects
	this.e = {};
	
	this._init();
}
tr_pop.prototype = {
	
	_init : function() {		
		
		this.buildBasic();
		
		this['loadType_'+this.o.type]();		
		
		if (this.o.header)
		{
			this.e.header = createNodeN('h5', {'class':'fc pop_header', innerHTML:this.o.header});
			this.e.content.insertBefore( this.e.header, this.e.content.firstChild );
			Cufon.refresh();
		}
		
		if (this.o.width) {
			this.e.frame.style.width = ( this.o.width + this.o.frameBorder * 2 ) + 'px';
		}
		
		if (this.o.autoShow) {
			this.show();
		}
		
	},
	
	buildBasic : function() {
		var self = this;
		
		this.e.popup 	= createNodeN('div', {'class':'tr_popup tr_popup_type_'+this.o.type+' ' + (this.o.absolute?'tr_popup_absolute ':' ') + (this.o.style ? 'tr_pop_' + this.o.style : '')});
		this.e.frame 	= createNodeN('div', {'class':'tr_popup_frame'});
		this.e.content 	= createNodeN('div', {'class':'tr_popup_content'});
		this.e.wrapper 	= createNodeN('div', {'class':'tr_popup_content_wrapper'});
		this.e.close	= createNodeN('a', {'class':'tr_popup_close', innerHTML:'Close Window'});
		this.e.close.onclick 	= function() { self.hide(); }
		this.e.blackout	= createNodeN('div', {'class':'tr_popup_blackout'});
		
		if (this.o.showClose) {
			this.e.frame.appendChild ( this.e.close );
		}
		
		this.e.popup.appendChild( this.e.frame );
		this.e.frame.appendChild( this.e.content );
		this.e.content.appendChild( this.e.wrapper );
		this.e.content.appendChild( createNodeN('div', {'class':'tr_clear clearing'}) );
		
		if (this.o.showBlack) {
			this.e.popup.appendChild ( this.e.blackout );
		}
		
		document.body.appendChild( this.e.popup );
	},
	
	// -- //
	
	// Type: blank
	// Vars:
	//  content - string or markup to display in box
	loadType_blank : function() {
		this.e.wrapper.innerHTML = this.o.content;	
		if (this.o.buttons)
			this.o.hideConfirmBtn = true;
			this.loadLayout_action(true);
	},
	
	event_blank_onCancel : function(e, popup) {
		popup.hide();
	},
	
	// Type: div - uses a current div as the popup and provides buttons underneath
	// Vars:
	//  ctn - object to use
	loadType_ctn : function() {
		this.e.wrapper.appendChild( this.o.ctn );
		this.loadLayout_action(!this.o.formClass);	
	},
	
	event_ctn_onConfirm : function(e, popup) {
		popup.hide();
	},
	
	event_ctn_onCancel : function(e, popup) {
		popup.hide();
	},
	
	// Type: iframe
	// Vars:
	//  url - Url of iframe
	loadType_iframe : function() {
		this.e.wrapper.style.padding = '0px';
		this.e.wrapper.innerHTML = '<iframe frameborder="0" src="'+this.o.url+'" width="'+this.o.width+'" height="'+this.o.height+'" style="width:'+this.o.width+';height:'+this.o.height+'" scrolling="'+(!this.o.noScrolling?'auto':'no')+'"></iframe>';		
	},
	
	// -- //
	
	// Type: notice - displays some information and a close button
	// Vars:
	//  message
	// Optional:
	//  cancelText - default: 'Close'
	//	onCancel() - function to call when cancelled - return true to cancel default handling
	loadType_notice : function() {
		var self = this;
		
		Addclass( this.e.content , 'pop_type_form_simple' );
		
		// Defaults
		this.o.width = this.o.width ? this.o.width : 350;
		this.o.cancelText = this.o.cancelText ? this.o.cancelText : 'Close';
		this.o.hideConfirmBtn = true;
		
		this.e.wrapper.innerHTML = this.o.message;
		
		this.loadLayout_action();				
	},
	
	event_notice_onCancel : function(e, popup) {
		popup.hide();
	},
	
	// -- //
	
	// Type: confirm - asks a question
	// Vars:
	//  question
	// Optional:
	//  content - use this html/text instead of wrapping question in a <P>
	//  text - text to appear in the box
	//	confirmText - default: 'Save'
	//  cancelText - default: 'Cancel'
	//  onConfirm() - function to call on confirm - return true to cancel default handling
	//	onCancel() - function to call when cancelled - return true to cancel default handling
	loadType_confirm : function() {
		var self = this;
		
		Addclass( this.e.content , 'pop_type_form_simple' );
		
		// Defaults
		this.o.width = this.o.width ? this.o.width : 350;
		
		if (this.o.question) {
			this.e.p1 = createNodeN('p', {innerHTML:this.o.question});
			this.e.wrapper.appendChild( this.e.p1 );
		} else if (this.o.content) {
			this.e.wrapper.innerHTML = this.o.content;
		}
		
		this.loadLayout_action();				
	},
	
	event_confirm_onConfirm : function(e, popup) {
		popup.hide();
	},
	
	event_confirm_onCancel : function(e, popup) {
		popup.hide();
	},
	
	// -- //	
	
	// Type: prompt - asks a textfield question
	// Vars:
	//  question
	// Optional:
	//  content - use this html/text instead of wrapping question in a <P>
	//  text - text to appear in the box
	//	confirmText - default: 'Save'
	//  cancelText - default: 'Cancel'
	//  onConfirm() - function to call on confirm - return true to cancel default handling
	//	onCancel() - function to call when cancelled - return true to cancel default handling
	loadType_prompt : function() {
		var self = this;
		
		Addclass( this.e.content , 'pop_type_form_simple' );
		
		// Defaults
		this.o.width = this.o.width ? this.o.width : 350;

		if (this.o.question) {
			this.e.p1 = createNodeN('p', {innerHTML:this.o.question});
			this.e.wrapper.appendChild( this.e.p1 );
		} else if (this.o.content) {
			this.e.content.innerHTML = this.o.content;
		}
		
		this.e.p2 = createNodeN('p');
		this.e.field = createNodeN('input', {'type':'text', 'class':'tr_popup_field', 'value':this.o.text ? this.o.text : ''});
		this.e.p2.appendChild( this.e.field );
		this.e.content.appendChild( this.e.p2 );
		
		this.loadLayout_action();				
	},
	
	event_prompt_onConfirm : function(e, popup) {
		popup.hide();
	},
	
	event_prompt_onCancel : function(e, popup) {
		popup.hide();
	},
	
	// -- //	
	
	// setups up an action layout - used for prompt and confirm
	loadLayout_action : function(noSimpleClass) {
		var self = this;
		
		if (!noSimpleClass)
			Addclass( this.e.content , 'pop_type_form_simple' );
		
		this.o.confirmText = this.o.confirmText ? this.o.confirmText : 'Save';
		this.o.cancelText = this.o.cancelText ? this.o.cancelText : 'Cancel';
		
		// Defaults
		this.o.confirmText = this.o.confirmText ? this.o.confirmText : 'Save';
		this.o.cancelText = this.o.cancelText ? this.o.cancelText : 'Cancel';
		this.o.width = this.o.width ? this.o.width : 350;		

	

		this.e.btns = createNodeN('div', {'class':'centered_buttons'});
		this.e.btnsW = createNodeN('div', {'class':'centered_buttons_wrapper'});
		this.e.btnClear = createNodeN('div', {'class':'tr_clear centered_buttons_clear'});
		
		this.e.confirmBtn = createNodeN('a', {'innerHTML':this.o.confirmText, 'class':'btn_action'});
		this.e.confirmBtn.onclick = function(e) { self.event(e, self, 'onConfirm'); }
		this.e.cancelBtn = createNodeN('a', {'innerHTML':this.o.cancelText, 'class':this.o.style=='lite'?'btn_black':'btn_gray'});
		this.e.cancelBtn.onclick = function(e) { self.event(e, self, 'onCancel'); }
		
		if (!this.o.hideCancelBtn) { this.e.btnsW.appendChild( this.e.cancelBtn ); }
		if (!this.o.hideConfirmBtn) { this.e.btnsW.appendChild( this.e.confirmBtn ); }
		
		this.e.btns.appendChild( this.e.btnsW );
		this.e.content.appendChild( this.e.btns );
		this.e.content.appendChild( this.e.btnClear );
		
	},
	
	// -- //
	
	event : function(e, popup, eventName) {
		if (popup.o[eventName]) {
			if (popup.o[eventName](popup)) {
				return;
			}
		}
		
		//default handling
		popup['event_'+popup.o.type+'_'+eventName](e, popup);
	},
	
	// -- //
	
	show : function() {
		
		var innerSize = this.innerSize();
		var parentWidth 	= this.o.parent ? this.o.parent.offsetWidth  : innerSize[0];
		var parentHeight 	= this.o.parent ? this.o.parent.offsetHeight : innerSize[1];
		var fillHeight		= this.o.parent ? parentHeight : screen.height;

		this.e.frame.style.left = (parentWidth / 2 - this.e.frame.clientWidth / 2) + 'px';
		if (this.o.forceTop) {
			this.e.frame.style.top = this.o.forceTop + 'px';
		} else {
			this.e.frame.style.top = ((parentWidth * 0.30 - this.e.frame.clientHeight / 2 + document.body.scrollTop) ) + 'px';
		}
		this.e.blackout.style.height = fillHeight + 'px';
		
		if (this.o.parent) {
			this.o.parent.style.position = 'relative';
			this.e.blackout.style.position = 'absolute';
			this.e.frame.style.position = 'absolute';
			this.e.blackout.style.width = parentWidth + 'px';
			this.o.parent.appendChild( this.e.popup );	
		}
		
		this.e.popup.style.display = 'block';	
		
		var self = this;
		if (this.o.clickAnywhereToClose)
			this.e.popup.onclick =
			this.e.blackout.onclick = function(e){ self.hide(); if (self.o.clickAnywhereToClose) window.onclick = null; }
	},
	
	hide : function() {		
		this.e.popup.style.display = 'none';		
	},
	
	// -- //
	
	kill : function() {
		this.e.popup.parentNode.removeChild( this.e.popup );
		//delete this;
	},
	
	// -- //
	
	//x-browser way to get innerHeight of window
	//http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
	innerSize : function () {
	  var myWidth = 0, myHeight = 0;
	  if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
	  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth;
		myHeight = document.documentElement.clientHeight;
	  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		myWidth = document.body.clientWidth;
		myHeight = document.body.clientHeight;
	  }
	  return [myWidth, myHeight];
	}
	
}




// --- General --- //

function $i(id) {
	return document.getElementById(id);
}
function createNode(ty, attributes, onclk, ih) {
	node = document.createElement(ty);
	for(ik in attributes) {
		switch(ik) {
			case('class'):
				node.className = attributes[ik];
				break;
			case('style'):
				its = attributes[ik].split(';');
				for(i=0; i<its.length; i++) {
					parts = its[i].split(':');
					if (parts.length > 1) {
						node.style[parts[0]] = parts[1];
					}
				}
				break;
			case('innerHTML'):
				node.innerHTML = attributes[ik];
				break;
			case('onclick'):
				node.onclick = attributes[ik];
			default:
				node.setAttribute(ik, attributes[ik]);
		}				
	}
	return node;
}

function createNodeN(ty, attributes) {
	node = document.createElement(ty);
	for(ik in attributes) {
		switch(ik) {
			case('class'):
				node.className = attributes[ik];
				break;
			case('style'):
				if (typeof attributes[ik] == 'string') {
					its = attributes[ik].split(';');
					for(i=0; i<its.length; i++) {
						parts = its[i].split(':');
						node.style[parts[0]] = parts[1];
					}
				} else {
					for(i in attributes[ik]) {
						node.style[ i ] = attributes[ik][i];
					}
				}
				break;
			case('innerHTML'):
				node.innerHTML = attributes[ik];
				break;
			case('onclick'):
				if (typeof attributes[ik] == 'string') {
					node.setAttribute('onclick', attributes[ik]);
				} else {
					node.onclick = attributes[ik]
				}
			default:
				node.setAttribute(ik, attributes[ik]);
		}				
	}
	return node;
}

function CreateSelect(id, values, selected, label, value, first) {
	var sel = createNodeN('select', {id:id, name:id});
	sel = FillSelect(sel, values, selected, label, value, first);
	return sel;
}
function FillSelect(sel, values, selected, label, value, first) {
	if (!label) { label = 'label'; }
	if (!value) { value = 'value'; }
	sel.options.length = 0;
	
	if (first) {
		sel.options[ 0 ] = new Option(first, null);		
	}
	for(var i in values) {
		sel.options[ sel.options.length ] = new Option(values[i][label], values[i][value]);
	}
	if (selected || selected == 0) { sel.value = selected; }	
	return sel;
}

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

function GetTarget(e) {
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ) {
		if (targ.nodeType == 3) // defeat Safari bug
			targ = targ.parentNode;
	}
	return targ;
};

function getElementsByClassName(oElm, strTagName, oClassNames){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    var arrRegExpClassNames = new Array();
    if(typeof oClassNames == "object"){
        for(var i=0; i<oClassNames.length; i++){
            arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
        }
    }
    else{
        arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
    }
    var oElement;
    var bMatchesAll;
    for(var j=0; j<arrElements.length; j++){
        oElement = arrElements[j];
        bMatchesAll = true;
        for(var k=0; k<arrRegExpClassNames.length; k++){
            if(!arrRegExpClassNames[k].test(oElement.className)){
                bMatchesAll = false;
                break;                      
            }
        }
        if(bMatchesAll){
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements)
};

function isObjectEmpty(obj) {
	for(var i in obj) {
		return false;	
	}
	return true;
}

function ObjToArr(obj) {
	var arr = [];	
	for(var i in obj) {
		arr[i] = obj[i];	
	}
	return arr;
}


function padN(n) {
	if (n < 10) { n = '0'+n; }
	return n;
}

function Addclass(obj, c) {
	if (obj != null && !obj.className.match(c)) {
		obj.className += ' ' + c;
	}
}
function Removeclass(obj, c) {
	if (obj != null) {
		obj.className = obj.className.replace(c, '');
	}
}
function Toggleclass(obj, c, which) {
	if (which) {
		Addclass(obj, c);
	} else {
		Removeclass(obj, c);	
	}
}


function createPostVarStr(obj) {
  var qStr = '';
  for(var i in obj) {
      qStr += '&' + i + '=' + obj[i];
  }
  return qStr;
}


function alerterror(e, where) {
	//var str = '';
	//for(var keys in e) { str += ' | ' + keys; }
	//alert( str );
	if (show_alert_error == 1) {
		if (e.fileName) {
			alert(where + ' = ' + e + ' | ' + e.fileName + ' | ' + e.lineNumber);
		} else if (e.sourceURL) {
			alert(where + ' = ' + e + ' | ' + e.sourceURL + ' | ' + e.line); 
		} else if (e.number) {
			alert(where + ' = ' + e + ' | ' + e.message + ' | ' + e.name );
		}
	}	
}
/*
window.onerror = function (err, file, line) {
alert('The following error occured: ' + err + '\n' +
'In file: ' + file + '\n' +
'At line: ' + line);
return true;
}
*/



function loadJS(src, callback) {
	var script = document.createElement('script');
	script.setAttribute('src',src);
	script.setAttribute('type','text/javascript');	
	document.documentElement.firstChild.appendChild(script);
	script.onload = callback;
	script.onreadystatechange = callback;	
}



/**
 * Function : dump()
 * Arguments: The data - array,hash(associative array),object
 *    The level - OPTIONAL
 * Returns  : The textual representation of the array.
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
 */
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...<br>";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"<br>";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}



function simpleAjax( vars ) {
	this.o = vars;
	this.spinner = this.o.noSpinner ? false : true;
}
simpleAjax.prototype = {
	
	send : function( variables ) {
		
		str = createPostVarStr( variables );
		
		if (this.o.postVars) {
			str += createPostVarStr( this.o.postVars );
		}
		
		if (this.o.ctn && this.spinner) {
			this.spinnerObj = new Spinner(this.o.ctn, '');
		}
		
		var A = new Ajax();
		var self = this;
		A.fire( this.o.url , function(r) { self.callback(r) } , str );			
		
	},
	
	callback : function(r) {
		
		//try {
		
		switch(this.o.type) {
			
			case 'json':
				this.o.callback( JSON.parse(r) );
				break;
				
			case 'ctn':
				this.o.ctn.innerHTML = r;
				if (this.o.parseJS) {
					var sp = new scriptParser(this.o.ctn, r);
					sp.parse();
				}
				if (this.o.callback) {
					this.o.callback(this);	
				}
				break;
			
			default:
				this.o.callback(r);
				
		}
		
		//} catch(e) { alert(e); }
		
	}		

}


function scriptParser(ctn, str) {
	this.ctn = ctn;
	this.str = str;
	this.remoteScriptCount = 0;
	this.evalScripts = [];
	this.evalScriptStart = 0;
}
scriptParser.prototype = {
	
	parse : function() {
		
		var self = this;
		
		// -- Firefox -- //
		
		if (!navigator.userAgent.match('MSIE')) {
		
			scripts = this.ctn.getElementsByTagName('script');
			for(i=0; i<scripts.length; i++) {			
				if (scripts[i].src.length) {
					this.loadJS(scripts[i].src);
				} else {
					this.evalScripts.push( scripts[i].innerHTML );
				}
			}
			
		} else {
		
			// -- IE - Fallback Parser -- //
			
			var matchScriptContent = /<script[^>]*>([\s\S\n\r]*)?<\/script>/mi;
			var matchSrc = /src=["']([^'"]*)"/i;
			var matchScriptStart = /<script[^>]*>/i;
			var matchScriptEnd = /<\/script>/i;	
			var matchStart, matchEnd;
			var strToCheck, scriptString, scriptContent;
			
			// Loop through content and find all script tags
			
			matchStart = matchScriptStart.exec(this.str);
			strToCheck = this.str;
			var i =0;
			
			while(matchStart)
			{     
				// Find end of script tag
				matchEnd = strToCheck.substr(matchStart[0].length).match(matchScriptEnd);
				
				// create script string
				scriptString = strToCheck.substr(matchStart.index, matchStart[0].length + matchEnd.index).replace('<\/script>','') + matchEnd[0];
				
				// commit the script
				scriptString.match(matchScriptContent);
				scriptContent = RegExp.$1;
				if ( scriptContent.length > 1 ) {
					this.evalScripts.push( scriptContent );
				} else if (scriptString.match(matchSrc)) {
					this.loadJS(RegExp.$1);
				}
				
				// Next match
				strToCheck = strToCheck.substr(matchStart.index + matchStart[0].length)
				matchStart  = matchScriptStart.exec(strToCheck);
				
			}
			
		}
		
		
		this.checkScriptsLoaded();		
		
	},
	
	loadJS : function(src) {
		this.remoteScriptCount++;
		var self = this;
		var script = document.createElement('script');
		script.setAttribute('src',src);
		script.setAttribute('type','text/javascript');	
		document.documentElement.firstChild.appendChild(script);
		script.onload = function(){ self.scriptLoaded(); };
		script.onreadystatechange = function(){ if(this.readyState == 'loaded') self.scriptLoaded(); };	
	},
	
	scriptLoaded : function() {	
		this.remoteScriptCount--;
		this.checkScriptsLoaded();
	},	
	 
	checkScriptsLoaded : function() {
		
		if (this.remoteScriptCount > 0) { return; }
		else {
			for(var i=this.evalScriptStart; i<this.evalScripts.length; i++) {
				if (this.evalScripts[i]) {
					try{
						eval(this.evalScripts[i]);
						delete this.evalScripts[i];
					}catch(e){}
				}
			}
		}
	}
	
}
	
	
	
	
	// -- Slider -- //

function Slider(s, opts) {
	this.s = s;
	this.o = opts;
	this.value = 0;
	
	this.images = '/images/';
	
	this.init();
}
Slider.prototype = {
	
	init : function() {					
		var self = this;
		this.trackWidth = (this.o.ticks - 1) * this.o.spacing + 1;
		this.width = this.o.label_width * 2 + this.trackWidth;
		var style = this.o.custom ? '' : 'background-image:url(' + this.images + 'slider_ticks_' + this.o.spacing + '.gif);';
	
		var newHTML = '';
		newHTML += 	'<div class="gz_slider_ticks" style="width:' + this.trackWidth + 'px; ' + style + '">';
		newHTML += 	'	<span class="gz_slider_handle"></span>';
		newHTML += 	'	<div class="gz_slider_track"><span></span><span class="gz_slider_track_r"></span></div>';
		newHTML += 	'</div>';
		newHTML += 	'<span class="gz_slider_r_label">' + this.o.label_r + '</span>';
		newHTML += 	'<span class="gz_slider_l_label">' + this.o.label_l + '</span>';
		
		this.s.style.width = this.width + 'px';
		this.s.className += ' gz_slider';
		this.s.innerHTML = newHTML;
		
		this.track = this.s.firstChild;
		this.SetClickEvent();
		
		this.handle = getElementsByClassName(this.s, 'span', 'gz_slider_handle')[0];
		this.handle.onmousedown = function(e) { self.stopProp(e); self.start(e, self); }
		this.disableSelection( this.handle );
		
	},
	
	SetClickEvent : function() {
		var self = this;
		this.track.onclick = function(e) { self.stopProp(e); self.ClickTrack(e, self); }		
	},
	
	start : function(e, obj) {						
		obj.stopProp(e);
		
		var self = obj;
		obj.leftEdge = obj.findPos(obj.track)[0];
		obj.track.onmousemove = function(e) { self.move(e, self); }	
		
		//This line could be improved as not to override any other onmouseup events
		stopEvent = function(e) { self.stopProp(e);  self.stop(self); }
		document.onmouseup = stopEvent;
		obj.handle.onmouseup = stopEvent;
		obj.track.onclick = null; //disables onclick to avoid duplicate events from occuring when mouse is lifted
	},
	
	stop : function(obj) {
		if ( obj.track.onmousemove != null ) {
			obj.track.onmousemove = null;
			obj.set( obj.value , true );	
		}
	},
	
	move : function(e, obj, goEvent) {								
		obj.stopProp(e);
		
		var coords = obj.mouseCoords(e);
		x = coords[0];								
		x -= obj.leftEdge;
		if (x < 0) { x = 0; }
		if (x > obj.trackWidth) { x = obj.trackWidth; }
		
		step = Math.round(x / obj.o.spacing);
		
		obj.set( step, goEvent );
		
		//$i('output').innerHTML = x + ' | ' + step;
	},
	
	ClickTrack : function(e, obj) {
		obj.stopProp(e);
		
		obj.leftEdge = obj.findPos(obj.track)[0];
		
		obj.move(e, obj, true);
	},
	
	// -- //
	
	set : function( s , goEvent ) {
		if ( this.value != s) {
			this.handle.style.left = (this.o.spacing * s - this.o.handle_width / 2) + 'px';
		}
		if (s != this.value)
		{
			this.value = s;
			if ( goEvent && this.o.event ) {
				this.o.event( this.o.event_args );
			}
			if (this.o.moveEvent) this.o.moveEvent( this.o.event_args );
		}
	},
	
	// -- //
	
	mouseCoords : function (e) {
		var x,y;
		if (typeof e != "undefined"){
			x = e.pageX;
			y = e.pageY;
		}
		else if (typeof window.event !="undefined") {
			browserOffset = browserSliderOffset();
			x = truebody().scrollLeft+event.clientX + browserOffset[0];
			y = truebody().scrollTop+event.clientY + browserOffset[1];
		}
		return [x,y];
	},
	
	disableSelection : function (element) { 
		if (element) {
			element.onselectstart = function() {
				return false;
			};
			element.unselectable = "on";
			element.style.MozUserSelect = "none";
		}
	},
	
	stopProp : function(e) {								
		if (!e) var e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	},
	
	findPos : function (obj) {
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			do {
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			} while (obj = obj.offsetParent);
		}
		return [curleft,curtop];
	}

	
}

function clearChildren(parent, cls) {
	for(var i=parent.childNodes.length - 1; i >= 0; i--) {
	    if (!cls || (cls && parent.childNodes[i].className.match(cls))) {
			parent.removeChild(parent.childNodes.item(i));
	    }
	}
}
	
function truebody() {
	return (!window.opera && document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
} 
var browserForSlider=false;
function browserSliderOffset() {
	if (!browserForSlider) {
		if (navigator.appVersion.match('MSIE 7')) {
			browserForSlider = 1;	
		}
	}
	if (browserForSlider == 1) { return [10,0]; }
	return [0,0];
}



// -- // 

function tr_accordian(a)
{
	this.id = a.id.replace('a_', '');
	this.a = a;
	this.c = $i('a_c_'+this.id);
	this.open = false;
	this.init();
	
	this.phrases = {'-1':'Hide','1':'Show'};
}
tr_accordian.prototype = 
{
	init : function() 
	{
		var self = this;
		this.a.onclick = function(){ self.toggle(); }
	},
	
	toggle : function()
	{
		this.open = !this.open;
		this.c.style.display = this.open ? 'block' : 'none';
		
		Toggleclass( this.a, 'tr_open', this.open );
		
		if (this.a.innerHTML.match(/(show|hide)/i))
		{			
			var what = RegExp.$1.match(/show/i) ? 1 : -1;
			this.a.innerHTML = this.a.innerHTML.replace( this.phrases[what] , this.phrases[what*-1] );
		}
	}
	
}

function setupAccordians() {
	var accords = getElementsByClassName(document.body, 'a', 'tr_accordian');
	var newAccords = [];
	for(var i=0; i<accords.length; i++)
	{
		newAccords.push( new tr_accordian(accords[i]) );
	}	
}

