var ajax_trigger_count = 00;

$(document).ready(function() {
	fixNamedAnchorDisplay();
	formAddInnerLabels();
	formAutocomplete();
	formDisplayRecaptcha();
	formToggleView();
	emailDecode();
	evenSpacing();
	prepareAccordions();
	prepareAjaxLinks();
	prepareFormValidation();
	processAutoCenter();
	prepareDimmer();
	prepareExpanderUL();
	prepareNamedAnchors();
	printerFriendlyLinks();
	
	$('.close').live('click',function(e) {
		if(e.which==1) {
			if($(this).parents('#modal').length>0) {
				dimOff();
			} else {
				history.back();
			}
		}
	});
	
	
	$(document).keydown(function(e) {
		if(e.which==27) {
			dimOff();
		}
	});

	$('#main').ajaxComplete(function(e) {
		setTimeout('formDisplayRecaptcha()','100');
		
	});

});

function fixNamedAnchorDisplay() {
	$('a[name]').each(function() {
		if(typeof($(this).attr('href'))=='undefined') {
			$(this).addClass('named_anchor');
		}
	});
}

function formToggleView() {
	$('.toggle_view').each(function() {
		$(this).find('.trigger').show();
		var $trigger_checkbox = $(this).find('.trigger input[type="checkbox"]');
		var trigger_is_reversed = $(this).hasClass('reverse');
		var $target = $(this).find('.target');
		if(trigger_is_reversed) {
			if($trigger_checkbox.attr('checked')==true) {
				$target.hide();
			}
		} else {
			if($trigger_checkbox.attr('checked')==false) {
				$target.hide();
			}
		}
		
		$trigger_checkbox.click(function() {
			$(this).trigger('change');
		});
		
		$trigger_checkbox.change(function() {
			if(trigger_is_reversed) {
				if($trigger_checkbox.attr('checked')==true) {
					$target.slideUp();
				} else {
					$target.slideDown();
					var scroll_destination = $(window).scrollTop() + 300;
					$('html, body').animate({scrollTop:scroll_destination}, '200');
				}
			} else {
				if($trigger_checkbox.attr('checked')==true) {
					$target.slideDown();
					var scroll_destination = $(window).scrollTop() + 300;
					$('html, body').animate({scrollTop:scroll_destination}, '200');
				} else {
					$target.slideUp();
				}
			}
		});
		
	});
}

function formDisplayRecaptcha() {
	$('.recaptcha_container').each(function() {
		if(typeof($(this).attr('invalid'))!='undefined') {
			var invalid_message = $(this).attr('invalid');
		} else {
			var invalid_message = '';
		}
		var recaptcha_container_id = $(this).attr('id');
		Recaptcha.create(
			"6LdKOgYAAAAAAPveNTTf0PHHEU9ztZnlFgNtCKi8",
			recaptcha_container_id,
			{
				theme: "clean",
				callback: recaptchaMarkValidation(invalid_message)
			}
		);
	});
}

function recaptchaMarkValidation(invalid_message) {
	if(invalid_message.length>0) {
		invalid_message = 'Please try again.';
		setTimeout("formElementInvalid($('#recaptcha_response_field'),'" + invalid_message + "')",'500');
	}
}

function scrollToElement($element,extra,direction) {
	var scroll_time = 700;
	if(typeof(direction)=='undefined') {
		var direction = '';
	} else {
		var window_offset = $(window).scrollTop();
	}
	if(typeof(extra)=='undefined') {
		extra = 0;
	}
	if($element=='top' || $element=='a[name=top]') {
		$element = 'html';
	}
	if(typeof($element)=='string') {
		$element = $($element);
	}
	if($element.length==0) {
		return false;
	} else {
		var element_offset = $element.offset().top + parseInt(extra);
		if(element_offset<0) {
			element_offset = 0;
		}
		switch(direction) {
			case 'up':
				if(element_offset>=window_offset) {
					return true;
				}
				break;
			case 'down':
				if(element_offset<=window_offset) {
					return true;
				}
				break;
			default:
				if(element_offset==window_offset) {
					return true;
				}
		}
		$('html, body').animate({scrollTop:element_offset}, scroll_time);
		return true;
	}
}

