/*
There are some functions in header.php because they use php variables.

*/

//--------------------GENERAL VARIABLES--------------------//	

//animations speed defaults
speed = new Object();
speed.slideup = 200;
speed.slidedown = 400;
speed.fadeout = 200;
speed.fadein = 400;

general_settings = new Object();

//size defaults
general_settings.qtip = new Object();
general_settings.qtip.centertip = new Object();
general_settings.qtip.centertip.height = 450;

	
//--------------------GENERAL LIVE FUNCTIONS--------------------//	
	
//forms with the class "nolabel" will switch from grey to black on focus and delete the value set to them.
$("form.nolabel input:not(select,.submit), form.nolabel textarea").livequery("focus",function() {
	if ($(this).data('label') == null) {
		$(this).data('label',$(this).val());
	}
	if ($(this).data('label') == $(this).val()) {
		$(this).val("").css("color","black");
	}
});

//forms with the class "nolabel" will switch from black to grey on blur, if they're blank, and set themselves back to the original label.
$("form.nolabel input:not(select,.submit), form.nolabel textarea").livequery("blur",function() {
	if ($(this).val() == "") {
		$(this).val($(this).data('label')).css("color","grey");
	}
});

//only forms with the class "noscript" will submit properly. All others will be prevented.
$("form:not(.noscript)").livequery("submit",function(event) {
	event.preventDefault();
});

//this prevents anchors with '#' as the href from going to the top of the page. These anchors are used for little buttons and things.
$("a[href='#']").livequery('click',function(event){
	event.preventDefault();
});

$(".drop_down a").live('click',function() {
	$(this).parents(".drop_down").hide();
});

$(".drop_down_trigger_sibling").live('click',function() {
	var drop_down;
	drop_down = $(this).siblings(".drop_down");
	$(".drop_down:visible").not(drop_down).hide();
	drop_down.toggle();
});

$("body").live('click',function(event) {
	if ($(event.target).closest(".drop_down_trigger").length == 0) {
		$(".drop_down:visible").hide();
	}
});

	
//--------------------FORM FUNCTIONS--------------------//

// part of this was taken from http://www.codetoad.com/javascript/is_valid_email.asp   It's a very simple email check, but good enough for us, I think.				
var emailCheck = function (elements){
	var error = 0;
	elements.removeClass("warningBkgd").each(function(){
		var str = $(this).val();
		if (!((str.indexOf(".") > 2) && (str.indexOf("@") > 0))) {//If it is not true that there both is a period 3 characters into the string and there is a @ one character in.
			$(this).addClass("warningBkgd");
			error = 1;
		}
	});
	if (error == 1) {
		return false;
	}
	else{
		return true;
	}
}	
	
//check if elements are blank and colors them
var blankCheck = function (elements){
	var error = 0;
	elements.removeClass("warningBkgd").each(function(){
		var value = $(this).val();
		if (value == "" || ($(this).is("select") && value == "-1")){
			$(this).addClass("warningBkgd");
			error = 1;
		}
	});
	if (error == 1) {
		return true;
	}
	else{
		return false;
	}
}

//doesn't check checkboxes or radio buttons
var formCheck = function (form) {
	var error = 0;
	var reqEl = form.find("input, select, textarea").not(".opt,.submit,:hidden");
	if (blankCheck(reqEl)) {
		error = 1;
	}
	if (error == 1) {
		return false;
	}
	else {
		return true;
	}
}

$("form label a").live("click",function() {
	$(this).siblings(".form_description_text").toggle();
});


	
//--------------------AJAX FUNCTIONS--------------------//

		
var create_loading_image = function (container, image) {
	var cb = createCenterBox (container, 100, 0, "absolute", 100);
	cb.html("<img src='"+HTML_ROOT+"/images/"+image+" />");
	return cb;
}
		
var start_loading_effect = function (container, image) {
	var image = createLoadingImage (container, image);
}
	
var end_loading_effect = function (container, image) {

}

/*-----New Ajax functions-----*/

/*variables that can be received in oInfo:
container (where on page data is loaded; is you don't want to load the page onscreen, set this to false)
url (page grabbed via ajax)
strData (data string, transferred via post)
custom_callback (function run onsuccess)
selector (filter applied to data)
*/
/*Notes for future add-ons:
custom speed (overrides defaults set above; just have a oInfo.speed object here. If it's not set, it takes the defaults.)
think about incorporating slideUpLoad, and leaving room for functionality like that, where there is an animation applied to remove/hide an element, but no new html actually loaded on the page. On the other hand, this may be redundant, as it can just be a custom callback
*/

