﻿/**
* @author alexander.farkas
* @version 1.3
*/
(function($) {
	$.widget('ui.checkBox', {
		_init: function() {
			var that = this,

				opts = this.options,

				toggleHover = function(e) {
					if (this.disabledStatus) {
						return false;
					}
					that.hover = (e.type == 'focus' || e.type == 'mouseenter');
					that._changeStateClassChain();
				};
			if (!this.element.is(':radio,:checkbox')) {
				return false;
			}
			this.labels = $([]);

			this.checkedStatus = false;
			this.disabledStatus = false;
			this.hoverStatus = false;

			this.radio = (this.element.is(':radio'));

			this.visualElement = $('<span />')
				.addClass(this.radio ? 'ui-radio' : 'ui-checkbox')
				.bind('mouseenter.checkBox mouseleave.checkBox', toggleHover)
				.bind('click.checkBox', function(e) {
					that.element[0].click();
					//that.element.trigger('click');
					return false;
				});

			if (opts.replaceInput) {
				this.element
					.addClass('ui-helper-hidden-accessible')
					.after(this.visualElement[0])
					.bind('usermode', function(e) {
						(e.enabled &&
	                        that.destroy.call(that, true));
					});
			}

			this.element
				.bind('click.checkBox', $.bind(this, this.reflectUI))
				.bind('focus.checkBox blur.checkBox', toggleHover);

			if (opts.addLabel) {
				//ToDo: Add Closest Ancestor
				this.labels = $('label[for=' + this.element.attr('id') + ']')
					.bind('mouseenter.checkBox mouseleave.checkBox', toggleHover);
			}

			this.reflectUI({ type: 'initialReflect' });
		},
		_changeStateClassChain: function() {
			var stateClass = (this.checkedStatus) ? '-checked' : '',
				baseClass = 'ui-' + ((this.radio) ? 'radio' : 'checkbox') + '-state';

			stateClass += (this.disabledStatus) ? '-disabled' : '';
			stateClass += (this.hover) ? '-hover' : '';

			if (stateClass) {
				stateClass = baseClass + stateClass;
			}

			function switchStateClass() {
				var classes = this.className.split(' '),
					found = false;
				$.each(classes, function(i, classN) {
					if (classN.indexOf(baseClass) === 0) {
						found = true;
						classes[i] = stateClass;
						return false;
					}
				});
				if (!found) {
					classes.push(stateClass);
				}

				this.className = classes.join(' ');
			}

			this.labels.each(switchStateClass);
			this.visualElement.each(switchStateClass);
		},
		destroy: function(onlyCss) {
			this.element.removeClass('ui-helper-hidden-accessible');
			this.visualElement.addClass('ui-helper-hidden');
			if (!onlyCss) {
				var o = this.options;
				this.element.unbind('.checkBox');
				this.visualElement.remove();
				this.labels
					.unbind('.checkBox')
					.removeClass('ui-state-hover ui-state-checked ui-state-disabled');
			}
		},

		disable: function() {
			this.element[0].disabled = true;
			this.reflectUI({ type: 'manuallyDisabled' });
		},

		enable: function() {
			this.element[0].disabled = false;
			this.reflectUI({ type: 'manuallyenabled' });
		},

		toggle: function(e) {
			this.changeCheckStatus((this.element.is(':checked')) ? false : true, e);
		},

		changeCheckStatus: function(status, e) {
			if (e && e.type == 'click' && this.element[0].disabled) {
				return false;
			}
			this.element.attr({ 'checked': status });
			this.reflectUI(e || {
				type: 'changeCheckStatus'
			});
		},

		propagate: function(n, e, _noGroupReflect) {
			if (!e || e.type != 'initialReflect') {
				if (this.radio && !_noGroupReflect) {
					//dynamic
					$(document.getElementsByName(this.element.attr('name')))
						.checkBox('reflectUI', e, true);
				}
				return this._trigger(n, e, {
					options: this.options,
					checked: this.checkedStatus,
					labels: this.labels,
					disabled: this.disabledStatus
				});
			}
		},

		reflectUI: function(elm, e) {
			var oldChecked = this.checkedStatus,
				oldDisabledStatus = this.disabledStatus;
			e = e ||
            	elm;

			this.disabledStatus = this.element.is(':disabled');
			this.checkedStatus = this.element.is(':checked');

			if (this.disabledStatus != oldDisabledStatus || this.checkedStatus !== oldChecked) {
				this._changeStateClassChain();

				(this.disabledStatus != oldDisabledStatus &&
					this.propagate('disabledChange', e));

				(this.checkedStatus !== oldChecked &&
					this.propagate('change', e));
			}

		}
	});
	$.ui.checkBox.defaults = {
		replaceInput: true,
		addLabel: true
	};

})(jQuery);

