/*
There are some functions in header.php because they use php variables.

All functions need to be defined before the document on ready function, otherwise they will be local to this document on ready function and not available globally. See http://www.nabble.com/function-from-an-external-js-does-is-not-defined-when-using--$(document).ready-in-the-external-file-td16920030s27240.html


To make animations sexier, we can make custom sliding and fade functions. For example, when sliding, we could add a fade in animation, or maybe even have it animate the width, too. We can have two or three options for animations, each with a primary effect (fading, sliding different directions), and other small effects. We can also experiment with queues (have a div slide down with 60% opacity, and then fade in after it finishes sliding).
These custom animations should also have toggle functions written (if element is visible, then run customFadeIn, else run customFadeOut). That way we can run the fadeins and outs separately, or as a toggle, as in JQuery. Also, make these methods of jquery objects instead of functions.

Also, consider adding more $.scrollTo functions. This could be added to the custom sliding/fading animations.
*/

var test = function (test)
	{
	$("h1").append(test);
	}
	
	
//--------------------FORM FUNCTIONS--------------------//
					
$("form.ajax").livequery("submit",function(event) {
	event.preventDefault();
});
					
var preventSubmit = function (form)
	{
	form.each(function()
		{
		$(this).submit(function(event)
			{
			event.preventDefault();
			});
		});
	}

// 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("warningHighlight").each(function()
		{
		var str = $(this).val();
		if (!((str.lastIndexOf(".") > 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("warningHighlight");
			error = 1;
			}
		});
	if (error == 1)
		return false;
	else
		return true;
	}	
	
//The new function; this should replace the old at some point.	It just checks the given input elements.
var blankCheck = function (elements)
	{
	var error = 0;
	elements.removeClass("warningHighlight").each(function()
		{
		var value = $(this).val();
		
		if (value == "" || ($(this).is("select") && value == "-1"))
			{
			$(this).addClass("warningHighlight");
			error = 1;
			}
		});
	if (error == 1)
		return true;
	else
		return false;
	}
						
var checkForBlanks = function (form)
	{
	var error = 0;
	$(form + " .required input:text, " + form + " .required input:password, " + form + " .required select").removeClass("warningHighlight").each(function()
		{
		var value = $(this).val();

		if (value == "" || ($(this).is("select") && value == "-1"))
			{
			$(this).addClass("warningHighlight");
			error = 1;
			}
		});	
	
	if (error == 1)
		return true;
	else
		return false;
	}
	
//verifyType should be either "pswd" or "email". T
var checkVerify = function(form, verifyType)
	{
	var input = form + " input[name='" + verifyType + "']";
	var inputVerify = form + " input[name='" + verifyType + "Verify']";
	var typeStr = "";
	if (verifyType == "email")
		typeStr = "email";
	if (verifyType == "pswd")
		typeStr = "password";
	var errorMessage = " - The two " + typeStr + " fields do not match. Please re-enter your " + typeStr + " in both fields and try again.<br />";
	
	//If either of them are blank, no error message is sent, since checkForBlanks() will already be handling it.
	if ($(input).val() != "" && $(inputVerify).val() != "" && $(input).val() != $(inputVerify).val())
		{
		$(input).add(inputVerify).addClass("warningHighlight");
		$(form + " .error").append(errorMessage);
		}
	}
		
//This function is used in the checkParentInfo function
var minorTest = function(form)
	{
	birthY = $(form + " select[name='BY']").val();
	birthM = $(form + " select[name='BM']").val() - 1;
	birthD = $(form + " select[name='BD']").val();
	birthday = new Date();
	birthday.setFullYear(birthY,birthM,birthD);
	minorTestDate = new Date();
	minorTestYear = minorTestDate.getFullYear() - 18;
	minorTestDate.setFullYear(minorTestYear);
	
	if (birthday > minorTestDate)
		return true;
	else
		return false;
	}
		
var checkParentInfo = function(form)
	{
	if (minorTest(form) == true)
		{
		var error = 0;
		$(form + " .parent").show();
		$(form + " .parent input").each(function()
			{
			if ($(this).val() == "")
				{
				$(this).addClass("warningHighlight");
				error = 1;
				}
			});
		if (error == 1)
			$(form + " .error").append(" - If you are a minor, you are required to enter your parents' contact information. Please enter this information and try again.<br />");
		}
	else
		$(form + " .parent").hide();
	}
	
//This function runs onSubmitError or onSubmitSuccess automatically, so it needs scroll set. This should be done differently, with this function just returning false or true according to an error, but oh well, this is good enough for now.
var emailDuplicateCheck = function(form, scroll)
	{
	var emailInput = form + " input[name='email']";
	var error = 0;
	$(form + " .error").load
		(
		HTML_ROOT + "/includes/htmlBlocks/emailDuplicateCheck.php",
		{
		email: $(emailInput).val()
		},
		function()
			{
			if ($(form + " .error").html().match("email") !== null)
				{
				$(emailInput).addClass("warningHighlight");
				onSubmitError(form, scroll);
				}
			else
				onSubmitSuccess(form);
			}
		);
	}

//Set scroll to "false" for no scrolling. Otherwise, it should be set to the element to be scrolled to.
var onSubmitError = function(form, scroll)
	{
	$(form + " .error").prepend("There are some problems with the information you entered:<br />");
	if (scroll != "false")
		$(window).scrollTo(scroll,300);
	$(form + " .submit").attr("disabled","");
	}
	
//Takes data from the form, uses the form's action for the load url, uses the parent of the form as the container for the new load, and then runs a fadeInLoad.
var onSubmitSuccess = function (form, callback)
	{
	var dataString = $(form).serialize();
	var url = $(form).attr("action");
	var container = $(form).parent();
	fadeInLoad (container, url, dataString, callback);
	}
	
//Set these variables to "true" for error checking of that type. scroll should be set to "false" for no scrolling on error; otherwise, it should be the element scrolled to. callback is called in onSubmitSuccess as a callback to fadeInLoad.
var formSubmit = function (event, form, email, pswd, parent, emailDuplicate, scroll, callback)
	{
	event.preventDefault();
	$(form + " input").removeClass("warningHighlight");
	$(form + " .error").html("");
	$(form + " .submit").attr("disabled","disabled");
	
	if (checkForBlanks (form))
		$(form + " .error").append(" - Some of the required information is blank. Please fill in all the required information and try again.<br />");
		
	if (parent == "true")
		checkParentInfo (form);
	
	if (email == "true")
		{
		checkVerify (form, "email");
		if (emailCheck ($(form + " input[name='email']")) == false)
			$(form + " .error").append(" - The email address you entered is not a valid email address.<br />");
		}
	
	if (pswd == "true")
		checkVerify (form, "pswd");
		
	if ($(form + " .error").html() !== "")
		onSubmitError(form,scroll);
	else
		{
		if (emailDuplicate == "true")
			emailDuplicateCheck(form, scroll);
		else
			onSubmitSuccess(form, callback);
		}
	}
	
//This binds all unviersal form behaviors
var bindFormBehaviors = function ()
	{
	$("select.month").change(function()
		{
		var daySelect = $(this).siblings("select.day");
		var month = $(this).val();
		var day = daySelect.val();
		$(this).siblings("select.day").load(HTML_ROOT + "/includes/htmlBlocks/getDayOptions.php",{month: month, day: day});
		});
	}
	
//--------------------ACCOUNT HOME CLASSES FUNCTIONS--------------------//

					
					
//pageType should be either "student" or "instructor" according to whether it is instructorHome or studentHome. oldAssignmentsLoad should be the div clicked on to load the new exams.
var loadOldAssignments = function (pageType, oldAssignmentsLoad)
	{
	var oldAssignments = oldAssignmentsLoad.siblings(".oldAssignments");
	var classID = oldAssignmentsLoad.parents(".classContainer").attr("id");
	var url = HTML_ROOT + "/includes/htmlBlocks/assignmentList.php";
	var data = "classid=" + classID + "&pageType=" + pageType + "&time=pastDue";
	var callback = function ()
		{
		showHideSwitch(oldAssignmentsLoad);
		}
	slideLoad (oldAssignments, url, data, "", callback);
	}

var hideOldAssignments = function (oldAssignmentsLoad)
	{
	var oldAssignments = oldAssignmentsLoad.siblings(".oldAssignments");
	oldAssignments.slideUp("normal", 
		function ()
			{
			showHideSwitch(oldAssignmentsLoad);
			});
	}
	
var loadNewClass = function (pageType)
	{
	if (pageType == "student")
		var page = "joinClass.php";
	if (pageType == "instructor")
		var page = "createClass.php";
	
	var trigger = $("#newClassLoad span");
	var container = $("#newClass");
	var url = HTML_ROOT + "/includes/htmlBlocks/" + page;
	var callback = function  ()
		{
		$.scrollTo(container, 1000);
		}
	slideLoadToggle (trigger, container, url, "", callback);
	}
	
var removeClass = function (pageType, strData, removeClassLoad)
	{
	if (pageType == "student")
		var page = "leaveClass.php";
	if (pageType == "instructor")
		var page = "deleteClass.php";
		
	var url = HTML_ROOT + "/includes/htmlBlocks/" + page;
	var classCount = $(".classContainer").length;
	var animateRemove = function()
		{
		if (classCount != 1)
			{
			removeClassLoad.parents(".classContainer").slideUp("normal", function(){$(this).remove();});
			}
		else
			{
			var reloadContainer = $("#" + pageType + "HomeClassList");
			var reloadUrl = HTML_ROOT + "/includes/htmlBlocks/" + pageType + "HomeClassList.php";
			fadeInLoad(reloadContainer, reloadUrl);
			}
		}
		
	$.ajax
		({
		url: url,
		type: "POST",
		data: strData,
		success: function()
			{
			animateRemove();
			}
		});
		
	}
	
