/**
 * 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);
			});
		});
	});		
};

/**
 * Builds pull quote divs assuming you've wrappted your content with a span with the class: pullquote-left or pullquote-right
 */
$.fn.pullQuote = function() {
	return this.each(function() {
		var contents = $.trim($(this).html());
		var firstCharacterCode = contents.charCodeAt(0);
		if (firstCharacterCode < 65 || firstCharacterCode > 96) {
			contents = '&hellip; ' + contents;
		};
		
		var lastCharacter = contents.charAt(contents.length - 1);
		if ("?!.".search(lastCharacter) < 0) {
			contents = contents + ' &hellip;';
		};
		var $parent = $(this).parent();
		var $pullquote = $('<div>').attr('class', $(this).attr('class')).html(contents);
		$parent.before($pullquote);
	});		
};

/**
 * 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');
	};
	
	var	tablePrep = function() {
		$('table tr:odd').addClass('alt');
		$('table tr').find('> :last').addClass('last');
   	};
	
	listPrep();
	tablePrep();
};     

// various mobile functions
var mobileSetup = function() {
	
	//menu toggle button
	$('#mobile-menu-toggle').click(function(event) {
		event.preventDefault();
		$('#nav').slideToggle();
	});
	
	//menu close button
	$('#mobile-menu-close').click(function(event) {
		event.preventDefault();
		$('#nav').slideUp();
	});
	
	// directory results tables:
	// make first and last name appear side by side, as if on one line
	// make email & phone number cells emulate buttons, even when not links/containing phone extensions
	$('#content table.directory-results tr:first').hide();
	$('#content table.directory-results tr td:first-child').addClass('inline');
	$('#content table.directory-results tr td:nth-child(2)').addClass('inline');
	$('#content table.directory-results tr td:nth-child(4)').addClass('button');
	$('#content table.directory-results tr td:nth-child(5)').addClass('button');
	
	if (window.innerWidth < 640) {
		var myHeight = $('.event #nav-sub').height();
		$('.event #content').css('padding-top', myHeight + 10);
	}
};


// Currently used for campus events
function pop(PopPage) {
	newWin = window.open(PopPage,"poppage", "resizable=no,scrollbars=yes,status=no,toolbar=no,location=no,width=750,height=600,left=200,top=20")
}

/**
 * Adds the active class to the currently viewed week
*/
function colorWeek () {		
	if ($('#tabs .active .week').size()) {
		
		// Get the first day of the active week
	 	var weekstart = $('.event #content dl').data('weekstart');
	
		// Find the first day of the active row (week), then add .active-week class to the row
		$('.event #content-sub tr').each(function (index, tr) {
			if($(tr).find('td:first').text() == weekstart || $(tr).find('td:first a').text == weekstart) {
				$(tr).addClass('active-week');
			}
		});
	}
}

/**
 * Contols filtering of entries based on categories
*/
var calendar = {
	
	/**
	 * Sets cookie to remember calendar filter state
	 * @param {Object} Unordered list of checkboxes to filter entries
	 */
	 setCookie: function($filter) {
		var checkedString = "";
		var checkedArray = new Array();

		// Goes through checked checkboxes and adds them to an array to put in a cookie
		$filter.find('input[type=checkbox]:checked').each(function(index, obj) {
				checkedArray[index] = $(this).attr('name');
		});
	
		checkedString = checkedArray.join("|");
		
		// Set Cookie expiration date
		var date = new Date();
		date.setTime(date.getTime()+(7*24*60*60*1000*365)); // Cookie will last for 7 years
		var expires = date.toGMTString();

		// Set cookie
		document.cookie = "filter="+checkedString+"; expires="+expires+"; path=/;";
	},
	
	/**
	 * Gets the cookie
	 * @param {String} c_name Name of the cookie we are looking for
	 * @returns String of contents if cookie is found, otherwise NULL
	 */
	getCookie: function (c_name) {
		if (document.cookie.length > 0) {
			c_start = document.cookie.indexOf(c_name);
			if (c_start != -1) {
				c_start = document.cookie.indexOf(c_name + "=");
				c_start = c_start + c_name.length+1;
				c_end = document.cookie.indexOf(";",c_start);
				if (c_end==-1) c_end = document.cookie.length;

				var return_string = unescape(document.cookie.substring(c_start,c_end));
				
				return return_string;
			} else {
				return null;
			}
		}
	},
	
	/**
	 * Initialize the filter on page load with a stored cookie 
	 * @param {Object} Unordered list of checkboxes to filter entries
	 * @param {Object} Definition List of entries
	*/
	initFilterWithCookie: function ($filter, $entries) {
	
		// Initialize the filter cookie
		var categories = calendar.getCookie('filter');
				
		// Check all boxes if no cookie
		if (!categories) {
			$filter.find('input[type=checkbox]').attr('checked', true);
		}
		
		// Put cookie with stored input names into an array 
		else {
			var categoriesArray = categories.split("|");
			if (categoriesArray == null) categoriesArray.push(categories);

			// Go through array and turn on corresponding categories, display events
			jQuery.each(categoriesArray, function(i, name) {
				$filter.find('input[name='+name+']').attr('checked', true);
			});
		};
	},
	
	/**
  	 * Toggle the dt element containing the date to hide/show if events are shown for the date
	 * @param {Object} Definition List of entries
	*/
	entryDateToggle: function ($entries) {
		$entries.find('dt a').each(function () {
			
			// For each dt, if there is at least one event shown, set display_dt to true
			display_dt = false;
			$entries.find('dd[data-day='+$(this).attr('name')+']').each(function () {
				if($(this).css('display') == 'block') {
					display_dt = true;
				}
			});
			
			// Toggle show the dt if there are events, hide if not
			if(!display_dt) {
				$(this).parent('dt').hide();
			}
			else {
				$(this).parent('dt').show();
			}
		});
	},

	/**
	 * Given a filter and entries, toggle the events
	 * @param {Object} Unordered list of checkboxes to filter entries
	 * @param {Object} Definition List of entries
	*/
	toggleEvents: function ($filter, $entries) {
		$entries.find('dd').hide();
		$filter.find('input[type=checkbox]:checked').each(function () {
			$entries.find('.'+$(this).attr('name')).show();
		});
		
		// If there are no other events in the day after filtered, hide the dt element (date)
		calendar.entryDateToggle($entries);
		
		// Set cookie with filter
		calendar.setCookie($filter);
	},
	
	/**
	 * Listens to the 'All' checkbox and toggles all checkboxes either on or off
	 * @param {Object} Unordered list of checkboxes to filter entries
	 * @param {Object} Definition List of entries
	*/
	toggleAll: function ($filter, $entries) {
		$filter.find('.all input[type=checkbox]').click(function () {
			if($(this).is(':checked')) {
				// Check all filter checkboxes
				$filter.find('input:checkbox').attr('checked', true);
			}
			else {
				// Uncheck all filter checkboxes
				$filter.find('input:checkbox').attr('checked', false);
			}
			calendar.toggleEvents($filter, $entries);
		});
	},
	
	/**
	 * Initialize the calendar
	*/
    init: function () {
		
		// Distinguish the calendar checkbox filters and dl entries
		$filter = $('.event .category-filter');
		$entries = $('.event #content dl');
		
		// Initialize the filter with a stored cookie, if it exists
		calendar.initFilterWithCookie($filter, $entries);
		
		// Toggle All events
		calendar.toggleAll($filter, $entries);
		
		// Toggle the events on page load
		calendar.toggleEvents($filter, $entries);

		// Toggle Events on click
		$filter.find('li input').click(function () {
			calendar.toggleEvents($filter, $entries);
		});
	}
}

