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


	// clear password input on edit profile form
	$("#edit_profile input#password").val("");
	
	// Tabs
	var tabs = $('div.tabs ul.tabNav a');
	var tabContainers = $('div.tabs > div');
    tabContainers.hide().filter(':first').show();
    
    
    $('div.tabs ul.tabNav a').click(function () {
    		tabs.removeClass();
            tabContainers.hide();
            tabContainers.filter(this.hash).show();
            $('div.tabs ul.tabNavigation a').removeClass('selected');
            $(this).addClass('selected');
            return false;
    }).filter(':first').click();
    
    $('a img').parent().addClass("imgLink");

    
	var default_email = 'E-Mail';
	$('#edit_profile input[name=username]').focus(function() {
		if ($(this).val() == default_email) {
			$(this).val('');
			$(this).siblings('input[name=password]').val('');
		}
	});
	$('#edit_profile input[name=username]').blur(function() {
		if ($(this).val() == '') {
			$(this).val(default_email);
			$(this).siblings('input[name=password]').val('12345678');
		}
	});
	
	// Show/hide comments
	$('a.#discuss').click(function() {
		$('#commentblock').toggle();
		colHeights();
		return false;
	});
	
	// Open external links in new window
	$("a[href^='http']")
		.not("[href*='www.bie.org'],[href*='bie.org']")
		.attr('target','_blank')
		.addClass('external');
	
	// Carousel
	$(".carousel .items").jCarouselLite({
	    btnNext: ".carouselNext",
    	btnPrev: ".carouselPrev",
		circlular: true,
		visible: 2,
		afterEnd: function(items) {
			moveCarouselText(items);
		}
	});
	moveCarouselText($(".carousel li").eq(2)); // set equal to number visible in the carousel thingy above
	
	function moveCarouselText(items) {
		$(".carousel .items li").removeClass('active');
		var item = $(items).eq(0);
		var h4 = '<h4>'+item.children('h4').text()+'</h4>';
		var p = '<p>'+$(items).eq(0).children('p').text()+'</p>';
		$('#carouselDetails').html(h4+p);
		item.addClass('active');
	}
	
	// By default, FoxEE assigns an href to this link equal to the
	// site homepage. That's fine and good *except* that in cases
	// where the user clicks the "buy now" button before FoxEE / 
	// FoxyCart is ready, the user gets taken to the homepage
	// rather than seeing the cart as expected. Setting the href
	// parameter to '#' isn't ideal, but at least the user doesn't
	// unexpectedly leave the page.
	$('form.foxycart a').attr('href', '#');
	
	// Hide summaries by default; show on click
	$('dd.summary *').not('h5').hide();
	$('dd.summary h5').text('Show Summary').addClass('clickshow').css('cursor', 'pointer');
	$('dd.summary h5.clickshow').live('click', function() {
		$(this)
			.text('Hide Summary').addClass('clickhide').removeClass('clickshow')
			.closest('dd.summary').find('*').show();
		colHeights();
		return false;
	});
	$('dd.summary h5.clickhide').live('click', function() {
		$(this)
			.text('Show Summary').addClass('clickshow').removeClass('clickhide')
			.closest('dd.summary').children().not('h5').hide();
		colHeights();
		return false;
	});


	// Hide answers by default; show on click
	$('div.answer *').not('h5').hide();
	$('div.answer h5').text('Show details').addClass('clickshow').css('cursor', 'pointer');
	$('div.answer h5.clickshow').live('click', function() {
		$(this)
			.text('Hide details').addClass('clickhide').removeClass('clickshow')
			.closest('div.answer').find('*').show();
		colHeights();
		return false;
	});
	$('div.answer h5.clickhide').live('click', function() {
		$(this)
			.text('Show details').addClass('clickshow').removeClass('clickhide')
			.closest('div.answer').children().not('h5').hide();
		colHeights();
		return false;
	});


	function colHeights() {
		var group_1 = new Array(
		{
			obj: $('#primaryContent'),
			margin: false
		},
		{
			obj: $('#secondaryNav'),
			margin: true
		});
		var group_2 = new Array(
		{
			obj: $('#secondaryContent'),
			margin: false,
			fudge: -10
		});
		makeColumnHeightsEqual(group_1, group_2);

	}

	
	// Tell-a-Friend
	// "Share" features
	if ($('#shareWindow').length > 0) {
		$fields = $('#email, #privacy, #terms');
		$email = $('#email');
		$privacy = $('#privacy');
		$terms = $('#terms');
		$('#shareWindow').jqm({toTop: true});
		$fields.click(function() {
			var content = $(this).attr('href') + '/ajax/';
			if ($(this).attr('rel') > '') {
				content += $(this).attr('rel');
			}
			$('#shareWindow').jqm({
				ajax: content
			}).jqmShow();
			return false;
		});
		/*
		if ($email.length > 0) {
			$('#shareWindow').jqm({
				ajax: $email.attr('href') + '/ajax/' + $email.attr('rel').replace('-', '/'),
				trigger: '#email',
				toTop: true
			});
		}
		*/
	}
	
	// On the user profile, we need to force send an empty value
	// if a checkbox is unchecked. Otherwise the value won't change
	// in the DB.
	$('#member_form input:checkbox').click(function() {
		if (! $(this).is(':checked')) {
			if ($('input:hidden[name=' + $(this).attr('name') + ']').length == 0) {
				$(this).after('<input type="hidden" name="'+$(this).attr('name')+'" value="" />');
			}
		} else {
			$('input:hidden[name=' + $(this).attr('name') + ']').remove();
		}
	});
	
	
	
	
	// The form validation script we're using isn't very smart.
	// That's ok, we'll help it along.
	$all_fields = $('#profile_edit .field, #change_password .field, #register_form .field, #member_form .field');
	
	// Require password if username and/or screen name is changed in user profile
	// rp = require password, of course
	$rp_fields = $('#profile_edit input[name="username"], #profile_edit input[name="screen_name"]');
	if (valuesAreDefault($rp_fields) == false) {
		$('#passwordbox').show();
	}
	$rp_fields.keyup(function() {
		if (valuesAreDefault($rp_fields) == false) {
			$('#passwordbox').show();
		} else {
			$('#passwordbox').hide();
		}
	}).blur(function() {
		if (valuesAreDefault($rp_fields) == true) {
			$('#passwordbox').hide();
		}
	});
	
	// Check for errors
	$all_fields.blur(function() {
		handleInvalidFields($all_fields);
	}).keyup(function() {
		handleInvalidFields($all_fields);
	});
	
	// Check for errors on submit
	$('#profile_edit form, #register_form form, #member_form').bind('submit', function() {
		markEmptiesAsInvalid();
		var invalid = fetchInvalidFields($all_fields);
		if (valuesAreDefault($rp_fields) == false || invalid.length > 0) {
			handleInvalidFields($all_fields);
			
			if (invalid.length > 0) {
				return false;
			}
		
		} else if ($('#edit_profile #member_form').length > 0) {
			var all = false;
			$all_fields.each(function() {
				if (valuesAreDefault($(this)) == true) {
					all = true;
				}
			});
			if (all == true) {
				//$('input[name=return]').val($('input[name=return]').val().replace('profile_updated', 'profile').replace('password_updated', 'change_passwd/error'));
				$('.instructions').show();
				$('input[name="submit"]').attr('disabled', 'disabled').css('opacity', .3);
				return false;
			}
			
		} else if (valuesAreDefault($all_fields) == true) {
			$('input[name=return]').val($('input[name=return]').val().replace('profile_updated', 'profile').replace('password_updated', 'change_passwd/error'));
		}
		return true;
	});
	
	function markEmptiesAsInvalid() {
		var $req = $('input[name=username], input[name=screen_name]'); //, input[name=password], input[name=password_confirm], input[name=current_password]');
		$req.each(function() {
			if ($(this).val() == '') {
				$(this).addClass('invalid');
			}
		});
	}
	
	function handleInvalidFields($fields) {
		resetFields();
		$invalid_fields = fetchInvalidFields($fields);
		
		// Create the list o' invalids
		var list = '';
		$invalid_fields.each(function() {
			var $label = $(this).parent().prev();
			// Mark labels with the appropriate class
			$label.addClass('invalid');
			var text = $label.text().replace(' ', '_').replace('*', '').replace(':', '').replace('_', ' ');
			list += '<li><a href="#'+text.toLowerCase()+'">'+text+'</a></li>';
		});
		
		// If password is blank when it shouldn't be, add it to the list
		if ($('#password').val() == '' && valuesAreDefault($rp_fields) == false) {
			list += '<li><a href="#passwordbox">Password is required to make these changes</a></li>';
		}
		
		if (list > '') {
			$('input[name="submit"]').attr('disabled', 'disabled').css('opacity', .3).before('<div id="error_list"><p>Please provide the required information:</p><ul>' + list + '</ul></div>');
		}
		
		colHeights();
	}
	
	function resetFields() {
		// Remove error list
		$('#error_list').remove();
		
		// Remove .invalid from labels
		$('td.invalid').removeClass('invalid');
		
		// Un-disable the submit button
		$('input[name="submit"]').attr('disabled', '').css('opacity', 1);
	}
	
	function fetchInvalidFields($fields) {
		return $fields.filter('.invalid');
	}
	
	function valuesAreDefault($fields) {
		var count = 0;
		var length = $fields.length;
		$fields.each(function() {
			if ($(this).attr('defaultValue') == $(this).val()) {
				count++;
			}
		})
		
		return (count == length) ? true : false;
	}
	
	// Check the "other" checkbox if something is typed in the
	// "other" field
	var $other_fields = $('input[name=education_level_other_value], input[name=education_role_other_value]');
	var $other_checkboxes = $('input:checkbox[name=education_level_other], input:checkbox[name=education_role_other]');
	var oldValueArray = new Object;
	$other_fields.each(function() {
		var $checkbox = $(this).siblings(':checkbox[name^='+$(this).attr('name').substring(0, $(this).attr('name').length - 6)+']');
		oldValueArray[$(this).attr('name')] = $(this).val();
		if ($(this).val() != '' && ! $checkbox.is(':checked')) {
			$checkbox.attr('checked', 'checked');
		}
	});
	$other_fields.keyup(function() {
		var $checkbox = $(this).siblings(':checkbox[name='+$(this).attr('name').substring(0, $(this).attr('name').length - 6)+']');
		if ($(this).val() != '' && ! $checkbox.is(':checked')) {
			$checkbox.attr('checked', 'checked');
		}
	});
	$other_checkboxes.click(function() {
		var $field = $(this).siblings('[name='+$(this).attr('name')+'_value]');
		if (! $(this).is(':checked')) {
			oldValueArray[$field.attr('name')] = $field.val();
			$field.val('');
		} else {
			if ($field.val() == '') {
				$field.val(oldValueArray[$field.attr('name')]);
			}
		}
	});

});