var bindHomeClassListBehaviors = function (pageType)
	{
	$("#expiredClassesLoad").unbind("click").click(function()
		{
		var clicked = $(this);
		var expiredClasses = $("#expiredClasses");
		var speed = 700;
		expiredClasses.slideToggle(speed, function(){showHideSwitch(clicked);});
		$.scrollTo(expiredClasses, speed);
		});
		
	$(".pendingAssignmentsLoad").unbind("click").toggle
		(
		function()
			{
			var pendingAssignmentsLoad = $(this);
			$(this).parents(".classContainer").find(".pendingAssignments").slideUp("normal", function (){showHideSwitch(pendingAssignmentsLoad);});
			},
		function()
			{
			var pendingAssignmentsLoad = $(this);
			$(this).parents(".classContainer").find(".pendingAssignments").slideDown("normal", function (){showHideSwitch(pendingAssignmentsLoad);});
			}
		);
		
	$(".oldAssignmentsLoad").unbind("click").toggle
		(
		function()
			{
			loadOldAssignments (pageType,$(this));
			},
		function()
			{
			hideOldAssignments ($(this));
			}
		);
		
	$(".expiredClassAssignmentsLoad").unbind("click").click(function()
		{
		var clicked = $(this);
		clicked.parents(".classContainer").find(".expiredClassAssignments").slideToggle("normal", function () {showHideSwitch(clicked);});
		});
		
	$("#newClassLoad span").unbind("click").click(function()
		{
		loadNewClass (pageType);
		});
		
	$(".removeClass").unbind("click").click(function()
		{
		$(this).fadeOut("normal", function (){$(this).siblings(".removeClassConfirm").fadeIn("normal");});
		});
		
	$(".removeClassCancel").unbind("click").click(function()
		{
		$(this).parent().fadeOut("normal", function () {$(this).siblings(".removeClass").fadeIn("normal");});
		});
		
	$(".removeClassLoad").unbind("click").click(function()
		{
		var removeClassLoad = $(this);
		var strData = "classID=" + removeClassLoad.parents(".classContainer").attr("id");
		removeClass (pageType, strData, removeClassLoad);
		});
		
	$(".classContainer .showClassInfo").unbind("click").click(function()
		{
		var clicked = $(this);
		clicked.closest(".classOperations").siblings(".classInfo").slideToggle("normal", function () {showHideSwitch(clicked);});
		});
		
	$(".classContainer .showClassRoster").unbind("click").click(function()
		{
		var courseid = $(this).parents(".classContainer").attr("id");
		var dataObj = {"courseid":courseid};
		loadQtipRoster($(this),dataObj);
		});
		
	$(".classContainer .showClassOptions").unbind("click").click(function()
		{
		var courseid = $(this).parents(".classContainer").attr("id");
		var dataObj = {"courseid":courseid};
		loadQtipClassOptions($(this),dataObj);
		});
		
	$(".newAssignmentLoad").unbind("click").toggle(
		function()
			{
			var trigger = $(this);
			var container = trigger.siblings(".newAssignment");
			var url = HTML_ROOT + "/includes/htmlBlocks/createAssignment.php";
			var classid = trigger.parents(".classContainer").attr("id");
			var strData = "classid=" + classid;
			var callback = function ()
				{
				showHideSwitch(trigger);
				}
			slideLoad (container, url, strData, "", callback);	
			},
		function()
			{
			var trigger = $(this);
			trigger.siblings(".newAssignment").slideUp("normal", function(){showHideSwitch(trigger);});
			}
		);
		
	$(".classContainer .editInfo").unbind("click").click(function()
		{
		var clicked = $(this);
		var classid = clicked.parents(".classContainer").attr("id");
		var container = clicked.parents(".classInfo");
		var oldHtml = container.html();
		var url = HTML_ROOT + "/includes/htmlBlocks/classInfo.php";
		var strData = "pageType=" + pageType + "&classid=" + classid + "&edit=true";
		var callback = function ()
			{
			bindEditClassInfoBehaviors(pageType, oldHtml);
			}
		fadeInLoadNoJump(container, url, strData, callback);
		});
		
	bindAssignmentListBehaviors ();
	}
	
var bindEditClassInfoBehaviors = function (pageType, oldHtml)
	{
	preventSubmit($(".editClassInfoForm"));
	$(".classContainer .editInfoCancel").unbind("click").click(function()
		{
		var container = $(this).parents(".classInfo");
		var callback = function (){bindHomeClassListBehaviors(pageType);};
		htmlReplaceFadeNoJump(container, oldHtml,callback);
		});
		
	$(".classContainer .editInfoSubmit").unbind("click").click(function()
		{
		var clicked = $(this);
		var form = clicked.parents(".editClassInfoForm");
		var classid = clicked.parents(".classContainer").attr("id");
		var errorElement = form.children(".error");
		
		errorElement.html("");
		
		if (checkForBlanks("#" + classid + " .editClassInfoForm"))
			errorElement.html("Fill in all the fields and try again.");
		else
			{
			var url = HTML_ROOT + "/includes/htmlBlocks/updateClassInfo.php";
			var strData = form.serialize();
			var callback = function ()
				{
				var newClassName = $("#" + classid + " .editClassInfoForm [name='name']").val();
				var containerCB = clicked.parents(".classInfo");
				var urlCB = HTML_ROOT + "/includes/htmlBlocks/classInfo.php";
				var strDataCB = "pageType=" + pageType + "&classid=" + classid;
				var callbackCB = function ()
					{
					$("#" + classid + " legend.className").html(newClassName);
					bindHomeClassListBehaviors(pageType);
					}
				fadeInLoadNoJump(containerCB, urlCB, strDataCB, callbackCB);
				}
			basicAjax (url, strData, callback);
			}
		});

	$("select[name='school']").change(function()
		{
		if ($(this).val() == "newSchool")
			loadSchoolFinder($(this));
		})
	.click(function()
		{
		var optionCount = $(this).find("option").length;
		if (optionCount == 1)
			loadSchoolFinder($(this));
		});
		
	$("select[name='schoolLevel']").change(function()
		{
		if ($(this).val() == "High School")
			$(this).parents("form").find("select[name='courseLevel']").val("Beginning").children("option[value='Advanced']").attr("disabled","disabled");
		else
			$(this).parents("form").find("select[name='courseLevel'] option[value='Advanced']").attr("disabled","");
		});

	}
	
//clicked must be set to a school select element.
var loadSchoolFinder = function (clicked)
	{
	getLargeTip ({
		target: clicked,
		position: {
			corner: {target: 'rightMiddle',tooltip: 'leftMiddle'},
			adjust: {scroll: false, screen: false}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/findSchool.php",
		container: clicked,
		callback: function(tooltip) {
			var api = tooltip.qtip("api");
			var target = api.elements.target;
			bindSchoolFinderBehaviors(target, tooltip);
		},
		title: "School Finder",
		tooltipClass: "schoolFinder"
	});
	/*clicked.qtip
		({
		content: 
			{
			text: "Loading...",
			url: HTML_ROOT + "/includes/htmlBlocks/findSchool.php",
			title: 
				{
				text: "<span class='large'>Find Your School</span>",
				button: "X"
				}
			},
		api: 
			{
			onContentUpdate: function()
				{
				var api = clicked.qtip("api");
				var tooltip = api.elements.tooltip;
				bindSchoolFinderBehaviors(clicked, tooltip);
				},
			onHide: function()
				{
				clicked.qtip('destroy');
				}
			},
		style: {name: 'largetip', classes: {tooltip: 'qtip schoolFinder'}, width: 400},
		position:
			{
			corner: 
				{
				target: 'rightMiddle',
				tooltip: 'leftMiddle'
				},
			scroll: false,
			screen: false
			},
		show: 
			{
			solo: false,
			when: false,
			ready: true,
			effect: largetipShowEffect
			},
		hide:
			{
			when: 'change',
			effect: largetipHideEffect
			}
		});*/
	}
	
//target should be the select box that served as the qtip target element.
var bindSchoolFinderBehaviors = function (target, tooltip)
	{
	var api = target.qtip('api');//We needed this for ie, along with the api.hide() call in addSchool(). For some reason, it didn't like target.qtip("hide").
	//var tooltip = api.elements.tooltip;
	var loadSchoolList = function (data)
		{
		var container = tooltip.find(".schoolSearchResults");
		var url = HTML_ROOT + "/includes/htmlBlocks/getSchoolList.php";
		var callback = function()
			{
			bindSchoolListBehaviors();
			}
			
		basicAjaxLoad(container, url, data, callback);
		}
		
	var addSchool = function (data)
		{
		var url = HTML_ROOT + "/includes/htmlBlocks/addSchool.php";
		var callback = function ()
			{
			api.destroy();
			}
		basicAjaxLoad (target, url, data, callback);
		}
		
	var bindSchoolListBehaviors = function ()
		{
		tooltip.find(".schoolList .addSchool").click(function()
			{
			addSchool($(this).find("form").serialize());
			});
		}	
		
	tooltip.find(".homeschoolSubmit").click(function()
		{
		addSchool("schoolid="+$(this).find("input[name='schoolid']").val());
		});
		
	tooltip.find(".schoolSearchList form").submit(function()
		{
		if (!blankCheck($(this).find("input").not(":hidden")))
			loadSchoolList($(this).serialize());
		});
	
	tooltip.find(".getAllSchools").click(function()
		{
		loadSchoolList();
		});
		
	tooltip.find(".createSchool").click(function()
		{
		//tooltip.find(".createSchoolForm").slideDown("normal");
		tooltip.find(".createSchoolForm").show();
		});

	tooltip.find(".createSchoolForm").submit(function()
		{
		if (!blankCheck($(this).find("input").not(":hidden")))
			{
			addSchool ($(this).serialize());
			}
		});
	}
	
var qtipChallenge = function (target, position, dataObj, container, callback) {
	target.qtip ({
		content: {
			text: "Loading...",
			url: HTML_ROOT + "/includes/htmlBlocks/getQtipChallenge.php",
			data: dataObj,
			title: {
				text: "<span class='large'>Question Challenge</span>",
				button: "X"
			}
		},
		api: {
			onContentUpdate: function() {
				var api = target.qtip("api");
				var tooltip = api.elements.tooltip;
				bindQtipChallengeBehaviors(tooltip, target);
				if ($.isFunction(callback))
					callback(tooltip);
			},
			onHide: function() {
				target.qtip('destroy');
				if (target.is(".centerBox"))
					target.remove();
			}
		},
		style: {name: 'largetip', classes: {tooltip: 'qtip qtipChallenge'}, width: 500},
		position: position,
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
		},
		hide:{
			when: false,
			effect: largetipHideEffect
		}
	});
}	

