$jsq = jQuery.noConflict();	// Make sure our implementation doesn't conflict with anyone elses

var popHelpT;
var overPopHelp;
var gpLinkHover = 0; 		// Tells us that we're hovering over the Geek Professor Link area
var gpLinkInterval = null;
var onJsearchPage = 0;		// This will be set to 0 by default, but will be overrided later by the Jsearch template IF we're on the right page

function styleJsearchButtons()
{
	// Add the "button off" style to all buttons in the jsearch area
	$jsq(".jsearch_area input[type=button]").addClass("jsearch_button");
	// Hover effect for jsearch area buttons
	$jsq(".jsearch_area input[type=button]").hover(
		function () {
			$jsq(this).addClass("jsearch_button_hover");
		}, 
		function () {
			$jsq(this).removeClass("jsearch_button_hover");
		}
	);		

}

$jsq(document).ready(function() {

	// Set the functions for the search button on the sidebar
	$jsq("#jsearch_sb_terms").keyup(
		function (event) {
			$jsq(this).val(jsearchSanitize($jsq(this).val()));
		}
	);
	$jsq("#jsearch_sb_terms").keydown(
		function (event) {
			if (event.keyCode == 13) {
				jsearchSbSearch();
			}
		}
	);
	$jsq("#jsearch_sb_button").click(jsearchSbSearch);				// When they click the sidebar "Search" button, start the search

	if (onJsearchPage)	// Only when we're on the actual page (otherwise many of these commands will fail)
	{
		$jsq(".jsearch_nav_button").click(
			function() {
				var onIndex = $jsq(".jsearch_nav_button").index(this);
				
				$jsq.each(
					$jsq(".jsearch_nav_button"),
					function() {
						var index = $jsq(".jsearch_nav_button").index(this);
						var areaID = this.id.replace("title","area");
						if (index != onIndex)		// This isn't the one that was clicked
						{
							// Turn off the button
							$jsq("#"+this.id).removeClass("jsearch_nav_button_on");
							$jsq("#"+this.id).addClass("jsearch_nav_button_off");
							
							// Turn off the matching area
							$jsq("#"+areaID).hide();
						}
						else
						{
							$jsq("#"+this.id).removeClass("jsearch_nav_button_hover");
							$jsq("#"+this.id).removeClass("jsearch_nav_button_off");
							$jsq("#"+this.id).addClass("jsearch_nav_button_on");
							$jsq("#"+areaID).show();
						}
					}
				);
			}
		);

		$jsq(".jsearch_nav_button").hover(
			function () {
				if (!$jsq(this).hasClass("jsearch_nav_button_on"))		// Only hover if this button isn't active (white and indented)
				{
					$jsq(this).addClass("jsearch_button_hover");
				}
			},
			function () {
				$jsq(this).removeClass("jsearch_button_hover");
			}
		);
	
		styleJsearchButtons();
	
		// Keyword entry stuff
		$jsq("#jsearch_terms_input").keyup(
			function (event) {
				$jsq(this).val(jsearchSanitize($jsq(this).val()));
			}
		);
		$jsq("#jsearch_terms_input").keydown(
			function (event) {
				if (event.keyCode == 13) {
					jsearchAddTerms('any');
				}
			}
		);
		
		jsearchUpdateCatBox();		// Load the category box with any categories found
		jsearchSetCatParentBox();	// Load the category parents drop-down
		jsearchUpdateTagBox();		// Load the category box with any categories found
		
		// If they click on any checkboxes or radio buttons inside the jsearch area, they changed a setting so update the results
		$jsq(".jsearch_area input[type=radio]").click(jsearchCallAJAX);
		$jsq(".jsearch_area input[type=checkbox]").click(jsearchCallAJAX);
		$jsq("#jsearch_ppp").change(jsearchCallAJAX);
		$jsq("#jsearch_result_type").change(jsearchCallAJAX);
		$jsq("#jsearch_results_type").change(function() {
			// Retarget the AJAX url
			jsearchAJAXURL = jsearchPluginUrl + "jsearch_" +$jsq("#jsearch_results_type").val() + ".php";
			// And refresh the results with the new value.
			jsearchCallAJAX($jsq('#paged_holder').val());	// Preserve the page because this won't cause a change in the query, just the view
		});
	
		// Make sure to update the english translation in case there are any selected values
		// This is the only time we'll pass a paged value (on first page load)
		jsearchUpdateEnglish(paged);

		// Set the buttons that show and hide the english to actually DO that
		$jsq('#eng_on,#eng_off').unbind('click');				// Over-ride the click function above that would have updated the ajax (we don't want that for this).
		$jsq("#eng_on").click(function() {				// Hide the english 
			$jsq("#jsearch_english").show();
		});
		$jsq("#eng_off").click(function() {				
			$jsq("#jsearch_english").hide();
		});
		// Now make sure the area is open or closed based on how the radio buttons are set
		if ($jsq("#eng_on").is(":checked"))
		{
			$jsq("#jsearch_english").show();
		}
		else
		{
			$jsq("#jsearch_english").hide();
		}
		// Set the english area	
	
		// Handle "minimize"/"maximize" issues
		$jsq("#jsearch_control_min").click(function () {jsearchControl('min')});	// This minimizes
		$jsq("#jsearch_control_max").click(function () {jsearchControl('max')});	// This maximizes
		jsearchControl(jsearchControlVis);				// Min or max it depending on the default
		
		// Everything's loaded, show this now (if it's not hidden)
		if (jsearchControlVis != "hide")
			$jsq("#jsearch_controls_hider").show();
	
		// Now that it's visible, set floaters
		jsearchGpAttach();
		$jsq("#jsearch_gp_link_anchor").hover( 
			function() {
				gpLinkHover = 1;						// We're hovering
				gpLinkAttach();
				$jsq("#jsearch_gp_link_area").fadeIn('fast');			// Show it
				gpLinkInterval = setInterval(function () {			// Set an interval to try and close it when the signal is raised
					if (!gpLinkHover)
					{
						$jsq("#jsearch_gp_link_area").fadeOut('fast');
						clearInterval(gpLinkInterval);
					}
				}, 500);				
			},
			function() {
			});
		$jsq("#jsearch_gp_link_area").hover( function() {}, function() { gpLinkHover = 0; });
	}
});


