(function($){
	
	$.fn.extend({
		checked : function(bool){
			var node = this.get(0);
			
			if (typeof(bool) == "undefined"){
				return node.checked;
			}
			
			switch (typeof(bool)) {
				case "boolean" :
					node.checked = bool;
					break;
				case "number" :
					node.checked = (bool == 0 ? false : true);
					break;
				case "string" : 
					node.checked = (bool == "false" ? false : true);
					break;
				default :
					break;
			}
			return this;
		}
	});
	
	$.CheckboxManager = function(params){
	
		var 
			_self = this, 
			_settings = $.extend({},this.defaults,params),
			_checkboxes = [],
			_count = 0;
			
		//start:events
		// RL - switched from live event to delegated event
		$(document).delegate("click", {
			".j_cb" : function(e) {
				e.preventDefault();
				while (e.target.className.indexOf(_settings.wrapperClass) == -1){
					e.target = e.target.parentNode;
				}
				_toggle(_checkboxes[$(e.target).data('Id')]);		
			}
		}).keyup(function(e){
			if (e.target.parentNode && e.target.parentNode.className && e.target.parentNode.className.indexOf(_settings.wrapperClass) != -1){
				if (e.keyCode == 32){
					e.preventDefault();
					_toggle(_checkboxes[$(e.target).parent().data('Id')]);	
				}
			}
		});

		// RL - removed keyup event for now
		
		//end:events
		
		//start:public
		/* 
		* use to instantiate new $.Checkbox objects
		* input is jQuery extended input element
		* opts can be anything in $.CheckboxManager.defaults execpt wrapperClass,
		* which needs to remain constant across $.Checkbox objects for event delegation
		*/
		this.addCheckbox = function(input, opts){
			var 
				params = $.extend({},_settings,opts),
				checkbox = new $.Checkbox(input, params);
				
			checkbox.Id = _count;
			_count++;
			
			checkbox.parent.data("Id", checkbox.Id);
			_checkboxes.push(checkbox);
			
			return checkbox;
		};	
		
		this.toggle = function($input){
			_toggle(_checkboxes[$input.parent().data("Id")]);
		};
		//end:public
		
		//start:private
		function _toggle(checkbox){
			
			if (checkbox.input.checked() == true){
				checkbox.input.checked(false);
				checkbox.parent.removeClass(checkbox.settings.checkedClass);
			} else {
				checkbox.input.checked(true);
				checkbox.parent.addClass(checkbox.settings.checkedClass);
			}
			
			checkbox.input.focus();
			checkbox.settings.changeCallback();
		}
		//end:private
	};
	$.CheckboxManager.prototype = {
		defaults : {
			wrapperClass : "j_cb",
			focusedStates : 1,
			changeCallback : function(){},
			checkedClass : "j_cb_checked",
			focusedState : 0, //use only if there is a separate skinned focused state
			focusedClass : "j_cb_focused"
		}
	};
	
	//use $.CheckboxManager.addCheckbox() to create $.Checkbox objects
	$.Checkbox = function(input, params){
		
		var _self = this;
		this.settings = params;
		this.input = input;
		this.input.wrap('<span class="'+params.wrapperClass+'"></span>');
		this.parent = input.parent();
		
		if (this.input.checked()){
			this.parent.addClass(this.settings.checkedClass);
		}
		
		if (params.focusedState){
			input.focus(function(){
				_self.parent.addClass(params.focusedClass);
			}).blur(function(){
				_self.parent.removeClass(params.focusedClass);
			});
		}
		
	};
})(jQuery);