var ajax_basic = function (oInfo){
	$.ajax({
		url: oInfo.url,
		type: "POST",
		data: oInfo.strData,
		dataType: "html",
		success: function(data){
			//if selector is set, filter data
			if (!oInfo.selector || oInfo.selector == null || oInfo.selector == "") {
				var html = data;
			}
			else {
				var html = $(data).filter(oInfo.selector);
			}
			if ($.isFunction(oInfo.callback)) {
				oInfo.callback(data);
			}
		}
	});
}

var ajax_load_html = function (oInfo) {
	oInfo.speed = speed;
	if (!$.isFunction(oInfo.custom_callback)) {
		oInfo.custom_callback = function(){};//set custom_callback to empty, so we can call it later without worrying about whether its defined or not
	}
	if (oInfo.container == false) {
		//If there is no container, and so no animation, just use the custom_callback for the callback and run ajax_basic
		oInfo.callback = function () {
			oInfo.custom_callback();
		}
		ajax_basic(oInfo);
	}
	else {//if data is being loaded, then we've got a lot to choose from
		switch (oInfo.animation) {
			case "append":
				oInfo.callback = function (html) {
					oInfo.container.append(html);
					bindGeneralBehaviors(oInfo.container);
					oInfo.custom_callback();
				}
				ajax_basic (oInfo);
				break;
			case "prepend":
				oInfo.callback = function (html) {
					oInfo.container.prepend(html);
					bindGeneralBehaviors(oInfo.container);
					oInfo.custom_callback();
				}
				ajax_basic (oInfo);
				break;
			case "replace":
				oInfo.callback = function (html) {
					oInfo.container.after(html).remove();
					bindGeneralBehaviors(oInfo.container);
					oInfo.custom_callback();
				}
				ajax_basic (oInfo);
				break;
			case "fade":
				oInfo.callback = function (html) {
					oInfo.container.html(html).fadeIn(oInfo.speed.fadein, function(){
						oInfo.custom_callback();
					});
					bindGeneralBehaviors(oInfo.container);
				}
				oInfo.container.fadeOut(oInfo.speed.fadeout, function(){
					if (jQuery.browser.msie){//ie requires that the background-color be explicitly set on this elemnt. Otherwise, the animation sucks.
						var bk = oInfo.container.css("background-color");
						if (bk == "transparent"){
							oInfo.container.parents().each(function(){
								bk = $(this).css("background-color");
								if (bk !== "transparent")
									return false;//If there is actually a background-color, then stop looking for one.
							});
							oInfo.container.css("background-color",bk);
						}
					}
					ajax_basic (oInfo);
				});
				break;
			case "fade_no_jump":
				//In the normal fade function, if there is anything relatively positioned below the container, there is a jump when the container element completely disappears, then gets populated with the new html again. This solves that problem by fading out to 0.001 opacity instead of 0
				oInfo.callback = function (html) {
					oInfo.container.html(html).fadeTo(oInfo.speed.fadein, 2, function(){
						oInfo.custom_callback();
					});
					bindGeneralBehaviors(oInfo.container);
				}
				if (oInfo.container.is(":hidden")) {//In case the container is hidden. Without this, the function never makes the container visible.
					oInfo.container.empty().show();
				}
				oInfo.container.fadeTo(oInfo.speed.fadeout, 0.001, function(){
					if (jQuery.browser.msie) {
						var bk = container.css("background-color");
						if (bk == "transparent"){
							container.parents().each(function(){
								bk = $(this).css("background-color");
								if (bk !== "transparent")
									return false;//If there is actually a background-color, then stop looking for one.
							});
							container.css("background-color",bk);
						}
					}
					ajax_basic (oInfo);
				});
				break;
			default:
				oInfo.callback = function (html) {
					oInfo.container.html(html);
					bindGeneralBehaviors(oInfo.container);
					oInfo.custom_callback();
				}
				ajax_basic (oInfo);
		}
	}
}
	
	
	
//--------------------UTILITY FUNCTIONS--------------------//
					
