// JavaScript Document
(function(jQuery) {	
	var hash = [], index = 0, classes = ['tsc_normal', 'tsc_checked', 'tsc_semi'];
	jQuery.fn.threeStateCB = function(options) {
		jQuery(this).each(function(i) {
			var parent		= jQuery(this).children('h3');
			var children	= jQuery(this).children('ul').children('li');
			
			if (options) {
				hash.push({
					checkedOnLoad:	options.checked || false,
					checked:		options.checked || false,
					fireChildEvent:	true
				});
				if (options.fireChildEvent != 'undefined') hash[i].fireChildEvent = options.fireChildEvent;
			} else {
				hash.push({
					checkedOnLoad:	false,
					checked:		false,
					fireChildEvent: true
				});
			}
			
			var cls = (hash[i].checkedOnLoad) ? 'tsc_checked' : 'tsc_normal';
			var test = hash[i];
			
			var cb =	jQuery('<span></span>').uniqueId().addClass('threeStateCheckbox').addClass(cls).
						append(jQuery('<input type="hidden" />').val(parent.text()));
			cb.bind('click', function() {
				var index = jQuery(this).attr('id').split('-')[1]-1;
				var cls, state, val;
				
				if (jQuery(this).hasClass(classes[0])) {
					cls		= classes[1];
					state	= 'checked';
				} else {
					cls		= classes[0];
					state	= 'unchecked';
				}
				val = jQuery(this).children('input').val();
				
				jQuery(this).removeClass().addClass('threeStateCheckbox').addClass(cls);
				
				jQuery(this).parent().children('ul').children('li').each(function() {
					var el = jQuery(this).children('.threeStateCheckbox');
					var cVal = el.children('input').val();
					var fire = hash[index];
					
					el.removeClass().addClass('threeStateCheckbox').addClass('inner_cb').addClass(cls);
					if (hash[index].fireChildEvent) el.trigger('stateChange', [state, cVal, state, val]);
				});
				
				jQuery(this).trigger('stateChange', [state, val]);
			});
			
			cb.bind('mouseenter', function() {
				var cls;
				
				if (jQuery(this).hasClass(classes[0])) cls = classes[0];
				else if (jQuery(this).hasClass(classes[1])) cls = classes[1];
				else cls = classes[2];
				
				jQuery(this).addClass(cls+'_hover');
			});
			
			cb.bind('mouseleave', function() {
				var cls;
				
				if (jQuery(this).hasClass(classes[0])) cls = classes[0];
				else if (jQuery(this).hasClass(classes[1])) cls = classes[1];
				else cls = classes[2];
				
				jQuery(this).removeClass(cls+'_hover');
			});
			
			cb.prependTo(jQuery(this));
			children.each(function() {
				var span = jQuery(this).children('span');
				var subcb =	jQuery('<span></span>').uniqueId('jqThreeStateInner').addClass('threeStateCheckbox').addClass(cls).
							addClass('inner_cb').append(jQuery('<input type="hidden" />').val(jQuery(this).text()));	
							
				span.addClass('threeStateSpan').bind('click', function() {
					subcb.trigger('click');
				});
				
				subcb.bind('click', function() {
					var cls, parentClass = classes[2], allChecked = true, allUnChecked = true, state, parentState = 'semi';
					
					if (jQuery(this).hasClass(classes[0])) {
						cls = classes[1];
						state = 'checked';
					} else {
						cls = classes[0];
						state = 'unchecked';
					}
					var val = jQuery(this).children('input').val();
					
					jQuery(this).removeClass().addClass('threeStateCheckbox').addClass('inner_cb').addClass(cls);
					
					jQuery(this).parent().parent().children('li').each(function() {
						if (jQuery(this).children('.threeStateCheckbox').hasClass(classes[0])) {
							allChecked = false;
						} else {
							allUnChecked = false;
						}
					});
					
					if (allChecked) {
						parentClass = classes[1];
						parentState = 'checked';
					} else if (allUnChecked) {
						parentClass = classes[0];
						parentState = 'unchecked';
					}
					var parentVal = jQuery(this).parent().parent().parent().children('.threeStateCheckbox').children('input').val();
					
					jQuery(this).trigger('stateChange', [state, val, parentState, parentVal]);
					
					jQuery(this).parent().parent().parent().children('.threeStateCheckbox').removeClass().
					addClass('threeStateCheckbox').addClass(parentClass).trigger('stateChange', [parentState, parentVal]);
				});
			
				subcb.bind('mouseenter', function() {
					var cls;
					
					if (jQuery(this).hasClass(classes[0])) cls = classes[0];
					else if (jQuery(this).hasClass(classes[1])) cls = classes[1];
					else cls = classes[2];
					
					jQuery(this).addClass(cls+'_hover');
				});
				
				subcb.bind('mouseleave', function() {
					var cls;
					
					if (jQuery(this).hasClass(classes[0])) cls = classes[0];
					else if (jQuery(this).hasClass(classes[1])) cls = classes[1];
					else cls = classes[2];
					
					jQuery(this).removeClass(cls+'_hover');
				});
				
				subcb.prependTo(jQuery(this));
			});
		});
		
		index++;
		
		return this;
	};
})(jQuery);

jQuery.fn.uniqueId = function(prefix, clobber) {
	if (prefix == null) prefix = "jqThreeState";
	if (jQuery.fn.uniqueId.index == null) {
		jQuery.fn.uniqueId.index = new Object();
		jQuery.fn.uniqueId.index[prefix] = 0;
	} else if (jQuery.fn.uniqueId.index[prefix] == null) {
		jQuery.fn.uniqueId.index[prefix] = 0;
	}
	return this.each(function(){
		if (!this.id || clobber) this.id = prefix + "-" + (++jQuery.fn.uniqueId.index[prefix]);
	});
}