/**
 * Rebuilds a select list into an unordered list
 */
$.fn.rebuildSelect = function () {	

	// Builds a hidden field with the selected default value, and field name
	var buildHiddenField = function ($ul) {
		// Get default value if it exists
		if($ul.find('.selected').size()) {
			value = $ul.find('.selected').attr('data-value');
		}
		else {
			value = $ul.find('li:first').attr('data-value');			
		}
		
		name = $ul.attr('data-name');
		
		$ul.after('<input type="hidden" name="'+name+'" value="'+value+'"/>');
	}
	
	// Reset the hidden field with value
	var resetHiddenField = function ($li) {
		
		// Get default value if it exists
		value = $li.find('.selected').attr('data-value');
		name = $ul.attr('data-name');
				
		$('input[name='+name+']').val(value);
	}
	
	// Rewrite the select element into a ul element
	var rewriteSelect = function ($select) {	
				
		// Get default value	
		var selected_value = $select.val();
		
		// Rewrite current Select element into a Ul element
		$select.find('option').each(function (index, option) {
			
			// Create the li elements
			$li = $(document.createElement("li"));
			$li.text($(option).text());
			$li.attr('data-value', $(option).attr('value'));
			
			// Add the 'selected' class to the default select value
			if (selected_value == $(option).attr('value')) {
				$li.addClass('selected');
			}
			$(option).replaceWith($li);
		});

		// Create the ul element
		var $ul = $(document.createElement("ul"));
		$ul.html($select.html());
		
		// Set default selected value
		if(!$ul.find('.selected').size()) {
			$ul.find('li:first').addClass('selected');
		}
		
		// Set UL's class to Select's class attribute
		$ul.addClass($select.attr('class'));
		$ul.attr('data-name', $select.attr('name'));
		$select.replaceWith($ul);
		
		return $ul;
	}
	
	// Initialize
	var $ul = rewriteSelect($(this).children('select'));
	buildHiddenField($ul);
	
	$ul.find('li').click(function () {
		
		// If UL is active, when an li is clicked reset the hidden field 
		// and hide the other list items.
		if ($ul.parent().hasClass('selectbox-active')) {
			$ul.parent().removeClass('selectbox-active');
			$ul.find('li.selected').removeClass('selected');
			$(this).addClass('selected');
			resetHiddenField($ul);
			$ul.find('li').hide();

			// Show the selected list element
			$ul.find('li.selected').show();
		}
		
		// If the selectbox is active, show LIs and make UL active
		else {
			$ul.parent().addClass('selectbox-active');
			$ul.find('li').show();

			// Add the check icon to the selected li
			$ul.find('li.selected');
		}
	});
}

$(document).ready(function() {
	placeholder();
	$('div.image-left, div.image-right').imageWidth();
	$('span.pullquote-left, span.pullquote-right').pullQuote();
	$('#directory #browse .rebuildSelect').rebuildSelect();

	markupPrep();
	mobileSetup();
	
	//  Innerfade setup for all generic pages
	$('.innerFade').innerFade({
		indexContainer: ".slider-controls ul",
		prevLink: ".slider-controls .previous",
		nextLink: ".slider-controls .next",
		timeout: 7500
	}); 
	
	$('.toggle-link').toggle(
		function () {
			$(this).siblings().slideDown();
		}, 
		function () {
			$(this).siblings().slideUp();
		}
	);
	
	colorWeek();
	calendar.init();
});