var bindQtipChallengeBehaviors = function (tooltip, target) {
	
	$(".questionChallengeForm").unbind("submit").bind("submit", function (e) {
		e.preventDefault();
		var url = HTML_ROOT+"/includes/htmlBlocks/addChallenge.php";
		var data = $(this).serialize();
		var callback = function () {
			tooltip.hide();
			target.html("You challenged this question").removeClass("clickText").addClass("em").unbind('click');
		}
		basicAjax (url, data, callback);
	});
}

var loadQuestionChallenge = function (clicked, dataObj) {
	var target = clicked;
	var position = {
		adjust: {screen: false,scroll: false, y: -320, x: 0},
		corner: {target: 'topRight',tooltip: 'topLeft'}
	};
	var container = target;
		
	var callback = function (tooltip) {
		
	}
	qtipChallenge (target, position, dataObj, container, callback);
}

var qtipComment = function (target, position, dataObj, container, callback) {
	target.qtip ({
		content: {
			text: "Loading...",
			url: HTML_ROOT + "/includes/htmlBlocks/getQtipComment.php",
			data: dataObj,
			title: {
				text: "<span class='large'>Question Comment</span>",
				button: "X"
			}
		},
		api: {
			onContentUpdate: function() {
				var api = target.qtip("api");
				var tooltip = api.elements.tooltip;
				bindQtipCommentBehaviors(tooltip, target);
				if ($.isFunction(callback))
					callback(tooltip);
			},
			onHide: function() {
				target.qtip('destroy');
				if (target.is(".centerBox"))
					target.remove();
			}
		},
		style: {name: 'largetip', classes: {tooltip: 'qtip qtipComment'}, width: 500},
		position: position,
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
		},
		hide:{
			when: false,
			effect: largetipHideEffect
		}
	});
}	

var bindQtipCommentBehaviors = function (tooltip, target) {
	
	$(".questionCommentForm").unbind("submit").bind("submit", function (e) {
		e.preventDefault();
		var url = HTML_ROOT+"/includes/htmlBlocks/addComment.php";
		var data = $(this).serialize();
		var callback = function () {
			tooltip.hide();
			target.html("You commented on this question").removeClass("clickText").addClass("em").unbind('click');
		}
		basicAjax (url, data, callback);
	});
}

var loadQuestionComment = function (clicked, dataObj) {
	var target = clicked;
	var position = {
		adjust: {screen: false,scroll: false, y: -320, x: 0},
		corner: {target: 'topRight',tooltip: 'topLeft'}
	};
	var container = target;
		
	var callback = function (tooltip) {
		
	}
	qtipComment (target, position, dataObj, container, callback);
}

var qtipRoster = function (target, position, dataObj, container, callback) {
	target.qtip ({
		content: {
			text: "Loading...",
			url: HTML_ROOT + "/includes/htmlBlocks/getQtipRoster.php",
			data: dataObj,
			title: {
				text: "<span class='large'>Class Roster</span>",
				button: "X"
			}
		},
		api: {
			onContentUpdate: function() {
				var api = target.qtip("api");
				var tooltip = api.elements.tooltip;
				bindQtipRosterBehaviors(tooltip, target);
				if ($.isFunction(callback))
					callback(tooltip);
			},
			onHide: function() {
				target.qtip('destroy');
				if (target.is(".centerBox"))
					target.remove();
			}
		},
		style: {name: 'largetip', classes: {tooltip: 'qtip qtipComment'}, width: 500},
		position: position,
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
		},
		hide:{
			when: false,
			effect: largetipHideEffect
		}
	});
}	

var bindQtipRosterBehaviors = function (tooltip, target) {
}

var loadQtipRoster = function (clicked, dataObj) {
	var target = clicked;
	var position = {
		adjust: {screen: false,scroll: false},
		corner: {target: 'rightMiddle',tooltip: 'rightMiddle'}
	};
	var container = target;
		
	var callback = function (tooltip) {
		
	}
	qtipRoster (target, position, dataObj, container, callback);
}

