/**********************************************************************************
 **
 **              jQuery Tristate Checkbox Plugin
 **              version: 1.0
 **
 **              Dual licensed under the MIT and GPL licenses:
 **              http://www.opensource.org/licenses/mit-license.php
 **              http://www.gnu.org/licenses/gpl.html
 **
 **              author: Jeff Leombruno
 **              creation date: 09.20.2011
 **              dependencies: jQuery v1.6 or higher
 **
 **              This file contains the functionality for implementing 3 state checkboxes.
 **              Inspired by:
 **                   http://code.google.com/p/jquery-tristate-checkbox/
 **                   http://css-tricks.com/13467-indeterminate-checkboxes/
 **
 **********************************************************************************/
 
(function ($) {
	$.fn.tristate = function (options) {

		var config = {
			selector: $(this).selector,
			checked: null,
			container: null,
			siblings: null,
			allowAllSelection: true
		};
		var opts = $.extend(config, options);

		var isWinSafari = false;
		if (window.devicePixelRatio && (navigator.appVersion.indexOf("Win") != -1))
			isWinSafari = true;

		return this.each(function () {
			var obj = $(this);

			var triState = function () {

				var pub = {};

				pub.init = function () {
					if (!config.allowAllSelection) {
						$(config.selector + ' > li > input').click(function () {
							return false;
						});
						$(config.selector + ' > li > input').bind('tricheck', function () {
							$(this).prop({
								indeterminate: true,
								checked: false
							});
							if (isWinSafari)
								$(this).parent().addClass('ind');
						});
						$(config.selector + ' > li > input:checked').each(function () {
							$(this).prop({
								indeterminate: true,
								checked: false
							});
							if (isWinSafari)
								$(this).parent().addClass("ind");
						});
					}
					$('input[type="checkbox"].tri', obj).change(function (e) {
						if (!config.allowAllSelection && $(this).is(config.selector + ' > li > input'))
							return false;

						config.checked = $(this).prop("checked")
						config.container = $(this).parent();
						config.siblings = config.container.siblings();

						config.container.find('input[type="checkbox"].tri').prop({
							indeterminate: false,
							checked: config.checked
						});

						if (isWinSafari)
							config.container.find('input[type="checkbox"].tri').parent().removeClass("ind");

						pub.checkSiblings(config.container);
					});
					// run checkSiblings for every checked checkbox when the page loads
					$('input[type=checkbox].tri:checked', obj).each(function () {
						config.checked = true;
						pub.checkSiblings($(this).parent());
					});
				};

				pub.checkSiblings = function (el) {
					var parent = el.parent().closest('li.tri');
					var all = false;

					el.siblings().each(function () {
						return all = ($(this).children('input[type="checkbox"].tri').prop("checked") === config.checked);
					});

					if (all && config.checked) {
						var c = parent.children('input[type="checkbox"].tri');
						c.prop({
							indeterminate: false,
							checked: config.checked
						});
						if (isWinSafari)
							c.parent().removeClass("ind");
						c.trigger("tricheck");
						pub.checkSiblings(parent);
					} else if (all && !config.checked) {
						var c = parent.children('input[type="checkbox"].tri');
						c.prop("checked", config.checked);
						c.prop("indeterminate", (parent.find('input[type="checkbox"].tri:checked').length > 0));
						if (isWinSafari) {
							if (parent.find('input[type="checkbox"].tri:checked').length > 0)
								c.parent().addClass("ind");
							else
								c.parent().removeClass("ind");
						}
						pub.checkSiblings(parent);
					} else {
						el.parents("li").children('input[type="checkbox"].tri').prop({
							indeterminate: true,
							checked: false
						});
						if (isWinSafari)
							el.parents("li").children('input[type="checkbox"].tri').parent().addClass("ind");
					}
				};

				return pub;

			} ();

			triState.init();
			triState.checkSiblings(obj);


		});
	};
})(jQuery);


