function add_onload(element, new_function) {
	var old_onload = element.onload;

	if (typeof old_onload != 'function') {
		old_onload = function(){};
	}

	element.onload = function (){
		old_onload();
		new_function();
	}
}

function add_onunload(element, new_function) {
	var old_onunload = element.onunload;

	if (typeof old_onunload != 'function') {
		old_onunload = function(){};
	}

	element.onunload = function (){
		old_onunload();
		new_function();
	}
}

function add_onfocus(element, new_function) {
	var old_onfocus = element.onfocus;

	if (typeof old_onfocus != 'function') {
		old_onfocus = function(){};
	}

	element.onfocus = function (){
		old_onfocus();
		new_function();
	}
}

function trim(stringToTrim) {
	return stringToTrim.replace(/^\s+|\s+$/g,"");
}

function limitTextarea(elm,limit,display_id,limit_id) {
  $(limit_id).value = limit - (elm.value.length);
  if ($(limit_id).value > 1) {
  	$(display_id).innerHTML = limit - elm.value.length+' characters remaining.';
  }
  if ($(limit_id).value == 1) {
  	$(display_id).innerHTML = '1 character remaining.';
 	}
  if ($(limit_id).value == 0) {
  	$(display_id).innerHTML = '0 characters remaining.';
 	}
 	if ($(limit_id).value < 0) {
 		$(display_id).innerHTML = limit - elm.value.length+' characters remaining, excess characters will be truncated.';
 	}
}