var loadQtipClassOptions = function (clicked, dataObj) {
	getLargeTip ({
		target: clicked,
		position: {
			adjust: {screen: false,scroll: false},
			corner: {target: 'rightMiddle',tooltip: 'rightMiddle'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipClassOptions.php",
		dataObj: dataObj,
		container: clicked,
		callback: function(tooltip) {
		},
		title: "Class Options",
		tooltipClass: "qtipClassOptions"
	});
}

var loadClassList = function (clicked, dataObj) {
	getLargeTip ({
		target: clicked,
		position: {
			adjust: {screen: false,scroll: false},
			corner: {target: 'rightMiddle',tooltip: 'rightMiddle'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipClassList.php",
		dataObj: dataObj,
		container: clicked,
		callback: function(tooltip) {
		},
		title: "Class List",
		tooltipClass: "qtipClassList"
	});
}

var loadExamPurchase = function (target, dataObj) {
	if (target == null)
		target = createCenterBox(null, null, null, "fixed");
	getLargeTip ({
		target: target,
		position: {
			adjust: {screen: false,scroll: false},
			corner: {target: 'topLeft',tooltip: 'topLeft'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipExamPurchase.php",
		dataObj: dataObj,
		container: target,
		callback: function(tooltip) {
		},
		title: "Purchase Exam Access",
		tooltipClass: "qtipExamPurchase"
	});
}

var loadPassageEditor = function (target, dataObj) {
	if (target == null)
		target = createCenterBox(null, null, null, "absolute");
	getLargeTip ({
		target: target,
		position: {
			adjust: {screen: false,scroll: false,x:200,y:-350},
			corner: {target: 'topMiddle',tooltip: 'topMiddle'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipPassageEditor.php",
		dataObj: dataObj,
		container: target,
		callback: function(tooltip) {
		},
		title: "User Passages",
		tooltipClass: "qtipPassageEditor"
	});
}
	
//container is sent to the callback, where, if the tags are submitted, they are loaded into the container.	
var qtipTagger = function (target, position, dataObj, container, callback)
	{
	target.qtip
		({
		content: 
			{
			text: "Loading...",
			url: HTML_ROOT + "/includes/htmlBlocks/getQtipTagger.php",
			data: dataObj,
			title: 
				{
				text: "<span class='large'>Select Your Tags</span>",
				button: "X"
				}
			},
		api: 
			{
			onContentUpdate: function()
				{
				var api = target.qtip("api");
				var tooltip = api.elements.tooltip;
				bindQtipTaggerBehaviors(tooltip,container);
				if ($.isFunction(callback))
					callback(tooltip);
				},
			onHide: function()
				{
				target.qtip('destroy');
				if (target.is(".centerBox"))
					target.remove();
				}
			},
		style: {name: 'largetip', classes: {tooltip: 'qtip qtipTagger'}, width: 500},
		position: position,
		show: 
			{
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
			},
		hide:
			{
			when: false,
			effect: largetipHideEffect
			}
		});
	}

//clicked should be an edit clicktext.	
var loadQuestionTagging = function (clicked, dataObj)
	{
	/*var target = clicked;
	var position = {
		adjust: {screen: false,scroll: false,x: 105,y:40},
		corner: {target: 'bottomLeft',tooltip: 'bottomLeft'}
	};*/
	var target = clicked;
	var position = {
		adjust: {screen: false,scroll: false,x:200,y:-350},
		corner: {target: 'topMiddle',tooltip: 'topMiddle'}
	};
	if (clicked.parents(".questionInfo").length == 1)
		var container = clicked.parents(".questionInfo").find(".taglist");
	else
		var container = clicked.parents(".createQuestion").find(".taglist");
		
	var callback = function (tooltip) {
		$.scrollTo(tooltip,500);
	}
	qtipTagger (target, position, dataObj, container, callback);
	}
	
var loadFilterTagging = function (clicked, dataObj)
	{
	//set variables for loading qtipTagger.
	var target = clicked.parents("form").parent();
	var position = {
		adjust: {screen: false,scroll:false,x:-60,y:50},
		corner: {target: 'topRight',tooltip: 'topLeft'}
		};
	var container = $("#filterForm #taglist");
	qtipTagger (target, position, dataObj, container);
	}

var loadCategoryTagging = function (clicked, dataObj)
	{
	//var target = createCenterBox($("#editExamContainer"),500,{left:0,top:"top"});
	var target = clicked.parents(".category");
	var position = {
		adjust: {screen: false,scroll:false,x:200,y:-275},
		corner: {target: 'topLeft',tooltip: 'topLeft'}
		};
	var container = clicked.parents(".category").find(".taglist");
	qtipTagger (target, position, dataObj, container);
	}

var bindQtipTaggerBehaviors  = function (tooltip,container)
	{
	var api = tooltip.qtip("api");
	var target = api.elements.target;
	var speed = 300;
	var maintags = tooltip.find("ul.mainTagList li");
	var subtags = tooltip.find("form.subtags");
	var defaultTagInfo = tooltip.find(".defaultTags").children("p");
	var back = tooltip.find(".back");
	var customTags = tooltip.find(".customTags");
	var custagsform = customTags.find("form.custagsform");
	var infoForm = tooltip.find("form.taggingInfo");
	var prevTags = "," + tooltip.find("input[name='prevTags']").val() + ",";
	var errorContainer = tooltip.find(".tagsSubmit .error");
	
	tooltip.find("input[name='maintag']").click(function(){
		var maintagid = $(this).val();
		var mainTag = $(this).closest("li");
		var subtagform = subtags.filter(".subtags" + maintagid);
		if ($(this).data("checked") == true) {
			subtagform.slideUp(speed, function(){api.updatePosition();});
			maintags.not(mainTag).slideDown(speed);
			//defaultTagInfo.slideUp(speed);
			back.hide();
			$(this).attr("checked","").data("checked",false);
		}
		else {
			
			subtags.not(subtagform).slideUp(speed);
			maintags.not(mainTag).slideUp(speed).find("input[name='maintag']").data("checked",false);
			$(this).data("checked",true);
			//defaultTagInfo.slideUp(speed);
			back.show();
			subtagform.slideDown(speed, function(){api.updatePosition();});
		}
	});
	
	tooltip.find("input[name='subtags[]']").click(function(e,show)
		{
		var li = $(this).closest("li");
		if (subList = li.children("ul"))
			{
			if ($(this).is(":checked") || show == "show")
				subList.slideDown(speed, function(){api.updatePosition();});
			else
				subList.slideUp(speed, function(){subList.find("input").attr("checked",""); api.updatePosition();}).end().find("ul").slideUp(speed);
			}	
		});
	
	tooltip.find(".showcustags").click(function()
		{
		var clicked = $(this);
		customTags.slideToggle(speed, function(){showHideSwitch(clicked);api.updatePosition();});
		});
		
	var loadEditTag = function (submit_val, tagid, tagname)
		{
		customTags.find(".editTagContainer").find("input[name='tagid']").val(tagid)
			.end().find("input[name=tagname]").val(tagname)
			.end().find("input.editTagSubmit").val(submit_val)
			.end().slideDown();
		}
		
	var hideEditTag = function () {
		customTags.find(".editTagContainer").slideUp().find("input[name=tagname]").val("");
	}
		
	tooltip.find(".createTagLoad").click(function()
		{
		loadEditTag("Create Tag","create","");
		});
	
	tooltip.find(".renameTagLoad").click(function() {
		var selected = custagsform.find("select[name='custags[]'] option:selected");
		if (selected.length == 1) {
			var tagid = selected.val();
			var tagname = selected.html();
		}
		if (parseInt(tagid) > 0) {
			loadEditTag("Rename Tag",tagid,tagname);
		}
	});
		
	tooltip.find(".editTagSubmit").click(function()
		{
		var container = customTags.find("select[name='custags[]']");
		var url = HTML_ROOT+"/includes/htmlBlocks/addTag.php";
		var tagname = customTags.find("input[name=tagname]").val();
		var tagid = customTags.find("input[name=tagid]").val();
		if (!parseInt(infoForm.find("input[name='questionid']").val()) > 0 || tagid !== "create") {
			var strData = custagsform.serialize() + "&tagname=" + tagname + "&tagid=" + tagid;
		}
		else {
			var strData = infoForm.serialize() + "&tagname=" + tagname + "&tagid=" + tagid;
		}
		var callBack = function ()
			{
			if (container.find("option").length > 0)
				container.closest("form").slideDown(speed);
			hideEditTag();
			}
		basicAjaxLoad (container, url, strData, callBack);
		});
		
	tooltip.find(".editTagCancel").click(function()
		{
		hideEditTag();
		});	
	
	back.click(function()
		{
		subtags.slideUp(speed);
		maintags.slideDown(speed);
		back.hide();
		defaultTagInfo.slideDown(speed);
		});
		
	tooltip.find(".tagsSubmit").find("input.submit").click(function()
		{
		if (maintags.find("input:checked").length > 0)
			var maintagid = maintags.find("input:checked").val();
		else
			var maintagid = "";
		var subtagform = subtags.filter(".subtags" + maintagid);
		var strdata = subtagform.serialize() + "&" + custagsform.serialize() + "&" + infoForm.serialize() + "&maintag=" + maintagid;
		var url = HTML_ROOT + "/includes/htmlBlocks/updateTagList.php";
		var callback = function() {
			if ($("#editExamContainer").length == 1)
				{//if we're on the instructor exams page
				container.parents(".category").find(".checkQuestionCount").trigger("click");
				}
		}
		
		if (!maintagid > 0 && !custagsform.find("[name='custags[]']").find("option:selected").length > 0)
			errorContainer.text("You didn't select any tags.");
		else
			{
			fadeInLoadNoJump (container, url, strdata, callback);
			target.qtip('hide');
			
			}
		});
		
	if (prevTags.length > 0)
		{
		tooltip.find("input[name='maintag']").each(function()
			{
			if (prevTags.match("," + $(this).val() + ",") !== null)
				{
				$(this).trigger("click");
				subtags.filter(".subtags"+$(this).val()).find("input[name='subtags[]']").each(function()
					{
					if (prevTags.match("," + $(this).val() + ",") !== null)
						$(this).trigger("click",["show"]);
					});
				}
			});
		custagsform.find("select[name='custags[]'] option").each(function()
			{
			if (prevTags.match("," + $(this).val() + ",") !== null)
				$(this).attr("selected","selected");
			else
				$(this).attr("selected","");
			});
		
		if (custagsform.find("select[name='custags[]'] option:selected").length > 0)
			tooltip.find(".showcustags").trigger("click");
		}
	}
	
var bindAssignmentListBehaviors = function ()
	{
	$(".assignment .edit").unbind("click").click(function()
		{
		var container = $(this).parents(".assignment");
		var url = HTML_ROOT + "/includes/htmlBlocks/editAssignment.php";
		var assignmentid = container.attr("id").replace("assign","");//the id of that div is "assign" followed by the id, so there isn't overlap with class ids.
		var strData = "assignmentid=" + assignmentid;
		fadeInLoadNoJump (container, url, strData);
		});
	
	$(".assignment .delete").unbind("click").click(function()
		{
		$(this).fadeOut("normal", function(){$(this).next().fadeIn("normal");});
		});
		
	$(".assignment .deleteCancel").unbind("click").click(function()
		{
		$(this).parent().fadeOut("normal", function(){$(this).prev().fadeIn("normal");});
		});
	
	$(".assignment .deleteLoad").unbind("click").click(function()
		{
		//something like this
		var deleteAssignmentLoad = $(this);
		var url = HTML_ROOT + "/includes/htmlBlocks/deleteAssignment.php";
		var assignmentid = deleteAssignmentLoad.parents(".assignment").attr("id").replace("assign","");
		var classid = deleteAssignmentLoad.parents(".classContainer").attr("id");
		var strData = "assignmentid=" + assignmentid + "&classid=" + classid;
		var assignmentCount = $(".assignment").length;
		var callback = function()
			{
			if (assignmentCount != 1)
				{
				deleteAssignmentLoad.parents(".assignment").slideUp("normal", function(){$(this).remove();});
				}
			else
				{
				//If we want something to change about the create a new assignment message or anything, we may need code here. 
				}
			}
		basicAjax (url, strData, callback);
		});
		
	$(".assignment .showAssignmentDescription").unbind("click").click(function()
		{
		var clicked = $(this);
		clicked.parents(".assignment").find(".description").slideToggle("normal", function () {showHideSwitch(clicked);});
		});
		
	$(".showResults").unbind("click").click(function()
		{
		var clicked = $(this);
		clicked.parents(".assignment").find(".results").slideToggle("normal", function() {showHideSwitch(clicked);});
		});
		
	$(".viewResults").unbind("click").click(function()
		{
		var url = HTML_ROOT + "/account/studentResults.php";
		var data = $(this).find("form").serialize();
		loadNewContent (url, data);
		});
		
	$(".viewClassResults").unbind("click").click(function()
		{
		var url = HTML_ROOT + "/account/instructorResults.php";
		var data = $(this).find("form").serialize();
		loadNewContent (url, data);
		});
	}
	
var bindExamInfoBehaviors = function ()
	{		
	var reloadExamList = function ()
		{
		var container = $("#instructorExamList");
		var url = HTML_ROOT + "/includes/htmlBlocks/instructorExamList.php";
		fadeInLoadNoJump (container, url, "", bindExamListBehaviors);
		}
	
	var loadEditExam = function (clicked, container, customData, callback)
		{
		var oldHtml = container.html();
		var url = HTML_ROOT + "/includes/htmlBlocks/editExam.php";
		var editType = container.children("input[name='editType']").val();
		var examid = clicked.parents(".examInfo").find("input[name='examid']").val();
		var strData = "editType=" + editType + "&examid=" + examid + "&" + customData;
		fadeInLoadNoJump (container, url, strData, function()
			{
			if ($.isFunction(callback))
				callback();
			bindEditExamBehaviors(oldHtml, container);
			});
		}
		
	//Click function for normal edit exam clicktexts. the Category edits are unique, so they are dealt with separately.
	$(".editExam").unbind("click").click(function()
		{
		var container = $(this).parents(".examInfoCategory").find(".examInfoContainer");
		loadEditExam ($(this), container);
		});
		
	//slightly different than the normal edit exam click function.
	$(".editCategory").die("click").live("click", function()
		{
		$(".deleteCategoryConfirm").hide().siblings(".deleteCategory").show();//<OCD>in case they had clicked delete, not responded, and then clicked edit.</OCD>
		var container = $(this).parents(".category");
		var data = "examCategoryid=" + container.children("input[name='examCategoryid']").val();
		loadEditExam ($(this), container, data);
		});
	
	
		
	$(".category .choosePassageLoad").die("click").live("click",function()
		{
		var passagesInput = $(this).parents(".category").find(".passagelist input[name*='passages']");
		var passages = passagesInput.val();
		var categorykey = passagesInput.attr("name").replace("passages[","").replace("]","");
		
		var categoryid = $(this).parents(".category").find("input[name*='examCategoryid']").val();
		dataObj = {"passageType":"category","passages":passages,"categorykey":categorykey,"categoryid":categoryid};
		loadPassageEditor ($(this),dataObj);
		});
		
	$(".deleteCategory").die("click").live("click", function()
		{
		$(this).fadeOut("normal", function (){$(this).siblings(".deleteCategoryConfirm").fadeIn("normal");});
		});
		
	$(".deleteCategoryCancel").die("click").live("click", function()
		{
		$(this).parent().fadeOut("normal", function () {$(this).siblings(".deleteCategory").fadeIn("normal");});
		});
		
	$(".deleteCategoryLoad").die("click").live("click", function()
		{
		var clicked = $(this);
		var examid = clicked.parents(".examInfo").find("input[name='examid']").val();
		var examCategoryid = clicked.parents(".category").find("input[name='examCategoryid']").val();
		var url = HTML_ROOT + "/includes/htmlBlocks/deleteCategory.php";
		var strData = "examid=" + examid + "&examCategoryid=" + examCategoryid;
		var animateDelete = function()
			{
			clicked.parents(".category").slideUp("normal", function()
				{
				$(this).remove();
				});
			}
			
		basicAjax (url, strData, animateDelete)
		});
		
	$(".addCategory").unbind("click").click(function()
		{	
		var newCategoryDiv = $(".category:hidden");
		newCategoryDiv.clone().insertAfter(newCategoryDiv);
		
		if ($(this).parents(".createExamForm").length)//If this is for a new exam creation
			{
			var url = HTML_ROOT + "/includes/htmlBlocks/getNewExamCategory.php";
			var key = parseInt($("div.category:visible:last").find("input[name*='categoryName']").attr("name").replace("categoryName[","").replace("]","")) + 1;//This is the key for the new category. finds last visible category and adds 1 to that key.
			var data = "key=" + key;
			var callback = function ()
				{
				}
			}
		else
			{
			var url = HTML_ROOT + "/includes/htmlBlocks/editExam.php";
			var examid = $(this).parents(".examInfo").find("input[name='examid']").val();
			var data = "editType=category&examid=" + examid;
			var callback = function ()
				{
				bindEditExamBehaviors("",newCategoryDiv);
				}
			}
			
		slideLoad (newCategoryDiv, url, data, callback);
		});
		
	$(".deleteExam").unbind("click").click(function()
		{
		$(this).fadeOut("normal", function (){$(this).siblings(".deleteExamConfirm").fadeIn("normal");});
		});
		
	$(".deleteExamCancel").unbind("click").click(function()
		{
		$(this).parent().fadeOut("normal", function () {$(this).siblings(".deleteExam").fadeIn("normal");});
		});
		
	$(".deleteExamLoad").unbind("click").click(function()
		{
		var clicked = $(this);
		//if this exam is assigned, bring up a qtip. If not, delete the exam.
		if ($(this).find("input[name='assigned']").val() == 1)
			{
			var examid = $(this).parents(".examInfo").find("input[name='examid']").val();
			clicked.qtip
				({
				content: 
					{
					text: "Loading...",
					url: HTML_ROOT + "/includes/htmlBlocks/getDeleteExamAssigned.php",
					data: {examid: examid},
					title: 
						{
						text: "Delete Exam",
						button: "X"
						}
					},
				api: 
					{
					onContentUpdate: function()
						{
						var api = clicked.qtip("api");
						var tooltip = api.elements.tooltip;
						bindDeleteExamAssignedBehaviors(clicked, tooltip);
						},
					onHide: function()
						{
						clicked.parents(".examInfo").find(".deleteExamCancel").trigger("click");
						clicked.qtip('destroy');
						}
					},
				style: {name: 'largetip', classes: {tooltip: 'qtip deleteExamAssigned'}},
				position:
					{
					corner: 
						{
						target: 'topLeft',
						tooltip: 'bottomRight'
						}
					},
				show: 
					{
					solo: false,
					when: false,
					ready: true,
					effect: largetipShowEffect
					},
				hide:
					{
					when: false,
					effect: largetipHideEffect
					}
				});
			}
		else
			deleteExam (clicked.parents(".examInfo"));
		});

	var bindDeleteExamAssignedBehaviors = function (target, tooltip)
		{
		preventSubmit(tooltip.find("form"));
		tooltip.find("form.deleteOptionForm").submit(function()
			{
			target.qtip('hide');
			if ($(this).find("input[name='deleteOption']:checked").val() != 3)
				deleteExam (target.parents(".examInfo"),$(this).serialize());
				
			});
		}
		
	//Exam is the examInfo element, and data is sent to the url via post, not including examid (this function gets examid on its own).
	var deleteExam = function (exam, data)
		{
		var url = HTML_ROOT + "/includes/htmlBlocks/deleteExam.php";
		var examid = exam.find("input[name='examid']").val();
		var strData = "examid=" + examid;
		if (data != null && data != undefined)
			strData = strData + "&" + data;
		var animateDelete = function()
			{
			exam.slideUp("normal", function()
				{
				$(this).remove();
				reloadExamList();
				});
			}
			
		basicAjax (url, strData, animateDelete)
		}
		
	preventSubmit($(".createExamForm"));
	$(".createExamSubmit").unbind("click").click(function()
		{
		var form = $(this).parents(".createExamForm");
		form.find(".taglist").removeClass("warningHighlight")
			.end().find(".error").html("");
		if (!blankCheck(form.find("input:not([name*='passages['])")))
			{
			var error = 0;
			$(".category:visible").each(function()//This does not run for the hidden category at the end that receives added category html.
				{
				var thisCategory = $(this);
				var errorDiv = thisCategory.find(".categoryError").html("");
				var categoryKey = thisCategory.find("input[name*='categoryName']").attr("name").replace("categoryName[","").replace("]","");
				
				var questionCheckUrl = HTML_ROOT + "/includes/htmlBlocks/getQuestionCount.php";
				var questionCheckData = "key=" + categoryKey + "&" + form.serialize();
				if (thisCategory.nextAll(".category").length == 1)//If this is true, we are on the last category
					{
					var callback = function ()
						{
						if ($(".categoryError").text().length < 4)
							{
							var container = $("#editExamContainer");
							var url = HTML_ROOT + "/includes/htmlBlocks/addExam.php";
							var data = form.serialize();
							var callback = function ()
								{
								bindExamInfoBehaviors();
								$("#createExamForm .submit").attr("disabled","");
								reloadExamList();
								var createdExamsInput = $("#userPageInfo input[name='createdExams']");
								if (createdExamsInput.val() == 0)
									{
									helpbox ("firstCreatedExam.php");
									createdExamsInput.val(1);
									}
								}
							fadeInLoad (container, url, data, callback);
							}
						}
					}
				basicAjaxLoad (errorDiv, questionCheckUrl, questionCheckData, callback);
				});
			}
		else if (form.find("input[name*='tags['].warningHighlight").length>0)
			{
			form.find(".error").html("Make sure you select tags for each of your question groups.");
			form.find("input[name*='tags['].warningHighlight").each(function()
				{
				$(this).parent().addClass("warningHighlight");
				});
			}
		});
	}
	

	
var bindEditExamBehaviors = function (oldHtml, container)
	{
	preventSubmit ($(".examForm"));
	var updateExam = function (container)
		{
		var url = HTML_ROOT + "/includes/htmlBlocks/updateExam.php";
		var data = container.find(".examForm").serialize();
		fadeInLoadNoJump (container, url, data);
		}
		
	container.find(".editExamInfoSubmit").unbind("click").click(function()
		{		
		var form = container.find(".examForm");
		var editType = form.find("input[name='editType']").val();
		var errorDiv = form.find(".error").html("");
		//Add blank checking, and also checking if there are no tags selected
		if (!blankCheck(form.find("input:not(:hidden)")))
			{
			if ($("h1").text() !== "Edit National Exam")
				{//I know, this is a hack job
				if (editType == "category")
					{
					var questionCheckUrl = HTML_ROOT + "/includes/htmlBlocks/getQuestionCount.php";
					var questionCheckData = form.serialize();
					var callback = function ()
						{
						if (errorDiv.text().length < 2)
							updateExam (container);
						}
						
					basicAjaxLoad (errorDiv, questionCheckUrl, questionCheckData, callback);
					}
				else
					{
					updateExam (container);
					}
				}
			else
				{
				updateExam (container);
				}
			}
		});
	
	container.find(".editExamInfoCancel").unbind("click").click(function()
		{
		if (oldHtml == "")
			container.slideUp("normal", function () {$(this).remove();});
		else
			htmlReplaceFadeNoJump (container, oldHtml);
		});
	}
	
var bindExamResultsBehaviors = function ()
	{
	//moved to live functions in the specific pages section
	}
	
var bindClassResultsBehaviors = function ()
	{
	$(".viewResultDetails").unbind("click").click(function() {
		getLargeTip({
			target: $("#resultsContainer"),
			url: HTML_ROOT + "/includes/htmlBlocks/getExamResults.php",
			dataObj: {
				examid: $(this).siblings(".resultDetailsForm").find("input[name='examid']").val(),
				examResultsid: $(this).siblings(".resultDetailsForm").find("input[name='examResultsid']").val(),
				pageType: "instructor"
			},
			callback: function(){bindExamResultsBehaviors();},
			title: "Exam Details",
			tooltipClass: "studentResultDetails",
			position: {corner: {target: "topMiddle",tooltip: "topLeft"}, adjust: {x: -150}}
		});
	});
}
	
//--------------------AJAX FUNCTIONS--------------------//
//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(".modifyOptions").each(function() {
		var options = $(this);
		var parent = options.parent();
		parent.qtip({
			content: {
				text: "<div style='position: absolute; z-index: 10000; top: +0px;left: +12px;'>"+options.html() + "</div>"
			},
			style: {name: 'modifytip', classes: {tooltip: 'qtip modifytip'},width: 90, height: 1},
			position: {
				target: 'mouse', 
				adjust:{y:5,x:3},
				corner: {target: 'bottomRight',tooltip: 'leftMiddle'}
			},
			show: {
				delay: 600,
				effect: modifytipShowEffect
			},
			hide:{
				fixed: true,
				effect: modifytipHideEffect
			}
		});
	});*/
	/*container.find(".help").each(function() {
		var help = $(this);
		var parent = help.parent();
		parent.qtip({
			content: {
				text: help.html(),
				title: {
					text: "<span class='large'>Help</span>",
					button: "X"
				}
			},
			style: {name: 'helptip', classes: {tooltip: 'qtip helptip'}, width: 400},
			position: {
				target: parent, 
				adjust:{y:0,x:0},
				corner: {target: 'bottomRight',tooltip: 'leftMiddle'}
			},
			show: {
				when: {target: parent, event: 'click'},
				effect: largetipShowEffect
			},
			hide:{
				fixed: true,
				when: 'unfocus',
				effect: largetipHideEffect
			}
		});
	});*/
	//I used this code below because the function above wasn't working. All sorts of odd, finnicky things going on.
	container.find(".help").each(function() {
		var help = $(this);
		var parent = help.parent();
		parent.toggle(
			function() {
				$(this).qtip({
					content: {
						text: help.html(),
						title: {
							text: "<span class='large'>Help</span>",
							button: "X"
						}
					},
					style: {name: 'helptip', classes: {tooltip: 'qtip helptip'}, width: 400},
					position: {
						target: parent, 
						adjust:{y:0,x:0},
						corner: {target: 'bottomRight',tooltip: 'leftMiddle'}
					},
					api: {
						onHide: function() {parent.trigger('click');}
					},
					show: {
						delay: '0',
						when: {target: parent, event: 'click'},
						effect: largetipShowEffect,
						ready: true
					},
					hide:{
						fixed: true,
						when: 'unfocus',
						effect: largetipHideEffect
					}
				});
			},
			function() {
				$(this).qtip('destroy');
			}
		);
	});
	
	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,screen: true},
					corner: {target: 'bottomRight',tooltip: 'topLeft'}
				},
				style: 'largetip',
				show: {delay: 800}
			});
		}
		else{
			$(this).qtip({
				position: {
					target: 'mouse', 
					adjust:{y:5,x:3},
					corner: {target: 'bottomRight',tooltip: 'topLeft'}
				},
				style: 'smalltip'
			});
		}
	});
}
		
