/**
 * Resizes floated image containers to the size of the image
 */
$.fn.imageWidth = function(threshold) {
	/**
	 * Function takes a jquery object and a css property (called dimension) and determines how many pixels the item is
	 * @param {jQuery Object} $item The jQuery object we're looking at
	 * @param {String} dimension The CSS property name to look for
	 * @returns The width or height of the CSS property with 'px' removed
	 * @type Number
	 */
	var	determineDimension = function($item, dimension) {
		$item = $($item);
		if ($item.css(dimension)) {
			return parseInt($item.css(dimension).replace('px', ''), 10);
		} else {
			return 0;
		};
		return false;
	};
	
	var	resizeImage = function($image, $parent, $container) {
		// Determine the width of the image along with borders and padding
		var imageWidth = $image.width();
		var paddingLeft = determineDimension($image, 'padding-left');
		var paddingRight = determineDimension($image, 'padding-right');
		var borderLeft = determineDimension($image, 'border-left-width');
		var borderRight = determineDimension($image, 'border-right-width');

		// Calculate total edge (padding and border) width and the total width (edge and image)
		var edgeWidth = paddingLeft + paddingRight + borderLeft + borderRight;
		var totalWidth = imageWidth + edgeWidth;

		// Determine parent width
		var parentWidth = $parent.width();

		// If the image is greater then the threshold times the parent width resize the image and the container width
		// Otherwise set the image left's div to the size of the image plus the edge
		if ((threshold * parentWidth) <= totalWidth) {
			var revisedWidth = parentWidth * threshold;
			var revisedImageWidth = revisedWidth - edgeWidth;

			$image.width(revisedImageWidth);
			$container.width(parseInt(revisedWidth, 10));
		} else {
			$container.width(totalWidth);
		};
	};

	return this.each(function() {
		// Threshold is the maximum width an image plus its border and padding can be 
		// in relation to its parent container
		var threshold = (threshold) ? threshold : 2/3;

		// Find image within div
		var $image = $('img', $(this));
		var $parent = $(this).parent();
		var $container = $(this);

		$image.each(function(index) {
			resizeImage($image, $parent, $container);
			$(this).load(function() {			
				resizeImage($image, $parent, $container);
			});
		});
	});		
};

/**
 * Makes all children with the selected container the same height.
 * Uses min-height, except for IE6 where height is used instead.
 */
$.fn.same_height = function() {
	return this.each(function() {
		tallest_height = 0;
		
		$(this).children().each(function(index) {
			tallest_height = ($(this).height() > tallest_height) ? $(this).height() : tallest_height;
		});
		
		if ($.browser.msie == true && $.browser.version <= 6) {
			$(this).children().css('height', tallest_height);
		} else {
			$(this).children().css('min-height', tallest_height);
		};
	});		
};

/**
 * Makes the placeholder attribute on input items useful by emulating the behavior
 */ 
var placeholder = function() {
	if ('placeholder' in document.createElement('input')) return this;
	
	$('input[placeholder]').each(function(index) {
		$(this).val($(this).attr('placeholder')).addClass('placeholder')
			.focus(function() {
				if ($(this).val() === $(this).attr('placeholder')) {
			        $(this).val('').removeClass('placeholder');
				}
			})
			.blur(function() {
				if ($(this).val() === ''){
					$(this).val($(this).attr('placeholder')).addClass('placeholder');
				}
			});
	});
};

/**
 * Adds the class 'last' to the last list items, and the last table item in a row. 
 * Also adds alt class to odd table rows.
 */
var markupPrep = function() {
	var listPrep = function() {
		$('> li:last', 'ul, ol').addClass('last');
		$('> li:first', 'ul, ol').addClass('first');
	};
	
	var	tablePrep = function() {
		$('table tr:odd').addClass('alt');
		
		$('table tr').each(function () {
			$(this).find(':last').addClass('last');
		});
	};
	
	listPrep();
	tablePrep();
};

