/**
 * jQuery custom checkboxes
 * 
 * Copyright (c) 2008 Khavilo Dmitry (http://widowmaker.kiev.ua/checkbox/)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @version 1.3.0 Beta 1
 * @author Khavilo Dmitry
 * @mailto wm.morgun@gmail.com
**/

(function($){
	/* Little trick to remove event bubbling that causes events recursion */
	var CB = function(e) {
		if (!e) var e = window.event;
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	};
	
	$.fn.checkbox = function(options) {
		/* IE6 background flicker fix */
		try { document.execCommand('BackgroundImageCache', false, true); } catch (e) {}
		
		/* Default settings */
		var settings = {
			cls: 'jquery-checkbox',  /* checkbox  */
			empty: 'images/empty.png'  /* checkbox  */
		};
		
		/* Processing settings */
		settings = $.extend(settings, options || {});
		
		var handleState = function(object) {
			var checked = object.attr('checked');
			var disabled = object.attr('disabled');
			object.trigger( (disabled == 'disabled') ? 'disable' : 'enable');
			if (object.attr('type') == 'radio' && checked == 'checked') {
				$('input[name="' + object.attr('name') + '"]').trigger('uncheck');
			}
			object.trigger( (checked == 'checked') ? 'check' : 'uncheck');
		}
		
		/* Wrapping all passed elements */
		return this.each(function() {
			var ch = this; /* Reference to DOM Element*/
			//var $ch = addEvents(ch); /* Adds custom events and returns, jQuery enclosed object */
			var $ch = $(ch);
			
			/* Removing wrapper if already applied  */
			if (ch.wrapper) ch.wrapper.remove();
			
			/* Creating wrapper for checkbox and assigning "hover" event */
			ch.wrapper = $('<span class="' + settings.cls + '"><span class="mark"><img src="' + settings.empty + '" /></span></span>');
			ch.wrapperInner = ch.wrapper.children('span:eq(0)');
			ch.wrapper.hover(
				function(e) { ch.wrapperInner.addClass(settings.cls + '-hover');CB(e); },
				function(e) { ch.wrapperInner.removeClass(settings.cls + '-hover');CB(e); }
			);
			
			/* Wrapping checkbox */
			$ch.css({position: 'absolute', zIndex: -1, visibility: 'hidden'}).after(ch.wrapper);
			
			/* Ttying to find "our" label */
			var label = false;
			if ($ch.attr('id')) {
				label = $('label[for='+$ch.attr('id')+']');
				if (!label.length) label = false;
			}
			if (!label) {
				/* Trying to utilize "closest()" from jQuery 1.3+ */
				label = $ch.closest ? $ch.closest('label') : $ch.parents('label:eq(0)');
				if (!label.length) label = false;
			}
			/* Labe found, applying event hanlers */
			if (label) {
				label.hover(
					function(e) { ch.wrapper.trigger('mouseover', [e]); },
					function(e) { ch.wrapper.trigger('mouseout', [e]); }
				);
				label.click(function(e) { $ch.trigger('click',[e]); handleState($ch); $ch.triggerHandler('custom_click',[e]); CB(e); return false;});
			}
			ch.wrapper.click(function(e) { $ch.trigger('click',[e]); handleState($ch); $ch.triggerHandler('custom_click',[e]); CB(e); return false;});

			/* Remove onclick attribute and create custom_click event */
			var onclick = $ch.attr('onclick');
			if (onclick) {
				$ch.attr('onclick', null);
				$ch.bind('custom_click', new Function("e, " + onclick) );
			}

			$ch.click(function(e) { CB(e); });
			$ch.bind('disable', function() { ch.wrapperInner.addClass(settings.cls+'-disabled');}).bind('enable', function() { ch.wrapperInner.removeClass(settings.cls+'-disabled');});
			$ch.bind('check', function() { ch.wrapper.addClass(settings.cls+'-checked' );}).bind('uncheck', function() { ch.wrapper.removeClass(settings.cls+'-checked' );});
			
			/* Disable image drag-n-drop for IE */
			$('img', ch.wrapper).bind('dragstart', function () {return false;}).bind('mousedown', function () {return false;});
			
			/* Firefox antiselection hack */
			if ( window.getSelection ) ch.wrapper.css('MozUserSelect', 'none');
			
			/* Applying checkbox state */
			if ( ch.checked )  ch.wrapper.addClass(settings.cls + '-checked');
			if ( ch.disabled ) ch.wrapperInner.addClass(settings.cls + '-disabled');
		});
	}
})(jQuery);