var createLoadingImage = function (container)
	{
	if (container.attr("id") == "container" || container.attr("id") == "resultsContainer" || container.is(":hidden") || container.closest(":hidden").length > 0)
		var cb = createCenterBox (null, 100, 0, "fixed", 100);
	else
		var cb = createCenterBox (container, 100, 0, "absolute", 100);
		
	cb.html("<img src='"+HTML_ROOT+"/images/ajax-loader3.gif' />");
	return cb;
	}
	
//image should be set to true if you want this function to create, display, and return the loading image object.	
var startLoadingEffect = function (container, image)
	{
	if (container.attr("id") !== "examArea")
		$("body").attr("id","waiting");
	if (image == true)
		{
		var imageObj = createLoadingImage (container);
		return imageObj;
		}
	else
		return false;
	}
	
//image should be set to the image object returned by startLoadingEffect.	
var endLoadingEffect = function (container, image)
	{
	if (container.attr("id") !== "examArea")
		$("body").attr("id","");
	if (image.length > 0)
		image.remove();
	}
	
/*These functions should be combined more so that you only have one basicAjax function that actually uses the $.ajax function, and everything else goes off that.*/			
var basicAjax = function (url, strData, callback)
	{
	$.ajax
		({
		url: url,
		type: "POST",
		data: strData,
		dataType: "html",
		success: function()
			{
			if ($.isFunction(callback))
				callback();
			}
		});
	}
	