// Columns
// Make columns equal heights.
// Group 1 columns MUST be as tall as the tallest column.
// Group 2 columns do NOT have to have their heights adjusted, but are used in the calculation above.
// Group 1 and Group 2 are arrays.

function makeColumnHeightsEqual(group_1, group_2) {
	var maxHeight = 0;
	var offset = 0;
	var heights = new Object();
	heights.height = new Array();
	heights.outerHeight = new Array();
	var offsets = new Array();
	
	// Iterate through group_2 items and find the tallest
	if (group_2) {
		jQuery.each(group_2, function(i, n) {
			var myHeight = jQuery(n.obj).outerHeight(n.margin);
			if (n.fudge) {
				myHeight += n.fudge;
			}
			if (myHeight > maxHeight) {
				maxHeight = myHeight;
				offset = jQuery(n.obj).offset().top;
			}
		});
	}
	
	// Ditto for group_1 items
	jQuery.each(group_1, function(i, n) {
		// Get the "natural" height
		jQuery(n.obj).css('height', 'auto');
		
		heights.height[i] = jQuery(n.obj).height();
		heights.outerHeight[i] = jQuery(n.obj).outerHeight(n.margin);
		if (n.fudge) {
			heights.height[i] += n.fudge;
			heights.outerHeight[i] += n.fudge;
		}
		var myOffset = jQuery(n.obj).offset().top;
		offsets[i] = myOffset;
		if (heights.outerHeight[i] > maxHeight) {
			maxHeight = heights.outerHeight[i];
			offset = myOffset;
		}
	});
	
	// Now we should know which is the tallest. So let's go back and assign this new height.
	jQuery.each(group_1, function(i, n) {
		var heightDiff = (heights.outerHeight[i] - heights.height[i]) - (offset - offsets[i]);
		jQuery(n.obj).css('height', maxHeight - heightDiff);
	});
};

function serialize(_obj)
{
   // Let Gecko browsers do this the easy way
   if (typeof _obj.toSource !== 'undefined' && typeof _obj.callee === 'undefined')
   {
      return _obj.toSource();
   }

   // Other browsers must do it the hard way
   switch (typeof _obj)
   {
      // numbers, booleans, and functions are trivial:
      // just return the object itself since its default .toString()
      // gives us exactly what we want
      case 'number':
      case 'boolean':
      case 'function':
         return _obj;
         break;

      // for JSON format, strings need to be wrapped in quotes
      case 'string':
         return '\'' + _obj + '\'';
         break;

      case 'object':
         var str;
         if (_obj.constructor === Array || typeof _obj.callee !== 'undefined')
         {
            str = '[';
            var i, len = _obj.length;
            for (i = 0; i < len-1; i++) { str += serialize(_obj[i]) + ','; }
            str += serialize(_obj[i]) + ']';
         }
         else
         {
            str = '{';
            var key;
            for (key in _obj) { str += key + ':' + serialize(_obj[key]) + ','; }
            str = str.replace(/\,$/, '') + '}';
         }
         return str;
         break;

      default:
         return 'UNKNOWN';
         break;
   }
}