/*-----Tooltip Generic Functions-----*/
/*
There are three types of qtips here:
1) smalltip -- designed to replace the default "title" display
2) largetip -- designed for longer "title" displays and little helptips (clicking on question mark to get help)
3) centertip -- designed for more major operations; larger tip placed in the center of the screen
*/

//custom style; last part is the name of the style
$.fn.qtip.styles.mydefault = {
	border: {color: '#37648b', width: 1, radius: 1},
	background: '#fcfcfc',
	color: '#37648b',
	paddingTop: 8,
	paddingBottom: 8,
	paddingLeft: 16,
	paddingRight: 16,
	title: {
		background: '#e3e3e3',
		margin: '0px',
		color: '#37648b',
		fontSize: 'large',
		paddingTop: 8,
		paddingBottom: 8,
		paddingLeft: 16,
		paddingRight: 16,
	}
}

$.fn.qtip.styles.smalltip = {
	name: 'mydefault',
	paddingTop: 1,
	paddingBottom: 1,
	paddingLeft: 6,
	paddingRight: 6,
	fontSize: 'small'
}

$.fn.qtip.styles.largetip = {
	width: {max: 400},
	name: 'mydefault'
}
	
$.fn.qtip.styles.centertip = {
	name: 'mydefault',
	'max-height': general_settings.qtip.centertip.height,
	'overflow': 'auto'
}

var smalltipHideEffect = {
	type: 'fade',
	length: speed.fadeOut
}

var smalltipShowEffect = {
	type: 'fade',
	length: speed.fadeIn
}

	
var largetipHideEffect = {
	type: 'fade',
	length: speed.fadeOut
}

var largetipShowEffect = {
	type: 'fade',
	length: speed.fadeIn
}
	
var centertipHideEffect = {
	type: 'none',
	length: '0'
}

var centertipShowEffect = {
	type: 'none',
	length: '0'
}

//oInfo should include text, url, oData, title, callback (which can take the tooltip as an operator), tooltipClass, and oPosition.
var getLargeTip = function (oInfo) {
	if (oInfo.url && (oInfo.text == null || oInfo.text == undefined || oInfo.text == "")) {
		oInfo.text = "Loading...";
	}
	oInfo.target.qtip ({
		content: {
			text: oInfo.text,
			url: oInfo.url,
			data: oInfo.oData,
			title: {
				text: "<span class='large'>"+oInfo.title+"</span>",
				button: "X"
			}
		},
		api: {
			onContentUpdate: function() {
				var api = oInfo.target.qtip("api");
				var tooltip = api.elements.tooltip;
				if ($.isFunction(oInfo.callback))
					oInfo.callback(tooltip);
			},
			onHide: function() {
				oInfo.target.qtip('destroy');
				if (oInfo.target.is(".centerBox"))
					oInfo.target.remove();
			}
		},
		style: {name: 'largetip', classes: {tooltip: oInfo.tooltipClass}},
		position: oInfo.oPosition,
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
		},
		hide:{
			when: false,
			effect: largetipHideEffect
		}
	});
}

//info should include text, url, oData, title, callback (which can take tooltip as its operator), and tooltipClass.
var getCenterTip = function (oInfo) {
	if (oInfo.text == null || oInfo.text == undefined || oInfo.text == "") {
		oInfo.text = "Loading...";
	}
	if (oInfo.width == null || oInfo.width == undefined || oInfo.width == "") {
		oInfo.width = 500;
	}
	$(".centerBox").each(function() {
		$(this).qtip("destroy");
		$(this).remove();
	});
	var cb = createCenterBox(null,oInfo.width,null,"absolute",general_settings.qtip.centertip.height);
	cb.qtip ({
		target: cb,
		content: {
			text: oInfo.text,
			url: oInfo.url,
			data: oInfo.oData,
			title: {
				text: "<span class='large'>"+oInfo.title+"</span>",
				button: "X"
			}
		},
		api: {
			onHide: function() {
				cb.qtip('destroy');
				cb.remove();
			},
			onContentUpdate: function() {
				var api = cb.qtip("api");
				var tooltip = api.elements.tooltip;
				if ($.isFunction(oInfo.callback)) {
					oInfo.callback(tooltip);
				}
				if (oInfo.draggable == false) {
					//tooltip.draggable('destroy');
				}
			},
			onRender: function() {
				//this.elements.tooltip.draggable(); **NOT TESTED**
			}
		},
		style: {name: 'centertip', classes: {tooltip: oInfo.tooltipClass}, width: oInfo.width},
		position: {
			adjust: {screen: true,scroll: false},
			corner: {target: 'topLeft',tooltip: 'topLeft'}
		},
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: centertipShowEffect
		},
		hide:{
			when: false,
			effect: centertipHideEffect
		}
	});
	var api = cb.qtip('api');
	var qtip = api.elements.tooltip;
	return qtip;
}