var basicAjaxLoad = function (container, url, strData, callback, selector, loadingImage)
	{
	//var image = createLoadingImage (container);
	var image = startLoadingEffect (container, loadingImage);
	
	$.ajax
		({
		url: url,
		type: "POST",
		data: strData,
		dataType: "html",
		dataType: "html",
		success: function(data)
			{
			if (!selector || selector == null || selector == "")
				var html = data;
			else
				var html = $(data).filter(selector);
				
			container.html(html);
			if ($.isFunction(callback))
				callback();
			bindGeneralBehaviors(container);
			endLoadingEffect (container, image);
			}
		});
	}
	
var appendLoad = function (container, url, strData, callback, selector, loadingImage)
	{
	var image = startLoadingEffect (container, loadingImage);
	$.ajax
		({
		url: url,
		type: "POST",
		data: strData,
		dataType: "html",
		success: function(data)
			{
			if (!selector || selector == null || selector == "")
				var html = data;
			else
				var html = $(data).filter(selector);
				
			container.append(html);
			if ($.isFunction(callback))
				callback();
			bindGeneralBehaviors(container);
			endLoadingEffect (container, image);
			}
		});
	}
			
var fadeInLoad = function (container, url, strData, callback, selector, loadingImage)
	{
	var image = startLoadingEffect (container, loadingImage);
	var speed = "normal";
	container.fadeOut(speed, 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
			({
			url: url,
			type: "POST",
			data: strData,
			dataType: "html",
			success: function(data)
				{
				if (!selector || selector == null || selector == "")
					var html = data;
				else
					var html = $(data).filter(selector);
				
				container.html(html).fadeIn(speed);
				if ($.isFunction(callback))
					callback();
				bindGeneralBehaviors(container);
				endLoadingEffect (container, image);
				}
			});
		});
	}
	
//If the normal fadeInLoad is used, when the element reaches an opacity of 0, it is hidden, and so has no height or width, causing the screen to jump for a split second before it fades back in. This solves the problem by never letting it reach an opacity of 0.
var fadeInLoadNoJump = function (container, url, strData, customcallback, selector, loadingImage)
	{
	var speed = 600;
	if (container.is(":hidden"))//In case the container is hidden. Without this, the function never makes the container visible.
		container.empty().show();
	container.fadeTo(speed, 0.001, function()
		{
		var callback = 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);
					}
				}
			container.fadeTo(speed, 1, function() 
				{
				if ($.isFunction(customcallback))
					customcallback();
				});
			}
		basicAjaxLoad (container, url, strData, callback, selector, loadingImage);
		});
	}
	
var slideLoad = function (container, url, strData, customcallback, callbackAfterSlide, selector, loadingImage)
	{
	var speed = "normal";
	var callback = function ()
		{
		container.slideDown(speed, function() 
			{
			if ($.isFunction(callbackAfterSlide))
				callbackAfterSlide();
			});
		if ($.isFunction(customcallback))
			customcallback();
		}
	basicAjaxLoad (container, url, strData, callback, selector, loadingImage);
	}
	
//This could get a lot more complicated, with optional callbacks on each slide, but this should be good for now. 
var slideLoadToggle = function (trigger, container, url, strData, callback, selector, loadingImage)
	{
	var image = startLoadingEffect (container, loadingImage);
	var speed = 700;
	$.ajax
		({
		url: url,
		type: "POST",
		data: strData,
		dataType: "html",
		success: function(data)
			{
			if (!selector || selector == null || selector == "")
				var html = data;
			else
				var html = $(data).filter(selector);	
			
			container.html(html).slideDown(speed);
			trigger.slideUp(speed);
			if ($.isFunction(callback))
				callback();
			bindGeneralBehaviors(container);
			endLoadingEffect (container, image);
			}
		});
	}
	
//loads new page into the container div.	
var loadNewContent = function (page, data, customCallback, selector)
	{
	$(".qtip").each(function(){
		var api = $(this).qtip("api");
		api.destroy();
		});
	if ($(".centerBox").length > 0) {
		$(".centerBox").fadeOut("normal", function(){$(this).remove();});
	}
	var container = $("div#container");
	var callback = function ()
		{
		bindContentBehaviors();
		if ($.isFunction(customCallback))
			customCallback();
		}
	basicAjaxLoad (container, page, data, callback, selector);
	}
	
	
	
					//--------------------UTILITY FUNCTIONS--------------------//
					
/*-----Tooltip Generic Functions-----*/

//custom style; last part is the name of the style
$.fn.qtip.styles.smalltip = 
	{
	border: {color: 'rgb(51,51,153)', width: 1, radius: 1},
	background: 'rgb(230, 230, 246)',
	paddingTop: 1,
	paddingBottom: 1,
	paddingLeft: 6,
	paddingRight: 6,
	fontSize: 'small'
	}
	
$.fn.qtip.styles.largetip = 
	{
	width: {max: 400},
	border: {color: 'rgb(51,51,153)', width: '2'},
	background: 'rgb(220, 220, 245)',
	title: 
		{
		background: 'rgb(170, 170, 228)',
		margin: '0px',
		color: 'rgb(0,0,102)',
		fontSize: 'large'
		}
	}
	
$.fn.qtip.styles.modifytip = 
	{
	border: {color: 'rgb(51,51,153)', width: 2, radius: 9},
	background: 'rgb(51,51,153)',
	fontSize: 'small',
	color: 'rgb(240, 240, 251)',
	paddingTop: 0,
	paddingBottom: 0,
	paddingLeft: 0,
	paddingRight: 0
	}
	
$.fn.qtip.styles.helptip =
	{
	name: 'largetip'
	}	
	
$.fn.qtip.styles.helpbox =
	{
	name: 'largetip'
	}
	
var largetipHideEffect = {
	type: 'fade',
	length: '1'
	}

var largetipShowEffect = {
	type: 'fade',
	length: '1'
	}
	
var helpboxHideEffect = {
	type: 'fade',
	length: '300'
	}

var helpboxShowEffect = {
	type: 'fade',
	length: '300'
	}
	
var modifytipShowEffect = {
	type: 'fade',
	length: '300'
}

var modifytipHideEffect = {
	type: 'fade',
	length: '300'
}
	
//data should be an object
var helpbox = function (page, data, callback, title, container)
	{
	if (title == undefined || title == null || title == "")
		title = "NBGE Help";
	
	position = "absolute";	
		
	if (container == undefined || container == null || container == "")
		container = null;
		
		
	var centerBox = createCenterBox(container, 600, null, position);
	centerBox.qtip
		({
		content: 
			{
			text: "Loading...",
			data: data,
			url: HTML_ROOT + "/includes/helpboxes/" + page,
			title: 
				{
				text: "<span class='large'>"+title+"</span>",
				button: "X"
				}
			},
		api: 
			{
			onHide: function()
				{
				centerBox.qtip('destroy');
				centerBox.remove();
				}
			},
		style: {name: 'largetip', classes: {tooltip: 'qtip helpBox'}, width: 600},
		position:
			{
			type: position,
			corner: 
				{
				target: 'topLeft',
				tooltip: 'topLeft'
				},
			scroll: false
			},
		show: 
			{
			solo: false,
			when: false,
			ready: true,
			effect: helpboxShowEffect
			},
		hide:
			{
			when: false,
			effect: helpboxHideEffect
			}
		});
	}
	
//info should include target, url, dataObj, title, callback (which can take tooltip as its operator), tooltipClass, and position.
var getLargeTip = function (info) {
	if (info.text == null || info.text == undefined || info.text == "") {
		info.text = "Loading...";
	}
	info.target.qtip ({
		content: {
			text: info.text,
			url: info.url,
			data: info.dataObj,
			title: {
				text: "<span class='large'>"+info.title+"</span>",
				button: "X"
			}
		},
		api: {
			onContentUpdate: function() {
				var api = info.target.qtip("api");
				var tooltip = api.elements.tooltip;
				if ($.isFunction(info.callback))
					info.callback(tooltip);
			},
			onHide: function() {
				info.target.qtip('destroy');
				if (info.target.is(".centerBox"))
					info.target.remove();
			}
		},
		style: {name: 'largetip', classes: {tooltip: info.tooltipClass}, width: 500},
		position: info.position,
		show: {
			solo: true,
			when: false,
			ready: true,
			effect: largetipShowEffect
		},
		hide:{
			when: false,
			effect: largetipHideEffect
		}
	});
}

/*-----Other-----*/

