/**
 * @author alexander.farkas
 */
(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();
				};

            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) {
				    (!this.disabledStatus && that.toggle.call(that, e));
				    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);