$(".qtip-button").live('click',function() {
	api = $(this).parents(".qtip").qtip('api');
	if (api.elements.target.hasClass('centerBox')) {
		api.elements.target.remove();
	}
	api.destroy();
});



/*-----Other-----*/

//http://www.alexandre-gomes.com/?p=115
function getScrollbarWidth () {
	var inner = document.createElement('p');
	inner.style.width = '100%';
	inner.style.height = '200px';

	var outer = document.createElement('div');
	outer.style.position = 'absolute';
	outer.style.top = '0px';
	outer.style.left = '0px';
	outer.style.visibility = 'hidden';
	outer.style.width = '200px';
	outer.style.height = '150px';
	outer.style.overflow = 'hidden';
	outer.appendChild (inner);

	document.body.appendChild (outer);
	var w1 = inner.offsetWidth;
	outer.style.overflow = 'scroll';
	var w2 = inner.offsetWidth;
	if (w1 == w2) w2 = outer.clientWidth;

	document.body.removeChild (outer);

	return (w1 - w2);
}

var getHighestWidth = function (elements){
	var highestWidth = 0;
	elements.each(function(){
		var width = $(this).width();
		highestWidth = Math.max(highestWidth,width);
	});
	return highestWidth;
}

var getHighestHeight = function (elements) {
	var highestHeight = 0;
	var height = 0;
	elements.each(function(){
		if (jQuery.browser.mozilla) {
			height = $(this).outerHeight();//firefox handles the height functions strangely. All browsers calculate the outerHeight correctly. And both calculate the height correctly. The problem is that when you set the css height to 18px in firefox, it limits the OUTER height of the cell to 18px, including padding and border, instead of just the inner height. 
		}
		else {
			height = $(this).height();
		}
		highestHeight = Math.max(highestHeight,height);
	});
	return highestHeight;
}

var test = function (test){
	$("h1").append(test);
}
	
/*This needs some work, but sets up a blanket the size of the window. This can be called again whenever the window is resized to keep the blanket in effect. This should be coupled with a function that actually creates the blanket and resizes it every time the window is resized. Something like this:
$("body").resize(function(){
	set_blanket_dimensions();
});*/
var set_blanket_dimensions = function (){
	var bodyH = $("body").height();
	var bodyW = $("body").height();
	var windowH = $(window).height();
	var windowW = $(window).width();
	if (bodyH < windowH)
		var height = windowH;
	else
		var height = bodyH;
	if (bodyW < windowW)
		var width = windowW;
	else
		var width = bodyW;
	$("#blanket").height(height).width(width);
}
	
//Just a little function to add a delay. Primarily, you can use it before or in-between animations. The delay function itself is an animation that technically does nothing over the specified amount of time, so it is a delay in the queue of animations. It can also be used to call any function after the specified time by passing it that function as its second operator. From http://james.padolsey.com/javascript/jquery-delay-plugin/
$.fn.delay = function(time, callback){
    // Empty function:
    jQuery.fx.step.delay = function(){};
    // Return meaningless animation, (will be added to queue)
    return this.animate({delay:1}, time, callback);
}