function jsearchControl(which)
{
	if (which == "min")
	{
		$jsq("#jsearch_control_table").hide();		// Hide the controls
		$jsq("#jsearch_english").hide();		// Hide the english area
		$jsq("#jsearch_minimized").show();		// Show the "minimized" message
		jsearchControlVis = 'min';
	}
	else
	{
		$jsq("#jsearch_control_table").show();		// Hide the controls
		$jsq("#jsearch_english").show();		// Hide the english area
		$jsq("#jsearch_minimized").hide();		// Show the "minimized" message	
		jsearchControlVis = 'max';
		jsearchGpAttach();				// Make sure the buttons are in the right place
	}
}

function jsearchGpAttach()
{
	$jsq("#jsearch_gp_icon_bk").css('left',($jsq("#jsearch_gp_anchor").width()-$jsq("#jsearch_gp_icon_bk").width()-1));
	$jsq("#jsearch_gp_icon_bk").css('top',"-171px");
	$jsq("#jsearch_gp_icon_area").css('left',($jsq("#jsearch_gp_anchor").width()-$jsq("#jsearch_gp_icon_bk").width()+7));
	$jsq("#jsearch_gp_icon_area").css('top',"-192px");
}

function gpLinkAttach()
{
	$jsq("#jsearch_gp_link_area").css('left',$jsq("#jsearch_gp_icon_bk").offset().left+$jsq("#jsearch_gp_icon_bk").width()-$jsq("#jsearch_gp_link_area").width());
	$jsq("#jsearch_gp_link_area").css('top',$jsq("#jsearch_gp_icon_bk").offset().top);
}

function jsearchSbSearch()
{	
	terms = jsearchTermSanitize($jsq("#jsearch_sb_terms").val());
	document.location.href = jsearchAddVars(jsearchTargetPage,"term_any="+terms);
}			


var termsPopOn = false;	// A variable for preventing the closure of our popup when we don't want it to be closed
var term_any = [];	// Holds the added terms
var term_all = [];	// Holds the added terms
var term_none = [];	// Holds the added terms
var auto_update = 0;	// Just need a default value here to prevent a page error


