
(function($){

	var container = null;
	var opts = null;
	var preSpan = '<span class="glossary" id="glossary_#">';
	var postSpan = '</span>';
	var definitionPopup = null;
	
 	$.fn.glossary = function(options) {
 		opts = $.extend({}, $.fn.glossary.defaults, options);
 		
 	 	return this.each(function() {
			container = $(this);
 	 		// load the glossary details
 	 		if (opts.glossary) {
 	 			applyGlossary(container);
 	 		}
 	 		applyHover(container);

 	 	});
 	};
 	
 	function applyGlossary(_container) {
 		// iterate through the contents of the container
 		if (!_container) {
 			_container = container;
 		}
 		$_container = $(_container);

		if (!$_container.hasClass('sIFR-replaced')
			&& !$_container.hasClass('glossary_term')
 			&& _container.tagName != 'A'
 		) {
 			if ($_container.contents().length) {
 				$_container.contents().each(function(idx, el) {
 					applyGlossary(el);
 				});
 			} else if ($_container.text().length
 					   && $_container.text() != "\n "
 			) {
 				// see if we can match the terms in the glossary
 				var text = $_container.text();
 				var textLength = text.length;
 				$(opts.glossary).each(function(idx, item) {
 					var start = 0;
 					var regexp = new RegExp(/\W/);
 					while ((tidx = text.toLowerCase().indexOf(item.term, start)) >= 0) {
 						var openSpan = text.indexOf('<span', tidx);
 						var closeSpan = text.indexOf('</span>', tidx);
 						if (((openSpan == -1 && closeSpan == -1) || (openSpan >= 0 && openSpan <= closeSpan))
 							&& (tidx == 0 || regexp.test(text.substr(tidx-1, 1))) 
 							&& (tidx + item.term.length == text.length || regexp.test(text.substr(tidx + item.term.length, 1))) )
 						{
	 						var termPreSpan = preSpan.replace('#', item.id);
	 						text = text.substr(0, tidx)
	 							 + termPreSpan 
	 							 + text.substr(tidx, item.term.length) 
	 							 + postSpan 
	 							 + text.substr(tidx + item.term.length);
	 						start += termPreSpan.length + postSpan.length;
 						}
 						start += tidx + item.term.length;
 					}
 				});
 				if (textLength != text.length) {
 					$_container.replaceWith(text);
 				}
 			}
 		}
 	};

 	function applyHover(el) {
		el.find('.glossary').hover(
			showDefinition
		  , hideDefinition
		);
 	}
 	
 	function showDefinition(event) {
 		if (!definitionPopup) {
 			createDefinitionPopup();
 		}
 		$_target = $(event.target);
 		var idx = $_target.attr('id').substr(9);
 		var content = getDefinition(idx) + '... <a rel="glossary_item_' + idx + '" href="education/glossary.html#glossary_item_' + idx + '">Learn more</a>';
 		definitionPopup.find('.definition_content').html(content);
 		// get position for this element
 		offset = $_target.offset();
 		definitionPopup.show();
 		definitionPopup.css({
 			'top': (offset.top - definitionPopup.outerHeight())
 		  , 'left': offset.left
 		});
 		definitionPopup.find('a').click(function(e) {
			var term = $('#' + e.target.rel);
			if (term.length && !term.next().is(':visible')) {
				term.click();
			}
 		});
 	};
 	
 	function getDefinition(idx) {
 		i = 0;
 		while (i < opts.glossary.length) {
 			if (opts.glossary[i].id == idx) {
 				return opts.glossary[i].definition;
 			}
 			i++;
 		}
 		return '';
 	}
 	
 	function hideDefinition(el) {
 		definitionPopup.hide();
 	};
 	
 	function createDefinitionPopup() {
 		definitionPopup = $(
 			'<div id="definition_wrapper"><div id="definition_popup">'
 		  + '<img src="images/glossary_popup_header.png" width="174" height="12" alt="What does this mean?" />'
 		  + '<div class="definition_content"></div><div class="arrow"></div></div></div>'
 		);
 		$('body').append(definitionPopup);
 		definitionPopup.hover(
 			function() {
 		 		definitionPopup.show();
 			}
 		  , function() {
 		 		definitionPopup.hide();
 			}
 		);
 	};
 	
 	/**
 	 *
 	 * Plugin defaults
 	 *
 	 */
 	$.fn.glossary.defaults = {
 		'glossary': [] 		
 	};
 	
})(jQuery);