function prepareNamedAnchors() {
	$('a[href^=#]').live('click',function(e) {
		if(e.which==1) {
			var anchor_name = $(this).attr('href').substring(1);
			if(scrollToElement('a[name=' + anchor_name + ']')==true) {
				e.preventDefault();
			}
		}
	});
}


// processAutoCenter finds elements of class .auto_center and centers them with fixed position. This is useful for centering elements of unknown or dynamic sizes, especially when other methods would exclude padding and/or borders. Each matched element is wrapped in a div of class "auto_center_wrapper". The rendered width of the wrapper is measured, and the left margin is dynamically changed with css to center the object.
function processAutoCenter() {
	$('.auto_center').each(function() {
		// We need to know if this function has already been called on this object before. If so, it will already have an "auto_center_wrapper" parent. We clone the element, then remove the original (along with its parent). From that point on, this iteration of the function will refer to the clone.
		if($(this).parent('.auto_center_wrapper').length>0) {
			var $this_clone = $(this).clone();
			$(this).parent('.auto_center_wrapper').before($this_clone);
			$(this).parent('.auto_center_wrapper').remove();
			var $this = $this_clone;
		} else {
			var $this = $(this);
		}
		$this.wrap('<div class="auto_center_wrapper"></div>');
		var $this_parent = $this.parent('.auto_center_wrapper');
		var effective_width = $this_parent.width();
		var effective_height = $this_parent.height();
		var this_new_margin_left = -1 * effective_width / 2;
		// var this_new_margin_top = -1 * effective_height / 2;
		var this_z_index = $this.css('z-index');
		$this_parent.css('margin-left',this_new_margin_left);
		// $this_parent.css('margin-top',this_new_margin_top);
		$this_parent.css('z-index',this_z_index);
		
		if(effective_height>300) {
			$this_parent.css('position','absolute');
		}
		
		
	});
}

function printerFriendlyLinks() {
	$('#main p a, #main li a, #main h2 a').each(function() {
		if(typeof($(this).attr('href'))!='undefined') {
			var link_url = $(this).attr('href');
			if($(this).html().search('\@')!=-1) {
				return true;
			}
			if($(this).html().search('^http')>-1) {
				return true;
			}
			if(link_url.search('http://')==-1 && link_url.search('mailto:')==-1) {
				link_url = 'http://www.menlo.edu/' + link_url;
			}
			$(this).append('<span class="print_link"> (' + link_url + ')</span>');
		}
	});
	
	$('#supplementary li a, #supplementary h2 a').each(function() {
		var link_url = $(this).attr('href');
		if($(this).html().search('\@')!=-1) {
			return true;
		}
		if(link_url.search('http://')==-1 && link_url.search('mailto:')==-1) {
			link_url = 'http://www.menlo.edu/' + link_url;
		}
		$(this).append('<span class="print_link"> ' + link_url + '</span>');
	});
}

function prepareAccordions() {
	$('.accordion ul[class!=current]').hide();
	$('.accordion > li').hover(function() {
		$hovered_accordion_element = $(this);
		if(typeof(accordion_move_timeout)!='undefined') {
			clearTimeout(accordion_move_timeout);
		}
		
		accordion_move_timeout = setTimeout('accordionMove($hovered_accordion_element)',300);
	});
	$('.accordion').hover(function() {

	}, function() {
		if(typeof(accordion_move_timeout)!='undefined') {
			clearTimeout(accordion_move_timeout);
		}
	});
}