var getHighestWidth = function (elements)
	{
	var highestWidth = 0;
	elements.each(function()
		{
		var width = $(this).width();
		highestWidth = Math.max(highestWidth,width);
		});
	return highestWidth;
	}
	
//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 (offset == undefined || offset == null || offset == "")
		offset = new Object();
	if (offset.top == undefined || offset.top == null || offset.top == "")
		offset.top = 0;
	if (offset.left == undefined || offset.left == null || offset.left == "")
		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);
		}
	
	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 !== null && height !== undefined && height !== "") {
		cb.top = (con.position.top + container.height()/2 + offset.top) - height/2;
	}
	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", "z-index": "6000"})
		.appendTo("#content");
		
	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;
	}
	
var showHideSwitch = function (showHideElement)
	{
	var strHtml = showHideElement.html();
	if (strHtml.match("Show") == "Show")
		var newStrHtml = strHtml.replace("Show","Hide");
	else if (strHtml.match("show") == "show")
		var newStrHtml = strHtml.replace("show","hide");
	else if (strHtml.match("Hide") == "Hide")
		var newStrHtml = strHtml.replace("Hide","Show");
	else if (strHtml.match("hide") == "hide")
		var newStrHtml = strHtml.replace("hide","show");

	showHideElement.html(newStrHtml);
	}
	
var fadeNoJump = function (container, callback)
	{
	container.fadeTo("normal",0.001, function()
		{
		if ($.isFunction(callback))
			callback();
		container.fadeTo("normal",1);
		});
	}
	
var htmlReplaceFadeNoJump = function (container, newHtml, callback)
	{
	container.fadeTo("normal", 0.001, function()
		{
		container.html(newHtml).fadeTo("normal", 1, function()
			{
			if ($.isFunction(callback))
				callback();
			});
		});
	}	

var layoutFourtoThree = function (speed)
	{
	if (!speed > 0)
		speed = 500;
	$("#content > .div2").css
		({
		width: "584px",
		marginLeft: "140px",
		marginRight: "140px",
		paddingRight: "0px"
		})
	.animate
		({
		width: "281px",
		marginLeft: "0%",
		marginRight: "0%",
		paddingRight: "21px"
		},speed, "linear", function()
			{
			$("#content").removeClass("layoutFour").addClass("layoutThree").children(".div3").fadeIn("slow");
			}
		);
	}
	
var layoutThreetoFour = function (speed)
	{
	if (!speed > 0)
		speed = 500;
	$("#content > .div2").css
		({
		width: "281px",
		marginLeft: "0%",
		marginRight: "0%",
		paddingRight: "21px"
		})
	.animate
		({
		width: "584px",
		marginLeft: "140px",
		marginRight: "140px"
		},speed, "linear", function()
			{
			$("#content").removeClass("layoutThree").addClass("layoutFour").children(".div3").hide();
			}
		);
	}
	
// 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 + ".");
			//otherwise, add a dot
			else
				loadingContainer.append(".");
			}
		});
	}
	
var loadingMessageStop = function (loadingContainer)
	{
	$(document).stopTime('loadingMessage');
	loadingContainer.html("");
	}
	
	
//These are any universal functions we want run every page.	
var bindContentBehaviors = function ()
	{
	/*
	//There can be a second function called onmouseout, but its not needed.
	$("#content").children("div").hover(
		function () {$(this).fadeTo(300, 1).siblings().fadeTo(300, 0.8);}
		);*/
		
	}
	
/*--------------------SPECIFIC PAGES--------------------*/
//Use this function if slideDown is giving you that jumping problem because of improperly calculated height. This was pulled from here: http://blog.pengoworks.com/index.cfm/2009/4/21/Fixing-jQuerys-slideDown-effect-ie-Jumpy-Animation
function slideToggle(el, bShow){
  var el, height = el.data("originalHeight"), visible = el.is(":visible");
  
  // if the bShow isn't present, get the current visibility and reverse it
  if( arguments.length == 1 ) bShow = !visible;
  
  // if the current visiblilty is the same as the requested state, cancel
  if( bShow == visible ) return false;
  
  // get the original height
  if( !height ){
    // get original height
    height = el.show().height();
    // update the height
    el.data("originalHeight", height);
    // if the element was hidden, hide it again
    if( !visible ) el.hide().css({height: 0});
  }

  // expand the knowledge (instead of slideDown/Up, use custom animation which applies fix)
  if( bShow ){
    el.show().animate({height: height}, {duration: 400});
  } else {
    el.animate({height: 0}, {duration: 400, complete:function (){
        el.hide();
      }
    });
  }
}


/*----------ACCOUNT----------*/

/*-----Passage Editor-----*/
$(".choosePassageForm .createPassage").livequery("click",function() {
	loadEditPassage ($(this),0);
});

$(".choosePassageForm .editPassage").livequery("click",function() {
	var selected = $(this).parents("form").find("select[name='passage'] option:selected");
	if (selected.length == 1) {
		var passageid = selected.val();
	}
	if (parseInt(passageid) > 0) {
		loadEditPassage ($(this),passageid);
	}
});

$(".choosePassageForm .viewPassage").livequery("click",function() {
	var selected = $(this).parents("form").find("select[name='passage'] option:selected");
	if (selected.length == 1) {
		var passageid = selected.val();
	}
	if (parseInt(passageid) > 0) {
		loadViewPassage ($(this),passageid);
	}
});

$(".choosePassageForm .deletePassage").livequery("click",function() {
	var selected = $(this).parents("form").find("select[name='passage'] option:selected");
	if (selected.length > 0) {
		$(this).fadeOut("normal",function(){$(this).siblings(".deletePassageConfirm").fadeIn("normal");});
	}
});

$(".choosePassageForm .deletePassageLoad").livequery("click",function() {
	var selected = $(this).parents("form").find("select[name='passage'] option:selected");
	if (selected.length > 0) {
		var passageids = "";
		selected.each(function() {
			if (passageids.length > 0) {
				passageids += ",";
			}
			passageids += $(this).val();
		});
		$(this).parents(".deletePassageConfirm").fadeOut("normal",function(){$(this).siblings(".deletePassage").fadeIn("normal");});
		loadDeletePassage ($(this),passageids);
	}
});

$(".choosePassageForm .deletePassageCancel").livequery("click",function() {
	$(this).parents(".deletePassageConfirm").fadeOut("normal",function(){$(this).siblings(".deletePassage").fadeIn("normal");});
});

var loadEditPassage = function (clicked, passageid) {
	var container = clicked.parents("form").find(".passageText");
	var url = HTML_ROOT + "/includes/htmlBlocks/editPassage.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageid=" + passageid;
	var callback = function () {
		clicked.parents(".choosePassageForm").find("input[name='lastPassageLoaded']").val(passageid);
	}
	basicAjaxLoad(container, url, data, callback);
}

var loadViewPassage = function (clicked, passageid) {
	var container = clicked.parents("form").find(".passageText");
	var url = HTML_ROOT + "/includes/htmlBlocks/viewPassage.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageid=" + passageid;
	var callback = function () {
		clicked.parents(".choosePassageForm").find("input[name='lastPassageLoaded']").val(passageid);
	}
	basicAjaxLoad(container, url, data, callback);
}

var loadDeletePassage = function (clicked, passageids) {
	var choosePassageForm = clicked.parents("form.choosePassageForm");
	var container = choosePassageForm.find("select[name='passage']");
	var url = HTML_ROOT + "/includes/htmlBlocks/deletePassage.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageids=" + passageids;
	var callback = function () {
		var lastPassageLoaded = choosePassageForm.find("input[name='lastPassageLoaded']").val();
		if (passageids.match(lastPassageLoaded) == lastPassageLoaded) {
			choosePassageForm.find(".passageText").html("");
		}
	}
	basicAjaxLoad(container, url, data, callback);
}

$(".editPassageSubmit").livequery("click",function() {
	var clicked = $(this);
	var qtip = $(this).parents(".qtipPassageEditor");
	var editPassageForm = clicked.parents("form.editPassageForm");
	var container = clicked.parents("form.choosePassageForm").find("select[name='passage']");
	var url = HTML_ROOT + "/includes/htmlBlocks/updatePassage.php";
	var passagesSelected = "";
	if (!blankCheck(editPassageForm.find("textarea,input:not(:hidden,.submit)"))) {
		qtip.find("select[name='passage'] option:selected").each(function() {
			if (passagesSelected.length > 0) {
				passagesSelected += ",";
			}
			passagesSelected += $(this).val();
		});
		var passageid = editPassageForm.find("input[name='passageid']").val();
		var data = editPassageForm.serialize() + "&" + qtip.find(".passageInfoForm").serialize() + "&passages=" + passagesSelected;
		var callback = function () {
			if (passageid == "new") {//if this is a new passage, first, check if there are multiple passages selected. If not, view the single selected. if not, view the one that wasn't selected before.
				newSelected = qtip.find("select[name='passage'] option:selected");
				if (newSelected.length == 1) {
					passageid = newSelected.val();
				}
				else {
					newSelected.each(function() {
						var val = $(this).val();
						if (passagesSelected.match(val) == null) {
							passageid = val;
							return false;
						}
					});
				}
			}
			loadViewPassage (qtip.find(".viewPassage"),passageid);
		};
		basicAjaxLoad(container, url, data, callback);
	}
});

$(".editPassageCancel").livequery("click",function() {
	$(this).parents(".choosePassageForm").find(".viewPassage").trigger('click');
});

$(".question .choosePassageSubmit").livequery("click", function() {
	var clicked = $(this);
	var choosePassageForm = clicked.parents(".choosePassageForm");
	var questionid = clicked.parents(".qtipPassageEditor").find("input[name='questionid']").val();
	var passageid = choosePassageForm.find("select[name='passage']").val();
	if (questionid == "new") {
		container = $(".createQuestion .passageName");
	}
	else {
		container = $("#question" + questionid + " .passageName");
	}
	var url = HTML_ROOT + "/includes/htmlBlocks/updateQuestionPassage.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageid=" + passageid;
	var callback = function() {
		
	}
	
	fadeInLoadNoJump (container, url, data, callback);
	container.parents(".passage").siblings("h4").qtip('hide');
});