// Used to show a popup for diagnostics purposes
function jsearchPopHelp(caller,text)
{
	if (text.length==0) return;
	callerP = $jsq(caller).offset();
	$jsq("#jsearch_help_pop").css('top',callerP.top);
	$jsq("#jsearch_help_pop").css('left',callerP.left+$jsq(caller).width()+3);
	$jsq("#jsearch_help_pop").show();
	$jsq("#jsearch_help_pop").html(text);
}

// Turn off the popup
function jsearchPopHelpOff()
{
	$jsq('#jsearch_help_pop').hide();
}

// Test for enter key so we can submit even without a form by hitting the enter key
function jsearchIsEnter(e)
{
	if (window.event)
		ccode = e.keyCode
	else if (e.which)
		ccode = e.which
	if (ccode == 13)
		return true;
	else
		return false;
}

function jsearchIDsToNames(which,anyall)
{
	temp = "";
	first = "";
	eval("len = "+which+"_"+anyall+".length;\n");
	for (i=0;i<len;i++)				// Iterate through and create a comma separated list of cat names
	{
		eval("temp += first+"+which+"Names["+which+"_"+anyall+"[i]];\n");	
		if (!first.length)
			first = ", ";
	}
	return temp;
}


function jsearchMakeSentence(term_update,cat_update,tag_update,andor)
{
	to_update = "";
	if (term_update && cat_update && tag_update)
		to_update += term_update+", "+cat_update+", "+andor+tag_update;
	else if (term_update && cat_update)
		to_update += term_update+" "+andor+cat_update;
	else if (term_update && tag_update)
		to_update += term_update+" "+andor+tag_update;
	else if (cat_update && tag_update)
		to_update += cat_update+" "+andor+tag_update;
	else
		to_update += term_update+cat_update+tag_update;		// Since two of these are blank, only one will show
	return to_update+".</p>";
}

// The paged variable here is ONLY for preserving paged information on FIRST PAGE LOAD. It won't be used any other time
function jsearchUpdateEnglish(paged)
{
	found = 0;			// We don't want to print anything at all if there's nothing to say. This variable tracks that		
	to_update = "";			// Build a string to update all at once
	term_update = cat_update = tag_update = "";
	if (term_any.length || cat_any.length || tag_any.length)
	{
		to_update += "a result will have to  ";
		if (term_any.length) term_update = "have at least one of these keywords: <b>"+term_any+"</b>";
		if (cat_any.length) cat_update = "be in one of these categories: <b>"+jsearchIDsToNames("cat","any")+"</b>";
		if (tag_any.length) tag_update = "be tagged with any of these tags: <b>"+jsearchIDsToNames("tag","any")+"</b>";
		
		to_update += jsearchMakeSentence(term_update,cat_update,tag_update,"and ");	
		found = 1;		
	}
	if (term_all.length || cat_all.length || tag_all.length)
	{
		term_update = cat_update = tag_update = "";
		if (found)
			to_update += "<p>They will also ";
		else
			to_update += "a result will have to  ";
		if (term_all.length) term_update = "contain ALL of these keywords: <b>"+term_all+"</b>";
		if (cat_all.length) cat_update = "be filed in ALL of these categories: <b>"+jsearchIDsToNames("cat","all")+"</b>";
		if (tag_all.length) tag_update = "have ALL of these tags: <b>"+jsearchIDsToNames("tag","all")+"</b>";
		
		to_update += jsearchMakeSentence(term_update,cat_update,tag_update,"and ");	
		found = 1;		
	}
	if (term_none.length || cat_none.length || tag_none.length)
	{
		term_update = cat_update = tag_update = "";
		if (found)
			to_update += "<p>But, results CAN NOT ";
		else
			to_update += "a result CAN NOT  ";
		if (term_none.length) term_update = "have any these keywords: <b>"+term_none+"</b>";
		if (cat_none.length) cat_update = "be in any of these categories: <b>"+jsearchIDsToNames("cat","none")+"</b>";
		if (tag_none.length) tag_update = "be tagged with any of these tags: <b>"+jsearchIDsToNames("tag","none")+"</b>";
		
		to_update += jsearchMakeSentence(term_update,cat_update,tag_update,"or ");	
		found = 1;		
	}
	
	// Do the ENGLISH stuff
	var the_english = "";
	if (found)
	{
		the_english += "<table><tr>";
		the_english += "<td id=jsearch_english_title valign=top>In English:</td>";
		the_english += "<td><p>Based on how your search is currently configured " + to_update + "</td>";
		the_english += "</tr></table>";
	}
	$jsq("#jsearch_english").html(the_english);
	jsearchCallAJAX(paged);	// Since every single change calls this, update the search results here
}