function accordionMove($accordion_element) {
	$accordion_parent = $accordion_element.parent('.accordion');
	$accordion_child = $accordion_element.find('ul');
	$accordion_siblings = $accordion_parent.find('li');
	$accordion_newphews = $accordion_parent.find('ul');
		
	$accordion_siblings.removeClass('current')
	$accordion_element.addClass('current');

	$accordion_siblings.find('ul').addClass('ready_to_hide');
	$accordion_siblings.find('ul').removeClass('ready_to_show');
		
	$accordion_child.removeClass('ready_to_hide');
	$accordion_child.addClass('ready_to_show');
	$accordion_parent.find('.ready_to_hide').slideUp(300);
	$accordion_parent.find('.ready_to_show').slideDown(300);
}

// friendlyText converts a string to lowercase and replaces spaces with underscores.
// It was originally developed so that human-friendly @title's in html tags could be translated to css-selector-friendly strings for javascript applications.

// If changes are maded to this function, equivalent changes should also be made to the PHP function "FriendlyText".

function friendlyText(string) {
	string = string.toLowerCase();
	string = string.replace(/[ |/|&]/g,'_');
	string = string.replace(/[^a-z0-9]/g,'');
	// Multiple underscores should be consolidated.
	string = string.replace(/_[_]*/g,'_');
	return string;
}

// prepareExpanderUL looks for <ul> tags of class "expander" and adds a nice sliding effect to child <ul>'s as a click event on each item.
function prepareExpanderUL() {
	$('ul.expander').each(function() {
		$(this).find('ul').hide();
	});
	$('ul.expander > li > a').each(function() {
		$(this).addClass('expander');
		$(this).click(function(e) {
			if(e.which==1) {
				e.preventDefault();
				$(this).toggleClass('expanded');
				$(this).parent().find('ul').slideToggle('500');
			}
		});
	});
}

// prepareDimmer adds the 'dimmer' class to a <div> with id="dimmer". The stylesheet makes this a fixed black box that takes up the entire window and sits at z-index 100. When the dimmer is clicked, it will go away. This effectively dims the background while objects at z-index >100 remain fully illuminated. Clicking the dimmer is a common user action to dismiss or remove focus from the foreground object, so the logical result is for the dimmer to fade away.
function prepareDimmer() {
	$('#dimmer').addClass('dimmer');
	$('.dimmer').hide();
	$('#dimmer').live('click',function(e) {
		if(e.which!=3) {
			dimOff();
		}
	});
	

}

// When dim is called, the dimmer div fades in, essentially turning down the lights on anything under z-index 100.
function dim() {
	$('#dimmer').css('display','block');
	$('#dimmer').fadeTo('fast',0.4);
}

function dimOff() {
	$('.pop_up_image').hide();
	$('.modal').fadeOut('200');
	$('.loading').fadeOut('200');
	if(typeof(show_loading_timeout)!='undefined') {
		clearTimeout(show_loading_timeout);
	}
	$('#dimmer').fadeOut('fast');
}

// popUp displays a modal window.
function popUp(url,user_data) {
	if(typeof(show_loading_timeout)!='undefined') {
		clearTimeout(show_loading_timeout);
	}
	dim();
	show_loading_timeout = setTimeout('$("#loading").fadeIn("200")','300');
	$('#modal').hide();
	$.post(
		url,
		user_data,
		function(data) {
			$('#modal').html(data);
			$('#modal').show();
			if(typeof(show_loading_timeout)!='undefined') {
				clearTimeout(show_loading_timeout);
			}
			$('#loading').hide();
			processAutoCenter();
			
			var scroll_time = $('html').scrollTop() * 4;
			if(scroll_time > 0 && scroll_time < 500 ) {
				scroll_time = 500;
			}
			if(scroll_time > 1500) {
				scroll_time = 1500;
			}
			if(scroll_time > 0) {
				$('html, body').animate({scrollTop:0}, scroll_time);
			}
		},
		'html'
	);
}