/**
 * Initialize innerfade on Home Page and Slide Shows
 * @author Jason Gillespie
*/

var innerfade = function () {
	$('.home #feature .tab-content').innerFade({
		'indexContainer': "#feature .tab-controls",
		'animate': false
	});
	
	$('.home #feature-sub .tab-content').innerFade({
		'indexContainer': "#feature-sub .tab-controls",
		'animate': false
	});
	
	$('.home #our-students ul.tab-content').innerFade({
		'indexContainer': "#our-students ul.tab-controls",
		'animate': false
	});
	
	$('#slideshow-content > ul').innerFade ({
		'indexContainer': "#slideshow-controls > ul",
		'animate': false
	});
}

/**
 * Displays a random child of a parent
 * @author Jason Gillespie
*/

$.fn.showRandomChild = function () {
	return this.each(function () {
		var children_count = $(this).children().hide().size();
		var n = Math.floor(Math.random() * children_count) + 1;
		$(this).children(':nth-child('+n+')').show();
	});
}

/**
 * Filter handles the filtering of items by checking for existing filters
 * @author Wes Baker
 * @version 1.0
 */
var filter = {
	debug: false,
	
	/**
	 * Creates the Filter event handler
	 */
	listener: function(){
		$('#filters li').live('click', function(event) {
			event.preventDefault();
			
			// Toggles the active class
			$list_item = $(this);
			$list_item.toggleClass('active');
			
			// Show/hide programs
			filter.filter();
		});
		
		
		// Add hover state to program div
		$('#programs div.program').live('mouseover mouseout', function (event) {
			if (event.type == 'mouseover') {
				$(this).addClass('hover');
			}
			if (event.type == 'mouseout') {
				$(this).removeClass('hover');
			}
		});
	},
	
	/**
	 * Get list of currently active filters
	 * @returns Two arrays in one object with the current active filters
	 * @type Object
	 */
	active: function(){
		var filters = {
			degree: [],
			interest: []
		};
		
		$('#filter-degree li.active').each(function(index) {
			filters.degree.push($(this).attr('data-filter'));
		});
		$('#filter-interest li.active').each(function(index) {
			filters.interest.push($(this).attr('data-filter'));
		});
		
		return filters;
	},
	
	/**
	 * Given a string of items separated by a |, divides them into an array. 
	 * This will turn strings into single item arrays.
	 * @param {String} filter_string The filter string from the data properties on the programs
	 * @returns An array of filters as strings
	 * @type Arrary
	 */
	split_array: function(filter_string) {
		var filters = [];
		if (filter_string.match('|')) {
			filters = filter_string.split('|');
		} else {
			filters = [filter_string];
		};
		
		return filters;
	},
	
	/**
	 * Filters out items that are supposed to be hidden
	 */
	filter: function(){
		current_filters = filter.active();
		
		$('#programs div.program').each(function(index) {
			// Remove the half class from everything
			$(this).removeClass('half');
			
			pagination.show_all();
			
			// Get the categories
			var program_interest_filters = filter.split_array($(this).attr("data-interest"));
			var program_degree_filters = filter.split_array($(this).attr("data-degree"));
			
			/**
			 * Determine whether the program fits in with the categories
			 * 
			 * Rule set:
			 * - If no filters are set then show everything
			 * - If filters are set in only one category (degree or interest) then the show 
			 * 	 everything that fits into that category
			 * - If filters are set in both categories, show items that have both categories
			 */
			var interest = true; 
			if (current_filters.interest.length) {
				interest = false;
				for (var interest_current=0; interest_current < program_interest_filters.length; interest_current++) {
					interest = ($.inArray(program_interest_filters[interest_current], current_filters.interest) > -1) ? true : interest;
				};
			};
			var degree = true;
			if (current_filters.degree.length) {
				degree = false;
				for (var degree_current=0; degree_current < program_degree_filters.length; degree_current++) {
					degree = ($.inArray(program_degree_filters[degree_current], current_filters.degree) > -1) ? true : degree;
				};
			};
			
			// Show the categories and whether is going to display
			if (filter.debug) {
				debug.group($.trim($(this).find('h1 span.degree').text()) + " in " + $.trim($(this).find('h1 span.name').text()));
					debug.info("Show?: " + (interest && degree));
					debug.group("Degree");
						debug.log("Categories: " + program_degree_filters);
						debug.log("Active Filters: " + current_filters.degree);
					debug.groupEnd();
					debug.group("Interest");
						debug.log("Categories: " + program_interest_filters);
						debug.log("Active Filters: " + current_filters.interest);
					debug.groupEnd();
				debug.groupEnd();
			};
			
			// Hide and show based upon the filters
			if ( ! interest || ! degree) {
				$(this).fadeOut();
			} else {
				$(this).fadeIn();
			};
		});	
	}
};