$(".category .choosePassageSubmit").livequery("click", function() {
	var clicked = $(this);
	var qtip = clicked.parents(".qtipPassageEditor");
	var api = qtip.qtip("api");
	var choosePassageForm = clicked.parents(".choosePassageForm");
	var selected = choosePassageForm.find("select[name='passage'] option:selected");
	var passageids = "";
	if (selected.length > 0) {
		if (selected.filter("[value='none']").size() == 1) {
			passageids = "none";
		}
		else if (selected.filter("[value='any']").size() == 1) {
			passageids = "any";
		}
		else {
			selected.each(function() {
				if (passageids.length > 0) {
					passageids += ",";
				}
				passageids += $(this).val();
			});
		}
	}
	else {
		passageids = "none";
	}
	var container = api.elements.target.parents(".category").find(".passagelist");
	var url = HTML_ROOT + "/includes/htmlBlocks/updateCategoryPassages.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageids=" + passageids;
	var callback = function() {
		
	}
	
	fadeInLoadNoJump (container, url, data, callback);
	api.elements.target.qtip('hide');
});

$(".filter .choosePassageSubmit").livequery("click", function() {
	var clicked = $(this);
	var qtip = clicked.parents(".qtipPassageEditor");
	var api = qtip.qtip("api");
	var choosePassageForm = clicked.parents(".choosePassageForm");
	var selected = choosePassageForm.find("select[name='passage'] option:selected");
	var passageids = "";
	if (selected.length > 0) {
		if (selected.filter("[value='none']").size() == 1) {
			passageids = "none";
		}
		else if (selected.filter("[value='any']").size() == 1) {
			passageids = "any";
		}
		else {
			selected.each(function() {
				if (passageids.length > 0) {
					passageids += ",";
				}
				passageids += $(this).val();
			});
		}
	}
	else {
		passageids = "none";
	}
	var container = api.elements.target.parents("form").find("#passagelist");
	var url = HTML_ROOT + "/includes/htmlBlocks/updateFilterPassages.php";
	var data = clicked.parents(".qtipPassageEditor").find(".passageInfoForm").serialize() + "&passageids=" + passageids;
	var callback = function() {
		
	}
	
	fadeInLoadNoJump (container, url, data, callback);
	api.elements.target.qtip('hide');
});

$("#questionArea .viewPassage").livequery("click",function() {
	var clicked = $(this);
	if (clicked.text().match("show") == "show") {
		var passageText = clicked.parents(".passageName").find("input[name='passage']").val();
		clicked.qtip({
			content: {
				text: "<p>"+passageText+"</p>"
			},
			style: {name: 'largetip', classes: {tooltip: "qtipViewPassage"}, width: 500},
			position: {
				adjust: {screen: false,scroll: false,x:300,y:-350},
				corner: {target: 'topMiddle',tooltip: 'topMiddle'}
			},
			api: {
				onHide: function() {clicked.qtip('destroy');}
			},
			show: {
				solo: true,
				when: false,
				ready: true,
				effect: largetipShowEffect
			},
			hide:{
				when: 'unfocus',
				effect: largetipHideEffect
			}
		});
	}
	else {
		clicked.qtip('hide');
	}
	showHideSwitch(clicked);
});



/*-----Instructor Questions-----*/

$(".tagTree .showList").live("click",function() {
	$(this).toggleClass("right_arrow_list").toggleClass("down_arrow_list").parents("li").find("ul.subtaglist").slideToggle();
});

$(".tagTree .maintag, .tagTree .subtag").live("click", function() {
	var questionids = ","+$(this).find("input[name='questionids']").val()+",";
	var questions = $("#questionArea .questionInfo");
	questions.each(function() {
		var questionid = $(this).attr("id").replace("question","");
		if (questionids.match(","+questionid+",") == null) {
			$(this).slideUp("normal");
		}
		else {
			$(this).slideDown("normal");
		}
	});
});

$(".tagTree .showAll").live("click",function() {
	$("#questionArea .questionInfo").slideDown("normal");
});



/*-----Instructor Exams-----*/

$("#editExamContainer .checkQuestionCount").live("click",function() {
	var container = $(this).parents(".category").find(".questionsAvailable");
	var url = HTML_ROOT + "/includes/htmlBlocks/getQuestionCount.php";
	var key = $(this).parents(".category").find("input[name*='categoryName']").attr("name").replace("categoryName[","").replace("]","");
	var data = $(this).parents("form").serialize()+"&simpleCheck=true&key="+key;
	fadeInLoad (container, url, data);
});

$("#editExamContainer .taggerload").live("click",function(){
	var taginput = $(this).parents(".category").find(".taglist input[name*='tags']");
	var prevTags = taginput.val();
	var categorykey = taginput.attr("name").replace("tags[","").replace("]","");
	var categoryid = $(this).parents(".category").find("input[name*='examCategoryid']").val();
	dataObj = {"tagType":"category","prevTags":prevTags,"categorykey":categorykey,"categoryid":categoryid};
	loadCategoryTagging ($(this),dataObj);
});

/*-----Results (both instructor and student)-----*/

$("#resultsContainer .toggleInfo, .studentResultDetails .toggleInfo").live("click", function() {
	var clicked = $(this);
	clicked.closest("li").children("ul").slideToggle("normal",function(){showHideSwitch(clicked);});
});
	
$(".additionalStats .showNext").live("click", function() {
	var clicked = $(this);
	clicked.closest("li").children("ul").find("li:hidden:first").slideDown("normal");
});

var toggleAllTagStats = function() {
	$(this).toggle(function(e){
		var clicked = $(this);
		var x = 0;
		clicked.closest("li").children("ul").find("li").slideDown("normal",function(){
			x++;
			if (x == clicked.closest("li").children("ul").find("li").length)
				showHideSwitch(clicked);
		});
	},
	function(e){
		var clicked = $(this);
		var x = 0;
		clicked.closest("li").children("ul").find("li").slideUp("normal",function(){
			x++;
			if (x == clicked.closest("li").children("ul").find("li").length)
				showHideSwitch(clicked);
		});
	});
}
	
$(".additionalStats .toggleAll").expire(toggleAllTagStats).livequery(toggleAllTagStats);



/*-----Instructor Results-----*/

$(".modifyClassRank").live("click",function() {
	$(this).parents(".classRankContainer").find(".classRankOptions").slideToggle();
});

$(".classRankForm").livequery("submit",function() {
	var classRank = $(this).parents(".classRankContainer").find(".classRank");
	var url = HTML_ROOT + "/includes/htmlBlocks/getClassRank.php";
	var data = $(this).serialize();
	basicAjaxLoad (classRank, url, data);
});



/*----------ABOUT/NON-ACCOUNT----------*/

/*----------ADMIN----------*/
/*homepage.php*/
$("#grantIndividualPass").livequery("submit",function(){
	if (!blankCheck($(this).find("select, input"))) {
		var container = $(this).find(".result");
		var url = HTML_ROOT + "/includes/htmlBlocks/grantExamPass.php";
		var data = $(this).serialize();
		basicAjaxLoad (container, url, data);
	}
});

$("#grantClassPass").livequery("submit",function(){
	if (!blankCheck($(this).find("select, input"))) {
		var url = HTML_ROOT + "/includes/htmlBlocks/getQtipClassList.php";
		var email = $(this).find("input#instructorEmail").val();
		var dataObj = {email: email, course_members: "true"};
		loadClassList ($(this), dataObj);
	}
});

$("#loginAsUser").livequery("submit",function(e){
	if (blankCheck($(this).find("select, input"))) {
		e.preventDefault();
	}
});

/*getQtipClassList.php*/
$(".grantPassClassListForm").livequery("submit",function() {
	var studentids = "";
	$(this).find("input:checked").each(function() {
		studentids = studentids + "," + $(this).attr("name");
	});
	var passType = $(this).find("select[name='passType'] option:selected").val();
	var container = $(this).find(".error");
	var url = HTML_ROOT + "/includes/htmlBlocks/grantExamPass.php";
	var data = "studentids=" + studentids + "&passType=" + passType + "&examid=1";
	basicAjaxLoad (container, url, data);
});

$(".grantPassClassListForm .h4").livequery("click", function () {
	$(this).next().slideToggle();
});

/*----------FAQ----------*/
$("#faqList dt").livequery("click",function(){
	slideToggle($(this).next());
});

/*----------EXAM----------*/
/*-----pre-exam.php-----*/
$(".showProctorTerms").livequery("click",function(){
	getLargeTip ({
		target: $(this),
		position: {
			adjust: {screen: true,scroll: false},
			corner: {target: 'rightMiddle',tooltip: 'leftMiddle'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipProctorTerms.php",
		container: $(this),
		callback: function(tooltip) {
		},
		title: "Proctor Terms",
		tooltipClass: "qtipProctorTerms"
	});
});

$(".showExamineeTerms").livequery("click",function(){
	getLargeTip ({
		target: $(this),
		position: {
			adjust: {screen: true,scroll: false},
			corner: {target: 'rightMiddle',tooltip: 'leftBottom'}
		},
		url: HTML_ROOT + "/includes/htmlBlocks/getQtipExamineeTerms.php",
		container: $(this),
		callback: function(tooltip) {
		},
		title: "Examinee Terms",
		tooltipClass: "qtipExamineeTerms"
	});
});


/*----------HELPBOXES----------*/
/*-----unfinishedExam.php-----*/
$("#finishExamForm").livequery("submit",function() {
	var url = HTML_ROOT+"/exam/exam.php";
	var data = $(this).serialize();
	loadNewContent(url, data);
});

$("#finishExamForm .closetip").livequery("click",function() {
	api = $(this).parents(".qtip").qtip("api");
	api.destroy();
});

/*-----getQtipClassOptions.php-----*/
$(".toggleClassOption").livequery("click",function() {
	var url = HTML_ROOT+"/includes/htmlBlocks/toggleClassOption.php";
	var data = $(this).children(".hiddenInfo").serialize() + "&" + $(this).closest(".classOptions").children(".hiddenInfo").serialize();
	basicAjaxLoad($(this),url, data);
});	
	
$(document).ready(function()
	{
	//bindContentBehaviors();
	bindGeneralBehaviors($(document));
	
	$("#infopagelist span.clickText").live("click",function()
		{
		var section = $("." + $(this).attr("id"));
		$(".infocontents div").not(section).hide();
		section.show();
		});
		
	$(".signupload").live("click",function()
		{
		$("#tabs a[id*='signup']").trigger("click");
		});
	});