// popUpImage displays a pop-up window with an image located at img_url.
function popUpImage(img_url) {
	dim();
	$('#pop_up_image').addClass('pop_up_image');
	$('.pop_up_image').hide();
	$('#pop_up_image').html('<img src="' + img_url + '" /></div>' + "\n\n");
	$('#pop_up_image img').load(function() {
		$('.pop_up_image').show();
		var new_top_margin = Math.ceil(-1 * $(this).height() / 2);
		var new_left_margin = Math.ceil(-1 * $(this).width() / 2);
		$('.pop_up_image').css('margin',new_top_margin + 'px 0 0 ' + new_left_margin + 'px')
	});
}

// formAddInnerLabels assigns a default value for <input> tags equal to the <label> that points to them. Also modifies value on focus and blur.
function formAddInnerLabels() {
	$('input.inner_label').each(function() {
		var field_id = $(this).attr('id');
		// Find the <label> that points to this <input>
		var field_label = $('label[for='+field_id+']');
		if((field_label).length>0) {
		
			// Add the "default" class to the input, populate with <label> text, hide the original label.
			$(this).addClass('default');
			var default_text = field_label.text();
			$(this).val(default_text);
			field_label.hide();
			
			// Upon focus, if the box still has the default text, remove the "default" class and clear the box.
			$(this).focus(function() {
				if($(this).val()==default_text) {
					$(this).val('');
					$(this).removeClass('default');
				}
			});
			
			// Upon blur, if the box is empty, assign "default" class and populate with default text.
			$(this).blur(function() {
				if($(this).val()=='') {
					$(this).addClass('default');
					$(this).val(default_text);
				}
			});
		}
	});
}


// formAutocomplete creates a combo box with dynamic suggestions. Basically, the non-javascript folks are served up a text input and accompanying dropdown. This function searches the DOM for a <select> with class "autocomplete" and accompanying <input>. It takes all of the text nodes and values from every <option> tag, then uses this information to add an unordered list of the same items. It then hides the original <select>. While a <select> with size>1 would function the same with a lot less hand-holding, I found it difficult to style (read "position") the <select> consistently across browsers.

// TAKING ADVANTAGE OF THIS FUNCTION
// 1) Create a text input with an id of "[whateveryouwant]".
// 2) Create a <select> with id "[whateveryouwant]_dropdown".
// 3) Populate the <select> with all autocomplete options.

function formAutocomplete() {
	$('select.autocomplete').each(function() {
		var this_id = $(this).attr('id');
		
		// This is how we find the accompanying text input.
		var input_id = this_id.replace('_dropdown','');
		var input = $('#'+input_id);
		
		// If we can't find it, skip it.
		if(input.length==0) {
			return 'continue';
		}
		var dropdown_id = this_id + '_dropdown_multi';
		
		// Hide the original <select>
		$(this).hide();
		
		// Insert an empty ordered list. We'll call it "dropdown".
		$(this).before(
			'<br /><ul class="autocomplete_multi" id="' + dropdown_id + '"></ul>'
		);
		var dropdown = $('#'+dropdown_id);
		
		// Hide the dropdown.
		dropdown.hide();
		
		// Loop through all of the <option>'s from the original <select>.
		$('#' + this_id + ' option').each(function(i) {
			// The first one usually has an empty value and a text node like "pick something from this list". We don't need that.
			if(i==0) {
				return 'continue';
			}
			var option_text = $(this).text();
			var option_value = $(this).val();
			var option_description = $(this).attr('title');
			
			// We're about to make some <li> tags, and their id's will be serialized.
			new_list_item_id = dropdown_id + '_' + i;
			dropdown.append('<li id="' + new_list_item_id + '" title="' + option_description + ' ' + option_text + '">' + option_text + '</li>');
			
			// If the user clicks one of these <li>'s, it changes the <input> value, and the dropdown makes a graceful exit.
			$('#' + new_list_item_id).click(function(e) {
				if(e.which==1) {
					input.val(option_value);
					dropdown.fadeOut('fast');	
				}
			});
			
			// Thought about handling the hover in CSS, then I thought about IE. And there's no sense in doing it both ways, because if we've made it this far, JavaScript is definitely enabled.
			$('#' + new_list_item_id).hover(function() {
				$(this).addClass('hover');
			}, function() {
				$(this).removeClass('hover');
			});
		});
		// The suggestion magic happens when the user starts typing in the <input> (or just tabs into it).
		input.keyup(function() {
			// any_matches will keep track of whether we'll need to display the dropdown on each keyup. If there are no matches, we don't need the box.
			var any_matches = false;
			var current_text = $(this).val();
			// Our ultra-forgiving match algorithm ignores capitalization and anything that isn't a letter, including spaces. I decided to omit spaces to avoid punishing the user for typing "JJ" as "J J" and stuff like that.
			var current_text_compare = current_text.toLowerCase().replace(/[^a-z]/g,'');
			
			// Because of the way we determine the match, a blank field would match everything.
			if(current_text_compare.length>0) {
				// Check each <li> for a match.
				$('#' + dropdown_id + ' li').each(function() {
					var list_item_text = $(this).text();
					list_item_text_compare = list_item_text.toLowerCase().replace(/[^a-z]/g,'');
					if(list_item_text_compare.indexOf(current_text_compare)==0) {
						// If we've got a match, we'll show this <li> and let the function know that we'd like to display the dropdown later.
						$(this).show();
						any_matches = true;
					} else {
						$(this).hide();
					}
				});
			}
			// Here's where we see how we did. If there's a match, we'll show the dropdown.
			if(any_matches==true) {
				dropdown.fadeIn('fast');
			} else {
				dropdown.fadeOut('fast');
			}
		});
		// If the user takes focus away from the <input>, we hide the dropdown.
		input.blur(function() {
			dropdown.fadeOut('fast');
		});
	});
}