/**
 * Pages through the available programs
 */
var pagination = {
	/**
	 * Hides all of the blocks on load, also "half-hides" the beginning of the next set
	 */
	hide: function(){
		$('#programs div.program:gt(19)').hide();
		$('#programs div.program:gt(14)').slice(0, 5).addClass('half');
	},
	
	/**
	 * Updates the pagination on the more-bar
	 */
	update_pagination: function() {
		$('#more-bar .current').text($('#programs div.program:visible').size());
	},
	
	/**
	 * Shows the next set of programs
	 */
	show_more: function(){
		// Figure out where we're starting from
		var start_from = $('#programs div.program:visible:not(.half)').size() - 1;
		
		// Show the next fifteen
		$('#programs div.program:gt(' + start_from + ')').slice(0, 20).removeClass('half').show();
		
		// Half-show the next five
		$('#programs div.program:gt(' + (start_from + 20) + ')').slice(0, 5).addClass('half').show();
		
		// Update pagination
		pagination.update_pagination();
		
		// If there are no items left to show, hide the more-bar
		if ($('#programs div.program:visible:not(.half)').size() == $('#programs div.program').size()) {
			pagination.show_all();
		};
	},	
	
	/**
	 * Show all of the div.programs
	 */
	show_all: function() {
		$('#more-bar').hide();
		$('#programs div.program').removeClass('half').show();
	},
	
	/**
	 * Listen for clicks on the view-all link and the more link
	 */
	listen: function(){
		$('#more-bar .view-all a').click(function(event) {
			event.preventDefault();
			pagination.show_all();
		});
		$('#more-bar a.more').click(function(event) {
			event.preventDefault();
			pagination.show_more();
		});
	},
	
	/**
	 * Fire off the listeners and the intial hide function
	 */
	init: function(){
		pagination.listen();
		pagination.hide();
	}
};

/**
 * Toggle the quicklook lightbox window
 * @author Jason Gillespie
*/
var program = {
	quick_look: function(){
		$('a.quick-look').fancybox({
			'showCloseButton': false,
			'onComplete': function () {
				
				// Close lightbox
				$('#quicklook a#close').click(function (event) {
					event.preventDefault();
					$.fancybox.close();
				});
			}
		});
	},
	
	presets: function(){
			var aos = unescape(gup( 'aos' ));
			$("#filter-interest li[data-filter='"+aos.replace("'","\\'")+"']").find('a').trigger('click');

			var dt = unescape(gup( 'dt' ));
			var dt_array = dt.split('|');
			for (var i=0;i<dt_array.length;i++){
				$("#filter-degree li[data-filter='"+dt_array[i].replace("'","\\'")+"']").find('a').trigger('click');
			}
	},
	
	init: function(){
		this.quick_look();
		this.presets();
	}
}

/**
 * Toggles page sections up/down when clicking on the section's header
 *	@author Jason Gillespie
*/