//Container should be the element you want this div centered on, passed as a JQuery object. Width should be the desire width of the div. Offset should be an object with top and left offset. If top offset is set to "top" or left offset is set to "left", then the box will be placed on the top or left edge. The height of this div will be determined by its contents, which are variable.
var createCenterBox = function (container, width, offset, position, height){
	var cb = new Object();
	var con = new Object();
	cb.id = $(".centerBox").length + 1;
	if (width == undefined || width == "" || width == null)
		width = 400;
	if (height == undefined || height == "" || height == null)
		height = "auto";
	if (offset == undefined || offset == null || offset == "")
		offset = new Object();
	if (offset.top == undefined)
		offset.top = 0;
	if (offset.left == undefined)
		offset.left = 0;
	if (position == undefined || position == "" || position == null)
		position = "absolute";
	
	if (container !== null) {
		con.position = container.position();
	}
	else{
		con.position = new Object();
		con.position.left = 0;
		con.position.top = 0;
		container = $(window);
	}
	container.css("backgroundColor","red");
	if (offset.left == "left") {
		cb.left = con.position.left;
	}
	else {
		cb.left = (con.position.left + container.width()/2 + offset.left) - width/2; //Gets the left position of the container, adds half its width to find the center, adds the offset, and then substracts half the width of the centerBox. Practically, this centers the centerbox and adjusts for offset.
	}
	if (offset.top == "top") {
		cb.top = con.position.top;
	}
	else if (height > 0) {
		cb.top = (con.position.top + container.height()/2 + offset.top) - height/2;
		if (cb.top < 0) {
			cb.top = 0;
		}
		height = height + "px";
	}
	else {
		cb.top = con.position.top + container.height()/4 + offset.top;//The centerBox's top is set a fourth down the container, then adjusted for offset. And there is no height value sent for the centerBox.
	}

	$("<div class='centerBox' id='cb"+cb.id+"'></div>")
		.css({top: cb.top + "px", left: cb.left + "px", position: position, width: width + "px", height: height})
		.appendTo("body");
		
	return $("#cb"+cb.id);//returns the centerBox just created as a JQuery object.
}

var timeFromSeconds = function (seconds){
	/*to include hours, use these:
	var hours = Math.floor(seconds / 3600); 
	if (hours < 10)
		hours = "0" + hours;
	var minutes = Math.floor(seconds % 3600 / 60); 
	if (minutes < 10)
		minutes = "0" + minutes;
	*/
	var minutes = Math.floor(seconds / 60);
	var seconds = seconds % 60; 
	if (seconds < 10)
		seconds = "0" + seconds;
	
	var time = minutes + ":" + seconds;
	return time;
}
	
// This uses the JQuery Timers plugin (found here: http://plugins.jquery.com/project/timers )
var loadingMessageStart = function (loadingContainer, loadingMessage){
	loadingContainer.html("");
	$(document).everyTime(300, 'loadingMessage', function (){
		//To start things off, we have 3 dots.
		if (loadingContainer.html() == "") {
			loadingContainer.html(loadingMessage + "...");
		}
		else{
			//If it gets to four dots, it's time to start over at one dot
			if (loadingContainer.html().length == loadingMessage.length + 4) {
				loadingContainer.html(loadingMessage + ".");
			}
			else{//otherwise, add a dot
				loadingContainer.append(".");
			}
		}
	});
}
	
var loadingMessageStop = function (loadingContainer){
	$(document).stopTime('loadingMessage');
	loadingContainer.html("");
}
	
//This should be run on success of every ajax call. It binds general scripting that may show up in any load.	Container is the container the ajax class is being loaded into, so ajax isn't binding on all data on the page.	This is also called on the initial document.ready function.	
var bindGeneralBehaviors = function(container){
	/*container.find("[title]:not(option)").each(function(){
		if ($(this).attr("title").length > 50 || $(this).hasClass("tagname")){
			$(this).qtip({
				position: {
					target: 'mouse', 
					adjust:{y:5,x:3},
					corner: {target: 'bottomRight',tooltip: 'topLeft'}
				},
				style: 'largetip',
				show: {delay: 600}
			});
		}
		else{
			$(this).qtip({
				position: {
					target: 'mouse', 
					adjust:{y:14,x:5},
					corner: {target: 'bottomRight',tooltip: 'topLeft'}
				},
				show: {
					delay: 250,
					effect: centertipShowEffect
				},
				hide:{
					effect: centertipHideEffect
				},
				style: 'smalltip'
			});
		}
	});*/
}


var change_heading = function(heading) {
	$("h1").html(heading);
}

	
//--------------------SPECIFIC PAGES--------------------//	