// Uses the value of the variables that hold what's in each box and actually prints a term/cat/tag any/all/none box of values
function jsearchPrintBox(tct,aan)
{
	eval("holder = "+tct+"_"+aan);		// To simplify all further code, only run an eval statement once to set a temporary variable (holder) to the value of the array we're messing with
	temp = "";	// Build a string
	temp += "<table class='jsearch_aan_value_table'>";
	var for_count = holder.length;
	var toPrint = "";
	for (i=0; i < for_count; i++)
	{
		if (tct == "cat") toPrint = catNames[holder[i]];
		else if (tct == "tag") toPrint = tagNames[holder[i]];
		else toPrint = holder[i];
		temp += "<tr><td><img class='jsearch_aan_value_x' src='"+jsearchPluginUrl+"/jsearch_x.gif' onclick=\"jsearchKiller('"+tct+"','"+aan+"',"+i+")\" /></td><td><div class='jsearch_aan_value'>"+toPrint+"</div></td></tr>";
	}
	temp += "</table>";
	$jsq('#'+tct+'_'+aan+'_box').html(temp);
	if (tct == "cat") jsearchUpdateCatBox();			// Update the cat selection box
	if (tct == "tag") jsearchUpdateTagBox();			// Update the tag selection box
	jsearchUpdateEnglish();
}

// Finds the term/cat/tag any/all/none variable and gets rid of the [index] value
function jsearchKiller(tct,aan,index)
{
	eval(tct+"_"+aan+".splice("+index+",1);");
	jsearchPrintBox(tct,aan);
}


// Moves a term from the add box to one of the other three
function jsearchAddTerms(which)
{
	var getOut = false;	// Just used by evaled code to determine if we should abandon ship
	//************
	// If we've hit our max, stop adding!
	to_eval = "if (term_"+which+".length >= 10)"+
	"{ jsearchPopHelp($jsq('#term_"+which+"_button'),\"You've added the maximum number of terms for this field. Please delete existing ones before trying to add more\",1);"+
	" setTimeout(\"jsearchPopHelpOff();\",3000);"+
	" getOut = true; }";
	eval(to_eval);
	if (getOut)
		return;
	
	eval("holder = term_"+which);		// Set a variable to the appropriate array to simplify the following code
	temp = jsearchTermSanitize($jsq("#jsearch_terms_input").val());
	if (temp.length < 2)
		return;
	temp = '"'+temp.replace(/,/g,'","')+'"';
	eval("holder.unshift("+temp+");");  	// Puts the added value at the front of the appropriate array
	eval("term_"+which+" = holder;");	// Put the array value back
	jsearchPrintBox('term',which);
	$jsq("#jsearch_terms_input").val("");	// And clear the source box for more input.
}


//*************************
// Category functions
//*************************


var cat_any = [];	// Holds the added terms
var cat_all = [];	// Holds the added terms
var cat_none = [];	// Holds the added terms

//***********************
//  catBox[][0] = category id
//  catBox[][1] = category parent id
//  catBox[][2] = levels (1 for every parent above it)
//***********************