function email_valid(string) {
	var local_name = string.replace(/@.*$/,'');
	var domain_name = string.replace(/^.*@/,'');
	
	
	// No double dots
	if(string.search(/\.\./)>-1) {
		return false;
	}
	
	// No double @'s
	if(string.search(/@@/)>-1) {
		return false;
	}
	
	// No dots at start or end of local name
	if(local_name.search(/^[^\.].*[^\.]$/)==-1) {
		return false;
	}
	
	// No bad characters in local name
	if(local_name.search(/[^a-zA-Z0-9\!\#\$\%\&\'\*\+\-\/\=\?\^/_\`\{\|\}\~]/)>-1) {
		return false;
	}
	
	// No bad characters in domain name
	if(domain_name.search(/[^a-zA-Z0-9\-\.]/)>-1) {
		return false;
	}
	
	// No dots at start or end of domain name
	if(domain_name.search(/\./)==-1) {
		return false;
	}
	
	if(domain_name.search(/^[^\.].*[^\.]$/)==-1) {
		return false;
	}
	
	return true;
}

function date_valid($element) {
	var text = String($element.val());
	$.post(
		'http://www.menlo.edu/include/utilities/validate.php',
		{ type: 'date', data: text },

		function(response) {
			if(response.length>0) {
				$element.val(response);
				formElementValid($element);
			} else {
				formElementInvalid($element,'The system cannot process dates expressed in this format.');
			}
		},
		'text'
	);
}

function time_valid($element) {
	var text = String($element.val());
	$.post(
		'http://www.menlo.edu/include/utilities/validate.php',
		{ type: 'time', data: text },
		function(data) {
			if(data.length>0) {
				$element.val(data);
				formElementValid($element);
			} else {
				formElementInvalid($element,'The system cannot process time expressed in this format.');
			}
		},
		'text'
	);
}

function quantity_valid(quantity) {
	if(quantity=='' || quantity.search(/^[0-9\s]*$/)>-1) {
		return true;
	} else {
		return false;
	}
}


function validateFormElement($element) {
	var validate_by_default = true;
	if($element.hasClass('validate_not_blank')) {
		if($element.val()=='') {
			formElementInvalid($element,'This field cannot be blank.');
			return false;
		}
	}
	if($element.hasClass('validate_email')) {
		if($element.val()=='' || email_valid($element.val())) {
		} else {
			formElementInvalid($element,'Please specify a valid e-mail address.');
			return false;
		}
	}
	if($element.hasClass('validate_date')) {
//		validate_by_default = false;
		if($element.val()=='') {
			formElementValid($element);
		} else {
			date_valid($element);
		}
	}
	if($element.hasClass('validate_time')) {
		validate_by_default = false;
		if($element.val()=='') {
			formElementValid($element);
		} else {
			time_valid($element);
		}
	}
	
	if($element.hasClass('validate_quantity')) {
		if($element.val()=='' || quantity_valid($element.val())) {
		} else {
			formElementInvalid($element,'Please specify a number or leave this field blank.');
			return false;
		}
	}
	
	if(validate_by_default==true) {
		formElementValid($element);
	}
	
	return true;
}

function formElementValid($element) {
	$element.removeClass('invalid');
		if($element.attr('type')!='button' && $element.attr('type')!='submit') {
			$element.addClass('validation_ok');
		}
		var $invalid_explanation = $('p#' + $element.attr('id') + '_invalid_explanation');
		if($invalid_explanation.length>0) {
			$invalid_explanation.fadeTo('fast',0,function() {
				$(this).slideUp('fast',function() {
					$(this).remove();
				});
			});
		}
}

function formElementInvalid($element,message) {
	$element.addClass('invalid');
	$element.removeClass('validation_ok');
	if($element.attr('type')=='text') {
		var invalid_explanation_class = "invalid_explanation_javascript text";
	} else {
		var invalid_explanation_class = "invalid_explanation_javascript";
	}
	var $form = $element.parents('form');
//	$form.find('label[for="' + $element.attr('id') + '"]').addClass('invalid');
	if(message!='') {
		var $invalid_explanation = $('p#' + $element.attr('id') + '_invalid_explanation');
		
		if($invalid_explanation.length==0) {
			$element.after('<p id="' + $element.attr('id') + '_invalid_explanation" class="' + invalid_explanation_class + '"></p>');
			var $invalid_explanation = $('p#' + $element.attr('id') + '_invalid_explanation');
		} else {
			
		}

		if($invalid_explanation.html()!=message) {
			$invalid_explanation.fadeTo('5',0,function() {
				$(this).html(message);
				$invalid_explanation.slideDown('fast',function() {
					$invalid_explanation.fadeTo('fast',1);
				});
			});
		}
	}	
}




// evenSpacing is called to distribute <li> tags horizontally with even space in between. This seems more visually balanced than placing the objects on a grid. When tested in Safari 4 on the Mac, more than 10% of page loads produced unexpected results due to mesreading of the clientWidth property. This could be avoided by adding a slight delay, but the noticeable "jump" was not favorable. Instead, the function will do its best to determine the appropriate spacing, and if it comes up less than zero, it will try again. After three attempts, it will give up. There is still a noticeable "jump" in the content, but it only occurs when there is a problem that would otherwise produce strange results.

// TAKING ADVANTAGE OF evenSpacing
// Create a <ul> or other list with class "even_spacing" and use css do define the desired width.
// Style the interior <li> to float left or right.


function evenSpacing(count) {
	if(count===undefined) {
		count = 0;
	}
	count++;
	
	// If we have already tried three times, this just won't work.
	if(count>3) {
		return true;
	}
	// Find all candidate lists.
	$('ul.even_spacing').each(function() {
		var number_of_items = 0;
		// Measure the width of the container.
		var available_width = this.clientWidth;
		$(this).children('li').each(function(i) {
			// Subtract the width of each <li> from the total and keep count of items.
			available_width -= this.clientWidth;
			number_of_items++;
		});
		
		// Take the remaining width, devide by one more than the number of items (b/c margins are on the left AND right), then round down just to be safe.
		var new_margin = Math.floor(available_width/(number_of_items+1));
		
		// If the new margin is less than zero, do not make the change. Reload the function after 10ms.
		if(new_margin<0) {
			setTimeout(function() {
				evenSpacing(count);
			},10);
			return true;
		}
		
		// If we like the number, assign the new margins to the <li>'s
		$(this).children('li').each(function() {
			$(this).css("margin-left",new_margin+'px');
			$(this).css("margin-right","0");
		});
	});
}


function prepareAjaxLinks() {
	$('a.ajax').live('click',function(e) {
		if(e.which==1) {
			e.preventDefault();		
			popUp($(this).attr('href'),temp_ajax_data);
		}
	});
}


function prepareFormValidation() {
	$('form').submit(function(event) {
		var form_is_valid = true;
		$(this).find('#recaptcha_response_field').addClass('validate_not_blank');
		$(this).find('input, textarea').each(function() {
			if(validateFormElement($(this))==true) {
				
			} else {
				form_is_valid = false;
			}
		});
		
		if(form_is_valid==true) {
			var form_data_addition = '&use_ajax=true';
			if($(this).hasClass('ajax')) {
				$this_submit = $(this).find('input[type=submit]');
				if($this_submit.length>0) {
					form_data_addition += '&' + $this_submit.attr('name') + '=' + $this_submit.val();
				}
				if($(this).closest('div').length==1) {
					$this_parent_div = $(this).closest('div');
					$.post(
						$(this).attr('action'),
						$(this).serialize() + form_data_addition,
						function(data) {
							$this_parent_div.html(data);
						},
						'html'
					);
				}
				return false;
			} else {
				return true;
			}
		} else {
			scrollToElement($(this).find('.invalid:first'),'-20','up');
			return false;
		}
	});
	$('input').live('change',function() {
//		validateFormElement($(this));
	});
	$('form .invalid').live('keyup',function() {
//		validateFormElement($(this));
	});
	$('form .invalid').live('change',function() {
		validateFormElement($(this));
	});
	$('form *').live('keyup',function() {
		// Just in case a modal form box gets closed prematurely, we save the data that was in there. If the form is pulled up again, we can recall this data so the user doesn't have to re-enter it.
		temp_ajax_data = ($(this).parents('form').serialize()) + '&use_ajax=true';
	});
}


function dimmerOn() {
	var dimmer = document.getElementById('dimmer');
	dimmer.style.visibility = 'visible';
	opacity('dimmer',1,50,250);
//	alert(dimmer);
//	changeOpac(50,'dimmer');
}

function dimmerOff() {
	var dimmer = document.getElementById('dimmer');
	opacity('dimmer',50,0,250);
}


/* 
emailDecode is part of the site's e-mail address obfuscation process, only displaying e-mail addresses when javascript is enabled.

The functions searches for <span> elements of class "hidden_email". Here is an example of such a tag:

<p>For more information, please contact the webmaster at 650-555-1010<span class="hidden_email"><!-- or by e-mail at |7765626d6173746572406d656e6c6f2e656475|--></span>.</p>

The span's contents are commented out so they aren't displayed on the screen in case JavaScript isn't enabled. The e-mail address is converted to a hex string so spambots won't read it, and it is placed between vertical bars so that this script can find it.

Without JavaScript, the user sees "For more information, please contact the webmaster at 650-555-1010."

With JavaScript, the user sees "For more information, please contact the webmaster at 650-555-1010 or by e-mail at <a href="mailto:webmaster@menlo.edu">webmaster@menlo.edu</a>.

To encode the e-mail address easily, use the PHP EmailEncode function like this:

echo '<p>For more information, please contact the webmaster at 650-555-1010' . EmailEncode('webmaster@menlo.edu',' or by e-mail at ||') . '.</p>';

*/

function emailDecode() {
	// Look for the spans and grab their contents.
	$('span.hidden_email').each(function() {
		var scrambled_text = $(this).html();
		// Remove the comment markers.
		scrambled_text = scrambled_text.replace('<!-' + '-','');
		scrambled_text = scrambled_text.replace('-->','');
		// Look for the content within vertical bars. This is the encoded e-mail address.
		email_scrambled = scrambled_text.replace(/^.*\|(.*)\|.*$/g,'$1');
		// Use hex2ascii to decode it.
		email = hex2ascii(email_scrambled);
		// Turn the e-mail address into a link.
		email_html = '<a href="mailto:' + email + '">' + email + '</a>';
		
		// The final step is replacing the encoded e-mail address with the link.
		decoded_text = scrambled_text.replace(/^(.*)\|.*\|(.*)$/g,'$1' + email_html + '$2');
		
		$(this).html(decoded_text);
	});
}

// hex2ascii is like unescape but does not require the '%' prefix for hex pairs, instead assuming that every two characters are a hex pair, adding at '%' to it, then unescaping it as usual.
function hex2ascii(hex) {
	var result = '';
	for(i=0;i<hex.length;i+=2) {
		result += unescape('%'+hex.substr(i,2));
	}
	return result;
}


// Fade over time.

function opacity(id, opacStart, opacEnd, millisec) { 
    //speed for each frame 
    var speed = Math.round(millisec / 100); 
    var timer = 0; 

    //determine the direction for the blending, if start and end are the same nothing happens 
    if(opacStart > opacEnd) { 
        for(i = opacStart; i >= opacEnd; i--) { 
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed)); 
            
            timer++; 
        } 
    } else if(opacStart < opacEnd) { 
        for(i = opacStart; i <= opacEnd; i++) 
            { 
            setTimeout("changeOpac(" + i + ",'" + id + "')",(timer * speed)); 
            timer++; 
        } 
    } 
} 