/*signup*/
$("#signup_form").livequery("submit",function(e) {
	var elements, signup_form, error_container;
	signup_form = $(this);
	elements = signup_form.find("li:not(.opt) input:not(:hidden)");
	error_container = signup_form.find(".error");
	error_container.html("");
	if (blankCheck(elements)) {
		e.preventDefault();
		error_container.append("You left something blank.<br />");
	}
	else {
		if ($("#pswd").val() !== $("#pswd_ver").val()) {
			elements.filter(".pswd").addClass("warningBkgd");
			e.preventDefault();
			error_container.append("Your passwords don't match.<br />");
		}
		if (!emailCheck(elements.filter("#email"))) {
			elements.filter("#email").addClass("warningBkgd");
			e.preventDefault();
			error_container.append("That's not a valid email address.<br />");
		}
	}
});

/*account_settings*/
$("#account_settings").livequery("submit",function(e) {
	elements = $(this).find("li:not(.opt) input:not(:hidden, #pswd, #pswd_ver)");
	error = $(this).find(".error");
	error.html("");
	if (blankCheck(elements)) {
		e.preventDefault();
		error.html("You left something blank.");
	}
	else if ($("#pswd").val() !== $("#pswd_ver").val()) {
		$("#account_settings .pswd").addClass("warningBkgd");
		e.preventDefault();
		error.html("Your passwords don't match.");
	}
});

$("#account_settings button.cancel").live("click",function() {
	window.location = HTML_ROOT + "/account/";
});


//----------QTIPS----------//

/*create_form.php*/



//----------ACCOUNT PAGES----------//

/*General Account Functions*/
var load_account_summary_view = function () {
	ajax_load_html({
		container: $("#container"),
		url: HTML_ROOT + "/account/account_summary_view.php",
		custom_callback: function () {
			change_heading ("Forms");
			load_heading_bar_right ("summary");
		}
	});
}

var load_form_data_view = function (formid, form_name) {
	ajax_load_html({
		container: $("#container"),
		url: HTML_ROOT + "/account/data_view.php",
		strData: "formid="+formid,
		custom_callback: function () {
			format_form_data($(".form_data"));
			resize_form_data();
			load_heading_bar_right ("data","formid="+formid);
			if (form_name !== null) {
				change_heading (form_name);
			}
		}
	});
}

//switch out the links on the heading_bar_right
var load_heading_bar_right = function (type, data) {
	var file;
	switch (type) {
		case "data":
			file = "heading_bar_data.php";
			break;
		default:
			file = "heading_bar_summary.php";
	}
	if ($("#heading_bar_right")) {
		ajax_load_html({
			container: $("#heading_bar_right"),
			url: HTML_ROOT + "/includes/html_blocks/" + file,
			strData: data,
			animation: "replace"
		});
	}
	else {
		ajax_load_html({
			container: $("#heading_bar"),
			url: HTML_ROOT + "/includes/html_blocks/" + file,
			strData: data,
			animation: "append"
		});
	}
}

var resize_form_data = function () {
	var data_container, body_container, heading_container, old_container_height, new_container_height, old_data_height, new_data_height, scrollbar_width, heading_width;
	if ($(".form_data")) {
		data_container = $("#data_container");
		body_container = $(".body_container");
		heading_container = $(".heading_container");
		rownum_container = $(".rownum_container");
		
		//Find the available room for the container by finding the height of all the elements except #data_container (found by subtracting data_container's height from the body height) and subtracting that from total window height.
		new_container_height = $(window).height() - ($("body").outerHeight() - data_container.outerHeight());
		old_container_height = data_container.outerHeight();
		data_container.height(new_container_height);
		
		//Next, do the same for #data_container, so we know what the height of the actual data should be (.body_container). Then set that height.
		new_data_height = new_container_height - (old_container_height - body_container.outerHeight());
		body_container.height(new_data_height);
		
		scrollbar_width = getScrollbarWidth();
		//If there is a horizontal scrollbar, adjust height of rownum_container in light of scrollbar_width.
		if (body_container.width() < body_container.find("table").width()) {
			rownum_container.height(new_data_height - scrollbar_width);
		}
		else {
			rownum_container.height(new_data_height);
		}
		//Finally, if there is a vertical scrollbar, and the heading_container hasn't already been resized, get the width of the heading_container and set it's width to that, minus the scrollbar_width
		heading_width = parseInt(heading_container.width());
		//$("h1").after("<p>" + parseInt(body_container.find("table").height()) + " " + new_data_height + " " + heading_width + " " + parseInt(body_container.width()) + "</p>");
		if (parseInt(body_container.find("table").height()) > new_data_height && heading_width == parseInt(body_container.width())) {
			//$("h1").after("<p>it worked</p>");
			heading_container.width(heading_width - scrollbar_width);
		}
		else {
			//$("h1").after("<p>it didn't</p>");
		}
	}
}