function jsearchUpdateCatBox()
{
	textFilter = $jsq('#jsearch_category_filter').val();
	var parent = getSelectedOption('jsearch_cat_parents_select');
	if (typeof(parent)=="undefined" || parent == -1)
		parent = "no";

	options = ""; 
	used = false;	// This variable will be set if the category has been used by one of the three option columns
	var indent = "";
	for_count = catBox.length;
	for (i=0; i < for_count; i++)
	{
		indent = "";
		dontPrint = false;
		// print an option with a value equal to an ID and the name equal to the name[id] array (which is the name);
		if (catBox[i][2])	// How many indentions to make? (how deeply nested is the subcat?
		{
			for_count2 = catBox[i][2];
			for (y=0; y < for_count2; y++)
				indent += "&nbsp;&nbsp;&nbsp;&nbsp;";
		}
				
		//*******
		// Check for any that are used and disable them in the main box
		//*******
		// For readability reasons... Also, had to convert them to strings. In some cases, the difference between int and string was making for false negatives
		foundAny = (cat_any.toString()).indexOf(catBox[i][0].toString());
		foundAll = (cat_all.toString()).indexOf(catBox[i][0].toString());
		foundNone = (cat_none.toString()).indexOf(catBox[i][0].toString());
		if (foundAny==-1 && foundAll==-1 && foundNone==-1)
		{
			used = "";
			value = catBox[i][0];
			disabled = "";
		}
		else
		{
			used = "category_used";
			disabled = " disabled='disabled' ";
			value = -1;			// Backup in case disabled doesn't work in this browser. The add cat function will dump if it sees this value
		}

		//*******
		// Check for parent filter. In this case, if it doesn't match the parent filter, don't show it at all
		//*******
		if (parent && parent != "no") 	// There's a parent filter active
			if (catBox[i][1] != parent)
				dontPrint = true;
				
		//*******
		// Now actually print it (if it matches the various filters (parent/text)
		//*******
		if (!dontPrint)	// This means that this isn't the right parent so don't print
		{
			// if the textFilter's not set or it is and the category includes the filter text, print the option
			if ((textFilter && catNames[catBox[i][0]].toLowerCase().indexOf(textFilter) != -1) || !textFilter)
				options += "<option value="+value+" "+disabled+" class='"+used+"' >"+indent+catNames[catBox[i][0]]+"</option>";
		}
	}
	$jsq('#jsearch_cat_dropbox').html(options);
}

function jsearchAddCats(which)
{
	var getOut = false;	// Just used by evaled code to determine if we should abandon ship
	//************
	// If we've hit our max, stop adding!
	to_eval = "if (cat_"+which+".length >= 10)"+
	"{ jsearchPopHelp($jsq('#cat_"+which+"_button'),\"You've added the maximum number of categories for this field. Please delete existing ones before trying to add more\",1);"+
	" setTimeout(\"jsearchPopHelpOff();\",2000);"+
	" getOut = true; }";
	eval(to_eval);
	if (getOut)
		return;
		
	eval("holder = cat_"+which);		// Set a variable to the appropriate array to simplify the code
	temp = document.getElementById('jsearch_cat_dropbox');
	for_count = temp.options.length;
	for (i=0; i < for_count; i++)
	{
		if (temp.options[i].selected && temp.options[i].value > -1)	// -1 is a special code set that means this particular option is disabled
			eval("holder.unshift("+temp.options[i].value+");");  	// Puts the added value at the front of the appropriate array
	}
	eval("cat_"+which+" = holder;");	// Put the array value back
	jsearchPrintBox('cat',which);
}


function jsearchSetCatParentBox()
{
	if (selectedCatParent == -1)
		options = "<option value=-1 selected>All</option>";
	else
		options = "<option value=-1>All</option>";
	var indent = "";
	for_count = catParents.length;
	for (i=0; i < for_count; i++)
	{
		theParent = catParents[i][0];
		indentions = catParents[i][2];

		if (indentions)	// How many indentions to make? (how deeply nested is the subcat?
		{
			for (y=0;y<indentions;y++)
				indent += "&nbsp;&nbsp;&nbsp;&nbsp;";
		}
		options += "<option value="+theParent+" ";

		if (selectedCatParent == theParent)	// If this is the one that's selected
			options += " selected ";
		options += ">"+catNames[theParent]+"</option>";
	}
	$jsq("#jsearch_cat_parents_select").html(options);
}


//*************************
// Tag functions
//*************************


var tag_any = [];	// Holds the added terms
var tag_all = [];	// Holds the added terms
var tag_none = [];	// Holds the added terms

//***********************
//  tagBox[][0] = tag id
//  tagBox[][1] = tag parent id
//  tagBox[][2] = levels (1 for every parent above it)
//***********************