function callbackLink(href, element_id, inner_html) {
	$(element_id).href = href;
	if (href == '' || href == 'javascript:;') {
		$(element_id+'_hidden').value = '';
		$(element_id).innerHTML = 'Add a Link';
		$(element_id).title = 'Add a Link';
		$(element_id+'_delete').hide();
	} else {
		if (inner_html === undefined) {
			inner_html = href.truncate(30);
		}
		$(element_id+'_hidden').value = href;
		$(element_id).innerHTML = inner_html;
		$(element_id).title = href;
		$(element_id).target = '_blank';
		$(element_id+'_delete').show();
	}
}
/* from themaninblue, it works. :) */
function addLoadListener(fn){
	if (typeof window.addEventListener != 'undefined') {
		window.addEventListener('load', fn, false);
	} else if (typeof document.addEventListener != 'undefined') {
		document.addEventListener('load', fn, false);
	} else if (typeof window.attachEvent != 'undefined') {
		window.attachEvent('onload', fn);
	} else {
		return false;
	}
	return true;
};
function attachEventListener(target, eventType, functionRef, capture) {
    if (typeof target.addEventListener != "undefined") {
        target.addEventListener(eventType, functionRef, capture);
    } else if (typeof target.attachEvent != "undefined") {
        target.attachEvent("on" + eventType, functionRef);
    } else {
        return false;
    }
    return true;
};
var flow = {
	/* values */
		wrapperId: "nav-flow",
		itemsTagName: "li", //my script is pretty naive at this time. basically just an element. this element can contain other elements, just not the same as it. :)
		subTagName: "a", //internal elemenent that moves. don't double up on these either. :)
		defaultItem: 6, /* index of initial expanded item */
		returnTo: "initial", //initial, default, sticky
		/*dimensions*/
		expandedWidth: 598,
		initialWidth: 155,
		contractedWidth: 66,
		totalWidth:934,
		spacing: 1,
		/*subHeight*/
			sub:false,
			subHeight:0,
			initSubHeight:0,
		/*animations*/
		quality: 12,
		duration: 1200,
	/* init vars*/
	items: [],
	orderedItems: [],
	interval: 0,
	i_time:   0,
	inited: false,
	/**/
	init: function () {
		if(!flow.inited && document.getElementById && document.getElementById(flow.wrapperId)){
			flow.inited = true;
			var container = document.getElementById(flow.wrapperId);
			var items = container.getElementsByTagName(flow.itemsTagName);
			var i=0;
			for(j in items){
				if (items[j].nodeType && items[j].nodeType == 1 && items[j].parentNode.id == flow.wrapperId) {
					if (!items[j].id) {items[j].id = "flow-banner-"+i+"salttesttestwrong";}
					flow.items[i] = items[j].id;
					if (flow.defaultItem == i && flow.returnTo == "default"){
						flow.defaultItem = items[j].id;
					}
					items[j].style.width = "155px";

					if (flow.sub){
						items[j].getElementsByTagName(flow.subTagName)[0].style.height = items[j].getElementsByTagName(flow.subTagName)[0].offsetHeight+"px";
					}
					if(items[j].addEventListener){
						items[j].addEventListener('mouseover', function(){flow.slide(this.id, 1);},false);
						items[j].addEventListener('mouseout', function(){flow.slide(this.id, -1);},false);
					} else {
						/* stupid backward IE */
						items[j].onmouseover = flow.flow_out;
						items[j].onmouseout = flow.flow_in;
					}
					i++;
				}
			}
		}
	},
	/* What's wrong with anonymous functions, huh, IE? nothing.
	   I have some quite good friends who happen to be anonymous functions.
	   so stop with your judging. */
	flow_out: function(event){
		flow.slide(this.id, 1);
	},
	flow_in: function(event){
		flow.slide(this.id,-1);
	},
	slide:function(itemId, dir){
		if ((dir > 0 || flow.returnTo != "sticky") && flow.inited) {
			if(flow.interval){clearInterval(flow.interval)}
			flow.i_time = 0;
			/*reorder our flow.items to get the one being expanded last.*/
			if (dir > 0 || flow.returnTo == "default"){
				flow.orderedItems = []; /*zero*/
				for (var n=0; n < flow.items.length;n++) {
					if ((dir > 0 && flow.items[n] != itemId) || (dir < 0 && flow.items[n] != flow.defaultItem)){
						flow.orderedItems.push(flow.items[n]);
					}
				}
				flow.orderedItems.push(dir > 0 ? itemId : flow.defaultItem);
			} else {
				flow.orderedItems = flow.items; /*if flow.returnTo == initial*/
			}

				if (flow.highlighted && document.getElementById(flow.highlighted)){ document.getElementById(flow.highlighted).className = ""; }
				if (dir > 0) {flow.highlighted = itemId+"-tab"; document.getElementById(flow.highlighted).className = "highlighted"; }
			/*start loop*/
			flow.interval = setInterval("flow.slide_i('"+itemId+"', "+dir+")", flow.quality);
		}
	},

	slide_i:function(itemId, overallDir){
		var otherWidths = 0;
		for (var n=0; n < flow.orderedItems.length;n++){
			var dir = overallDir;

			var newWidth = 0;
			var item = document.getElementById(flow.orderedItems[n]);
			var currentWidth = Number(item.style.width.match(/\d*/));
			var lastItem = (n == flow.orderedItems.length - 1);
			if (flow.sub){
				var newSubHeight = 0;
				var itemSub = item.getElementsByTagName(flow.subTagName)[0];
				var currentSubHeight = Number(itemSub.style.height.match(/\d*/));
			}
			if ((dir > 0 && flow.orderedItems[n] != itemId) || (dir < 0 && flow.orderedItems[n] == flow.defaultItem && flow.returnTo == "default")){
				dir = dir*-1;
			}
			if (lastItem) {
				/*make it's size the leftovers. this means I can do fancy tweens without the edge being ragged. */
				newWidth = flow.totalWidth - (flow.spacing * (flow.items.length - 1)) - otherWidths;
			}
			if (dir > 0) {
				if (!lastItem) {
					newWidth = Math.round(flow.easeInOutCirc(flow.i_time+=flow.quality, currentWidth, flow.expandedWidth-currentWidth, flow.duration));
				}
				if (flow.sub){
					newSubHeight = Math.floor(flow.easeInOutCirc(flow.i_time+=flow.quality, currentSubHeight, flow.subHeight-currentSubHeight, flow.duration));
				}
			} else if (dir < 0){
				if (!lastItem) {
					newWidth = Math.round(flow.easeInOutCirc(flow.i_time+=flow.quality, currentWidth, (flow.returnTo == "initial" && overallDir < 0 ? flow.initialWidth : flow.contractedWidth)-currentWidth, flow.duration));
				}
				if (flow.sub) {
				newSubHeight = Math.floor(flow.easeInOutCirc(flow.i_time+=flow.quality, currentSubHeight, flow.initSubHeight-currentSubHeight, flow.duration));
				}
			}
			if(dir > 0 && flow.i_time >= flow.duration){
				newWidth = flow.expandedWidth;
				if (flow.sub){
					newSubHeight = flow.subHeight;
				}
			} else if(dir < 0 && flow.i_time >= flow.duration){
				newWidth = flow.returnTo == "initial" && overallDir < 0 ? flow.initialWidth : flow.contractedWidth;
				if (flow.sub){
					newSubHeight = flow.initSubHeight;
				}
			}
			//item.className = newWidth > flow.expandedWidth - 100 ? flow.selectedClassName : "" ;
			item.style.width = newWidth+"px";
			if (flow.sub) {
				itemSub.style.height = newSubHeight+"px";
			}
			otherWidths = n==0 ? newWidth : otherWidths + newWidth;
		}
	},
	/*#^ FROM http://www.robertpenner.com/easing/penner_chapter7_tweening.pdf ^#*/
	easeInOutCirc: function (t, b, c, d) {
		if ((t/=d/2) < 1) return c/2 * (1 - Math.sqrt(1 - t*t)) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	}
}