//Javascript formatting for .form_data table. Sets the widths of columns and heights of rows. Very messy.
var format_form_data = function (form_data) {
	var heading_table, body_table, rownum_table, heading_th, rownum_th;
	body_table = form_data.find(".body_container table")
	if (body_table.length > 0) {
		heading_table = form_data.find(".heading_container table");
		rownum_table = form_data.find(".rownum_container table");
		top_left = form_data.find(".top_left");
		heading_th = heading_table.find("th");
		rownum_th = rownum_table.find("th");
		//set all column widths
		heading_th.each(function() {
			set_column_width (body_table, $(this));
		});
		set_column_width (null, top_left);
		
		//set all row heights
		rownum_th.each(function() {
			set_row_height (body_table, $(this));
		});
		return true;
	}
	else {
		return false;
	}
}

//set the width of an individual column to the max-width between the th and the first td of the column. If th is set to the top_left div, this will set it to the width of the rownum column.
var set_column_width = function (body_table, th) {
	var fieldid, first_td, width, both;
	fieldid = th.find("input[name='fieldid']").val();
	if (th.hasClass("top_left")) {//if this is the little box in the top_left
		first_td = th.parents(".form_data").find(".rownum_container table tr:first th");
	}
	else {
		first_td = body_table.find("tr:first td:has(input[name='fieldid'][value='"+fieldid+"'])");
	}
	both = first_td.add(th);
	width = getHighestWidth (both);
	if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {//if this is chrome
		width += 1;
	}
	both.css("minWidth",width);
}

//set the height of an individual row  to the max-height of the th and the first td of the row.
var set_row_height = function (body_table, th) {
	var instanceid, first_td, height, both;
	instanceid = th.find("input[name='instanceid']").val();
	first_td = body_table.find("tr td:first-child:has(input[name='instanceid'][value='"+instanceid+"'])");
	both = first_td.add(th);
	height = getHighestHeight (both);
	both.height(height + "px");
}

$("#summary_bar .form_summary_container .view_description").live("click",function() {
	$(this).parents(".form_summary_container").find(".form_description").slideToggle();
});





/*account_summary_view*/
$(".form_icon_container .form_icon").live("mouseover", function() {
	var formid;
	formid = $(this).parents(".form_icon_container").find("input[name='formid']").val();
	$("#summary_bar .form_summary_container.form" + formid).show().siblings().hide();
});

$(".form_icon_container .form_icon").live("click",function() {
	var formid, form_name, form_icon_container;
	form_icon_container = $(this).parents(".form_icon_container");
	form_name = form_icon_container.find(".form_name").text();
	formid = form_icon_container.find("input[name='formid']").val();
	load_form_data_view (formid, form_name);
});

$(".create_form_load").live("click",function() {
	getCenterTip ({
		url: HTML_ROOT + "/includes/qtips/edit_form.php",
		callback: function(tooltip) {
			$(".create_form").unbind('submit').submit(function() {
				$(this).find(".error").html("");
				if (formCheck($(this))) {
					var return_url = $(this).find("input[name='return_url']");
					if (return_url.val().indexOf("http://") !== 0) {
						return_url.addClass("warningBkgd");
						$(this).find(".error").html("Your return url needs to begin with 'http://'.");
					}
					else {
						ajax_load_html({
							container: tooltip.qtip('api').elements.content,
							url: HTML_ROOT + "/includes/operations/add_form.php",
							strData: $(this).serialize(),
							custom_callback: function() {
								load_account_summary_view();
							}
						});
					}
				}
				else {
					$(this).find(".error").html("You left something blank.");
				}
			});
		},
		title: "Create Form",
		tooltipClass: "qtip_create_form"
	});
});





/*form_data_view*/


$(".account_summary_load").live("click",function() {
	load_account_summary_view();
});

//deletes a form
$(".delete_form").live("click", function() {
	var del = confirm("Are you sure you want to delete this form?");
	if (del) {
		ajax_basic({
			url: HTML_ROOT + "/includes/operations/delete_form.php",
			strData: "formid=" + $(".form_data").find("input[name='formid']").val(),
			callback: function() {
				load_account_summary_view();
			}
		});
	}
});