function jsearchUpdateTagBox()
{
	textFilter = $jsq('#jsearch_tag_filter').val();
	options = ""; 
	used = false;	// This variable will be set if the tag has been used by one of the three option columns
	var indent = "";
	for_count = tagBox.length;
	for (i=0; i < for_count; i++)
	{
		//*******
		// Check for any that are used and disable them in the main box
		//*******
		// For readability reasons... Also, had to convert them to strings. In some cases, the difference between int and string was making for false negatives
		foundAny = (tag_any.toString()).indexOf(tagBox[i].toString());
		foundAll = (tag_all.toString()).indexOf(tagBox[i].toString());
		foundNone = (tag_none.toString()).indexOf(tagBox[i].toString());
		if (foundAny==-1 && foundAll==-1 && foundNone==-1)
		{
			used = false;
			value = tagBox[i];
		}
		else
		{
			used = true;
			value = -1;			// Backup in case disabled doesn't work in this browser. The add tag function will dump if it sees this value
		}


		//*******
		// Now actually print it (if it matches the various filters (parent/text)
		//*******
		if (!used)
		{
			// if the textFilter's not set or it is and the tag includes the filter text, print the option
			if ((textFilter && tagNames[tagBox[i]].toLowerCase().indexOf(textFilter) != -1) || !textFilter)
				options += "<option value="+value+">"+indent+tagNames[tagBox[i]]+"</option>";
		}
	}
	$jsq('#jsearch_tag_dropbox').html(options);
}

function jsearchAddTags(which)
{
	var getOut = false;	// Just used by evaled code to determine if we should abandon ship
	//************
	// If we've hit our max, stop adding!
	to_eval = "if (tag_"+which+".length >= 10)"+
	"{ jsearchPopHelp($jsq('#tag_"+which+"_button'),\"You've added the maximum number of tags for this field. Please delete existing ones before trying to add more\",1);"+
	" setTimeout(\"jsearchPopHelpOff();\",2000);"+
	" getOut = true; }";
	eval(to_eval);
	if (getOut)
		return;
		
	eval("holder = tag_"+which);		// Set a variable to the appropriate array to simplify the code
	temp = document.getElementById('jsearch_tag_dropbox');
	for_count = temp.options.length;
	for (i=0; i < for_count; i++)
	{
		if (temp.options[i].selected && temp.options[i].value > -1)	// -1 is a special code set that means this particular option is disabled
			eval("holder.unshift("+temp.options[i].value+");");  	// Puts the added value at the front of the appropriate array
	}
	eval("tag_"+which+" = holder;");	// Put the array value back
	jsearchPrintBox('tag',which);		// Print the appropriate box
}


//*************************
// INPUT CLEANER STUFF
//*************************

//**
//*
//*  Javascript trim, ltrim, rtrim
//*  http://www.webtoolkit.info/
//*
//**
 
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
 
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
 
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

// Cleans the term input and returns a comma separated string
function jsearchSanitize(input)
{
	cleaned = input;
	cleaned = cleaned.replace(/\s/gi,",");	// Note: g means global and tells it to replace more than once
	cleaned = cleaned.replace(/[^a-z0-9 ,]*/gi,"");	// Note: g means global and tells it to replace more than once
	return cleaned;
}

function jsearchTermSanitize(input)
{
	cleaned = input;
	cleaned = cleaned.replace(/\s/gi,",");	// Note: g means global and tells it to replace more than once
	cleaned = cleaned.replace(/[^a-z0-9,]*/gi,"");	// Note: g means global and tells it to replace more than once
	cleaned = cleaned.replace(/,,/gi,",");	// Note: g means global and tells it to replace more than once
	// Clear any commas at the front or back
	if (cleaned.charAt(0) == ",") cleaned = cleaned.substring(1,cleaned.length-1);
	if (cleaned.charAt(cleaned.length-1) == ",") cleaned = cleaned.substring(0,cleaned.length-1);
	return cleaned;
}

function filterSanitize(id)
{
	temp = $jsq("#"+id).val();
	$jsq("#"+id).val(temp.replace(/[^a-zA-Z0-9\s-_]/g,""));
}

function numCleaner(obj)
{
	return obj.value.replace(new RegExp("[^0-9]","g"),"");	// Note: g means global and tells it to replace more than once
}

function getSelectedOption(name)
{
	return $jsq("#"+name).val();
}


// USED FOR THE PAGELINKS SECTION
function jsearchGoto(num,lastPage)
{
	if (num < 1)
		num = 1;
	if (num > lastPage)
		num = lastPage;
		
	$jsq('#paged_holder').val(num); 	// Set the value
	jsearchCallAJAX(num);			// Force a page load and don't reset the paged value
}


