/**
 * jQuery Glossary Plugin v1.0
 *
 * Copyright (c) 2009 Gerry Vandermaesen, Morris & Chapman
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 */
(function($) {
	var glossaryId = 1;
	$.fn.glossary = function(options) {
		var alphabet = 'abcdefghijklmnopqrstuvwxyz', numbers = '0123456789', alphanum = alphabet + numbers, mapping = {}, labels = [];
		options = $.extend({
			groups: ['a-e', 'f-j', 'k-o', 'p-t', 'u-z', '0-9_'],
			labels: { '0-9_': '#' },
			disableEmptyTabs: true
		}, options);
		options.groups = options.groups || $.merge(alphabet.split(''), ['0-9']);
		$.each(options.groups, function(i, group) {
			var chars = group.toLowerCase();
			$.each(chars.match(/.-./g) || [], function(j, match) {
				var parts = match.split('-', 2);
				chars = chars.replace(match, alphanum.substring(alphanum.indexOf(parts[0]), alphanum.indexOf(parts[1]) + 1));
			});
			$.each(chars.split(''), function(j, char) {
				mapping[char] = i;
			});
			labels.push(options.labels[group] || group);
		});
		return this.each(function() {
			var sorted = [], reverse = {}, disabledTabs = [];
			$.each(options.groups, function() {
				sorted.push([]);
			});
			$(this).find('dt').each(function() {
				var dt = $(this).clone(true), dd = $(this).nextAll('dd:first').clone(true), id;
				var term = dt.html().replace(/(<.*?>|^\s+|\s+$)/g, '').replace(/\s{2,}/g, ' ');
				var k = term.charAt(0).toLowerCase();
				if (typeof mapping[k] === 'undefined') {
					k = '_';
				}
				if (typeof mapping[k] !== 'undefined') {
					id = 'ui-glossary' + glossaryId + '-panel' + (mapping[k] + 1) + '-term' + (sorted[mapping[k]].length + 1);
					dt.prepend('<a name="' + id + '"></a>')
					sorted[mapping[k]].push({ dt: dt, dd: dd });
					reverse[term] = { id: id, tab: mapping[k] };
				}
			});
			var container = $('<div class="ui-glossary" />');
			var tabs = $('<ul />').appendTo(container);
			$.each(options.groups, function(i, group) {
				var id = 'ui-glossary' + glossaryId + '-panel' + (i + 1);
				$('<li><a href="#' + id + '">' + labels[i] + '</a></li>').appendTo(tabs);
				var panel = $('<div id="' + id + '" />').appendTo(container);
				var dl = $('<dl />').appendTo(panel);
				$.each(sorted[i], function() {
					this.dt.appendTo(dl);
					this.dd.find('.ui-glossary-link').each(function() {
						var term = $(this).attr('title') || $(this).html().replace(/(<.*?>|^\s+|\s+$)/g, '').replace(/\s{2,}/g, ' '), link;
						if (typeof reverse[term] !== 'undefined') {
							link = $('<a href="#' + reverse[term].id + '" class="ui-glossary-link" title="' + term + '">' + $(this).html() + '</a>').click(function() {
								container.tabs('select', reverse[term].tab);
							});
							$(this).replaceWith(link);
						}
					}).end().appendTo(dl);
				});
				if (sorted[i].length === 0) {
					disabledTabs.push(i);
				}
			});
			$(this).replaceWith(container);
			container.tabs();
			if (options.disableEmptyTabs) {
				container.data('disabled.tabs', disabledTabs);
			}
			glossaryId++;
		});
	};
})(jQuery);