//change the opacity for different browsers 
function changeOpac(opacity, id) { 
    var object = document.getElementById(id).style; 
    object.opacity = (opacity / 100); 
    object.MozOpacity = (opacity / 100); 
    object.KhtmlOpacity = (opacity / 100); 
    object.filter = "alpha(opacity=" + opacity + ")"; 
    if(opacity==0) {
    		document.getElementById(id).style.visibility = 'hidden';
    }
}




/* TextInputFocus and TextInputBlur were written to enable a search box behavior wherein the box (object) inititally has some default text (like "search") in a grayed out style. When the user puts focus on the box, the default text is removed, and a darker color is used for the text. If the box is blurred when empty, the default text and style return.

alternate_default_text was introduced for a particular behavior in a search results page:

	User has entered "dancing" in a search box and has executed the search.
	On the results page, "dancing", the alternate_default_text, appears grayed out in the search box.
	When the user focuses on the search box, "dancing" goes away and the active color is applied.
	If the user blurs the box when empty, the box will now read "search".
	
A simple implementation of these two functions would look like this:
	<input type="text" value="search" onFocus="TextInputFocus(this,'search',black);" onBlur="TextInputBlur(this,'search',gray);" />
	
*/

function TextInputFocus(object,default_text,color,alternate_default_text) {
	if(object.value==default_text) {
		object.value = '';
	} else if(typeof(alternate_default_text)!='undefined') {
		if(object.value==alternate_default_text) {
			object.value = '';
		}
	}
	object.style.color = color;
}

function TextInputBlur(object,default_text,color) {
	if(object.value=='') {
		object.value = default_text;
		object.style.color = color;
	}
}

// postwith uses a dynamically-generated form to redirect the user to "url" with POST "data".
function postwith(url,data) {
	var temp_form = document.createElement("form");
	temp_form.method = 'post';
	temp_form.action = url;
	for(var key in data) {
		var temp_input = document.createElement('input');
		temp_input.setAttribute('name',key);
		temp_input.setAttribute('value',data[key]);
		temp_form.appendChild(temp_input);
	}
	document.body.appendChild(temp_form);
	temp_form.submit();
	document.body.removeChild(temp_form);
}