function jsearchAJAXUpdate(data)
{
	$jsq("#jsearch_results_area").html(data);
}

var lastAJAXcall=null;			// If this doesn't match the call, that means we need to wait.
function jsearchCallAJAX(page)
{
	if (typeof(page) == "undefined")
		page = 1;
	$jsq('#paged_holder').val(page); 			// Every time the query changes, start from page one
	vars = jsearchVars();
	if (lastAJAXcall!=null) lastAJAXcall.abort();		// If a query is already loading when I get here, abort it and start this one
	AJAXurl = jsearchAJAXURL;				// This points to the results-handling file we'll be using	
	$jsq("#jsearch_results_area").html($jsq("#jsearch_loading").html());
	lastAJAXcall = $jsq.post(AJAXurl,vars,jsearchAJAXUpdate);	// Hold this for aborting it later if necessary
}

// Used because I was always having to check to see if there were already vars before adding more. This just helps
function jsearchAddVars(url,vars)
{
	if (url.indexOf('?')==-1)
		return url+"?"+vars;
	else
		return url+"&"+vars;
}

function jsearchURL()
{
	vars = jsearchVars();
	var_string = "";
	for (var_name in vars)
	{
		var_string += var_name+"="+vars[var_name]+"&";
	}
	return jsearchAddVars(jsearchTargetPage,var_string);
}

function jsearchVars()
{
	var vars = {};

	// Options stuff	
	vars['ppall'] = $jsq("#jsearch_ppall_container input:radio:checked").val();	// Gets the value of the currently selected radio
	vars['tefull'] = $jsq("#jsearch_tefull_container input:radio:checked").val();	// Gets the value of the currently selected radio
	vars['ppp'] = $jsq('#jsearch_ppp').val();					// Posts per page
	vars['results_type'] = $jsq('#jsearch_results_type').val();			// What type of results display do we want?
	vars['eng'] = $jsq("#jsearch_eng_container input:radio:checked").val();		// Gets the value of the currently selected radio

	vars['paged'] = $jsq('#paged_holder').val();
	vars['order'] = $jsq('#order_holder').val();

	// Terms
	if (term_any.length)	// We have some
		vars['term_any'] = term_any.toString(); 
	if (term_all.length)	// We have some
		vars['term_all'] = term_all.toString(); 
	if (term_none.length)	// We have some
		vars['term_none'] = term_none.toString(); 

	// The different stuff we can search with the terms
	if ($jsq('#jsearch_search_titles').attr('checked')) vars['search_titles'] = "1";
	else vars['search_titles'] = "0";
	if ($jsq('#jsearch_search_content').attr('checked')) vars['search_content'] = "1";
	else vars['search_content'] = "0";
	if ($jsq('#jsearch_search_excerpts').attr('checked')) vars['search_excerpts'] = "1";
	else vars['search_excerpts'] = "0";
	if ($jsq('#jsearch_search_custom').attr('checked')) vars['search_custom'] = "1";
	else vars['search_custom'] = "0";
//	if ($jsq('#jsearch_search_comments').attr('checked') vars['search_comments'] = "1";
//	else vars['search_comments'] = "0";
	
	// Categories	
	if ($jsq('#jsearch_category_filter').val()) vars['cat_filter'] = $jsq('#jsearch_category_filter').val();
	if (cat_any.length)	// We have some
		vars['cat_any'] = cat_any.toString(); 
	if (cat_all.length)	// We have some
		vars['cat_all'] = cat_all.toString(); 
	if (cat_none.length)	// We have some
		vars['cat_none'] = cat_none.toString(); 
	temp = getSelectedOption('jsearch_cat_parents_select');
	if (typeof(temp) != 'undefined')
		vars['selected_cat_parent'] = temp;
	
	// Tags	
	if ($jsq('#jsearch_tag_filter').val()) vars['tag_filter'] = $jsq('#jsearch_tag_filter').val();
	if (tag_any.length)	// We have some
		vars['tag_any'] = tag_any.toString(); 
	if (tag_all.length)	// We have some
		vars['tag_all'] = tag_all.toString(); 
	if (tag_none.length)	// We have some
		vars['tag_none'] = tag_none.toString();
		
	vars['control_vis'] = jsearchControlVis;

	return vars;
}