$.fn.collapsible = function(options) {

	var listener = function ($collapsible, options) {
		$collapsible.find(options.header).css('cursor', 'pointer');
		
		$collapsible.find(options.header).click(function () {
			if ($collapsible.hasClass('active')) {
				$collapsible.removeClass('active');
				$collapsible.find(options.contents).slideUp('slow');
			}
			else {
				$collapsible.addClass('active');
				$collapsible.find(options.contents).slideDown('slow');
			}
		});
	}
	
	var prepare = function ($collapsible, options) {
		if(!$collapsible.hasClass('active')) {
			$collapsible.find(options.contents).hide();
		}
	}
	
	return this.each(function() {
		prepare($(this), options);
		listener($(this), options);
	});	
}

/**
 * Initialize flowplayer
 * @author Jason Gillespie
*/
var video = function () {
	if ($('#player').size() > 0) {
		flowplayer("player", "/js/flowplayer/flowplayer-3.2.6.swf");
	}
}

function calculateSameHeight (selector) {
	
	var tallest_height = 0;
	
	// Get tallest height
	$(selector).each(function () {
		if($(this).height() > tallest_height) {
			tallest_height = $(this).height() + parseInt($(this).css('padding-top')) + parseInt($(this).css('padding-bottom'));
		}
	});
			
	// Set tallest height
	$(selector).each(function () {
		if ($.browser.msie == true && $.browser.version <= 6) {
			$(this).css('height', tallest_height);
		} else {
			$(this).css('min-height', tallest_height);
		};
	});

}

/**
 * Highlight the nav item associated with the page
*/
function programDetailNav () {
	
	// Get last url segment
	var url_segments = window.location.pathname.split('/');
	
    /// Remove last segment if empty
    if (url_segments[url_segments.length-1] == '') {
        url_segments[url_segments.length-1] = 'index.php';
    }
	
	var last_url_segment = url_segments[url_segments.length - 1];
	
	// Initialize segments to compare
	var href_segments = '';
	var last_href_segments = '';
	
	$('#section-nav li a').each(function () {
		href_segments = $(this).attr('href').split('/');
		last_href_segment = href_segments[href_segments.length - 1];
		if (last_href_segment.search(last_url_segment) != -1) {
			$(this).parent().addClass('active');
		}
	});
}

function gup( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}

/**
 *  Checks for a <span>*</span> in each label
 *  and checks that the associated input is not empty
*/
function validate_required () {
	$('form').each(function () {
		$(this).submit(function () {
				var errors = false;
				var message = '<p class="error"><span>Sorry, there were errors in the form.  Please correct them and submit again.</span></p>';
				
				// Remove previous errors
				$('.error').remove();
				
				// Attach error messages
				$(this).find('label span').each(function () {
					var $input = $(this).parent('label').siblings('#'+$(this).parent('label').attr('for'));
					var $label = $input.siblings('label').clone();
					$label.find('span').remove();
					
					if ($input.val() == '') {
						$input.before('<span>Please enter your '+$label.text()+'</span><br/>');
						errors = true;
					}
				});
				
				if (errors) {
					$(this).prepend(message)
					return false;
				}	
			});
		})
}

$(document).ready(function() {

	markupPrep();
	placeholder();
	$('span.image-left, span.image-right').imageWidth();
	pagination.init();
	program.init();
	innerfade();
	video();
	programDetailNav();
	validate_required();
	
	$('#carousel').bxSlider();
	
	calculateSameHeight('#carousel .box-wrapper');
		
	// Pick a random image to show on the Home Page
	$('.home #random-image-pool').showRandomChild();
	$('#random-blurb').showRandomChild();
	
	// Collapse/Expand degree content on Admissions Page
	$('.admissions .degree').collapsible({
		'header': '.collapsible-header',
		'contents': '.collapsible-content'
	});

	// Collapse/Expand degree content on Tuition Page
	$('.tuition .degree').collapsible({
		'header': '.collapsible-header th',
		'contents': '.collapsible-content div'
	});
	
});

// Filter.listener is fired ahead of document.ready because it's using live() event delegation
filter.listener();