//clears a form's data
$(".clear_form_data").live("click", function() {
	var del = confirm("Are you sure you want to clear all of this form's data?");
	if (del) {
		formid = $(".form_data").find("input[name='formid']").val();
		ajax_basic({
			url: HTML_ROOT + "/includes/operations/clear_form_data.php",
			strData: "formid=" + formid,
			callback: function() {
				load_form_data_view (formid);
			}
		});
	}
});

//edits form settings
$(".edit_form_info").live("click", function() {
	var tip = getCenterTip ({
		url: HTML_ROOT + "/includes/html_blocks/form_settings.php",
		oData: {
			formid: $(".form_data input[name='formid']").val()
		},
		callback: function(tooltip) {
		},
		title: "Form Settings",
		tooltipClass: "qtip_form_settings",
		draggable: false
	});
});

//submits form settings
$("#form_settings").livequery("submit",function() {
	var form, form_name, url, data, callback, error_container;
	form = $(this);
	error_container = form.find(".error");
	error_container.html("");
	if (formCheck(form)) {
		var return_url = $(this).find("input[name='return_url']");
		if (return_url.val().indexOf("http://") !== 0) {
			return_url.addClass("warningBkgd");
			error_container.html("Your return url needs to begin with 'http://'.");
		}
		else {
			form_name = form.find("input[name='form_name']").val();
			ajax_basic({
				url: HTML_ROOT + "/includes/operations/update_form_info.php",
				strData: form.serialize(),
				callback: function() {
					change_heading(form_name);
					form.parents(".qtip").qtip("hide");
				}
			});
		}
	}
	else {
		error_container.html("You left something blank.");
		return false;
	}
});

//synchronizes the scrolling between the body_container and heading_container, rownum_container. need to check on normal machine to see how fast this works.
$("#data_container .body_container").livequery("scroll",function() {
	var scroll_left, scroll_top, form_data;
	scroll_left = $(this).scrollLeft();
	scroll_top = $(this).scrollTop();
	$(this).parents(".form_data").find(".heading_container").scrollLeft(scroll_left).end().find(".rownum_container").scrollTop(scroll_top);
	/*this is another way to do it; potentially faster
	if ($(this).data('scroll_left') !== scroll_left) {
		$(this).parents(".form_data").find(".heading_container").scrollLeft(scroll_left);
		$(this).data('scroll_left',scroll_left);
	}
	if ($(this).data('scroll_top') !== scroll_top) {
		$(this).parents(".form_data").find(".rownum_container").scrollTop(scroll_top);
		$(this).data('scroll_top',scroll_top);
	}*/
});

//needs oInfo.instanceid and oInfo.rownum
var load_single_instance = function(oInfo) {
	$(".qtip_single_instance").qtip('destroy');
	var tip = getCenterTip ({
		url: HTML_ROOT + "/includes/html_blocks/single_instance.php",
		oData: {
			instanceid: oInfo.instanceid
		},
		callback: function(tooltip) {
		},
		title: "Submission " + oInfo.rownum,
		tooltipClass: "qtip_single_instance instance"+oInfo.instanceid
	});
}

$(".body_container tr").live('click',function() {
	var instanceid;
	instanceid = $(this).find("input[name='instanceid']").val();
	$(this).add(".rownum_container tr:has(input[name='instanceid'][value='"+instanceid+"'])").addClass("selected").siblings().removeClass("selected");
});

$(".body_container tr.selected td").live('click',function() {
	var instanceid;
	instanceid = $(this).find("input[name='instanceid']").val();
	if ($(".qtip_single_instance.instance"+instanceid).length == 0) {//check if it's already loaded
		load_single_instance ({
			instanceid: instanceid,
			rownum: $(".rownum_container th:has(input[name='instanceid'][value='"+instanceid+"'])").text()
		});
	}
});



//--------------------DOCUMENT ONREADY--------------------//		
	
$(document).ready(function(){
	//This function can be used to find behaviors on document on ready and on every call of ajax. livequery can pretty much accomplish this, but in case there are other functions that need to happen that livequery can't handle, we have this.
	bindGeneralBehaviors($(document));
	
	if ($(".form_data")) {
		format_form_data($(".form_data"));
		resize_form_data();
	}
	$(window).resize(function(){
		if ($(".form_data")) {
			resize_form_data();
		}
	});
});
