(function ($) {

	// Selectall
	var Selectall = function (element, options) {
		this.element = $(element);

		this.options = $.extend(true, {
			semichecked: 'semi-checked',

			// Callbacks
			select: $.noop
		}, options);

		this.init();
	};

	Selectall.prototype = {

		init: function () {
			var that = this;

			this.checkboxes = $('input[type=checkbox][name^='+ this.element.attr('name') +']')
				.not(this.element)
				.on('click.selectall', function (e) {
					that.check();
				});

			this.element.on('click.selectall', function (e) {
				$(this).removeClass(that.options.semichecked);
				that.checkboxes.not(':disabled').prop('checked', $(this).is(':checked'));

				that.options.select.apply(this, [that.checkboxes]);
			});
		},

		check: function () {
			var checked = this.checkboxes.filter(function () {
				return $(this).is(':checked');
			});

			if (checked.length) {
				if (checked.length == this.checkboxes.length) {
					this.element
						.removeClass(this.options.semichecked)
						.prop('checked', true);
				} else {
					this.element
						.addClass(this.options.semichecked)
						.prop('checked', false);
				}
			} else {
				this.element
					.removeClass(this.options.semichecked)
					.prop('checked', false);
			}

			this.options.select.apply(this, [this.checkboxes]);
		}

	};

	$.fn.selectall = function (options) {
		return this.each(function() {
			if (!$(this).data('selectall')) {
				var selectall = new Selectall(this, options);
				$(this).data('selectall', selectall);
			}
		});
	};

})(jQuery);