/*!
 * jQuery UI Button - v1.10.4
 * http://jqueryui.com
 *
 * Copyright 2014 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/button/
 */
define([
    'jquery',
    'jquery-ui-modules/core',
    'jquery-ui-modules/widget'
], function ($, undefined) {

    var lastActive,
        baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
        typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
        formResetHandler = function () {
            var form = $(this);
            setTimeout(function () {
                form.find(":ui-button").button("refresh");
            }, 1);
        },
        radioGroup = function (radio) {
            var name = radio.name,
                form = radio.form,
                radios = $([]);
            if (name) {
                name = name.replace(/'/g, "\\'");
                if (form) {
                    radios = $(form).find("[name='" + name + "']");
                } else {
                    radios = $("[name='" + name + "']", radio.ownerDocument)
                        .filter(function () {
                            return !this.form;
                        });
                }
            }
            return radios;
        };

    $.widget("ui.button", {
        version: "1.10.4",
        defaultElement: "<button>",
        options: {
            disabled: null,
            text: true,
            label: null,
            icons: {
                primary: null,
                secondary: null
            }
        },
        _create: function () {
            this.element.closest("form")
                .unbind("reset" + this.eventNamespace)
                .bind("reset" + this.eventNamespace, formResetHandler);

            if (typeof this.options.disabled !== "boolean") {
                this.options.disabled = !!this.element.prop("disabled");
            } else {
                this.element.prop("disabled", this.options.disabled);
            }

            this._determineButtonType();
            this.hasTitle = !!this.buttonElement.attr("title");

            var that = this,
                options = this.options,
                toggleButton = this.type === "checkbox" || this.type === "radio",
                activeClass = !toggleButton ? "ui-state-active" : "";

            if (options.label === null) {
                options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
            }

            this._hoverable(this.buttonElement);

            this.buttonElement
                .addClass(baseClasses)
                .attr("role", "button")
                .bind("mouseenter" + this.eventNamespace, function () {
                    if (options.disabled) {
                        return;
                    }
                    if (this === lastActive) {
                        $(this).addClass("ui-state-active");
                    }
                })
                .bind("mouseleave" + this.eventNamespace, function () {
                    if (options.disabled) {
                        return;
                    }
                    $(this).removeClass(activeClass);
                })
                .bind("click" + this.eventNamespace, function (event) {
                    if (options.disabled) {
                        event.preventDefault();
                        event.stopImmediatePropagation();
                    }
                });

            // Can't use _focusable() because the element that receives focus
            // and the element that gets the ui-state-focus class are different
            this._on({
                focus: function () {
                    this.buttonElement.addClass("ui-state-focus");
                },
                blur: function () {
                    this.buttonElement.removeClass("ui-state-focus");
                }
            });

            if (toggleButton) {
                this.element.bind("change" + this.eventNamespace, function () {
                    that.refresh();
                });
            }

            if (this.type === "checkbox") {
                this.buttonElement.bind("click" + this.eventNamespace, function () {
                    if (options.disabled) {
                        return false;
                    }
                });
            } else if (this.type === "radio") {
                this.buttonElement.bind("click" + this.eventNamespace, function () {
                    if (options.disabled) {
                        return false;
                    }
                    $(this).addClass("ui-state-active");
                    that.buttonElement.attr("aria-pressed", "true");

                    var radio = that.element[0];
                    radioGroup(radio)
                        .not(radio)
                        .map(function () {
                            return $(this).button("widget")[0];
                        })
                        .removeClass("ui-state-active")
                        .attr("aria-pressed", "false");
                });
            } else {
                this.buttonElement
                    .bind("mousedown" + this.eventNamespace, function () {
                        if (options.disabled) {
                            return false;
                        }
                        $(this).addClass("ui-state-active");
                        lastActive = this;
                        that.document.one("mouseup", function () {
                            lastActive = null;
                        });
                    })
                    .bind("mouseup" + this.eventNamespace, function () {
                        if (options.disabled) {
                            return false;
                        }
                        $(this).removeClass("ui-state-active");
                    })
                    .bind("keydown" + this.eventNamespace, function (event) {
                        if (options.disabled) {
                            return false;
                        }
                        if (event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER) {
                            $(this).addClass("ui-state-active");
                        }
                    })
                    // see #8559, we bind to blur here in case the button element loses
                    // focus between keydown and keyup, it would be left in an "active" state
                    .bind("keyup" + this.eventNamespace + " blur" + this.eventNamespace, function () {
                        $(this).removeClass("ui-state-active");
                    });

                if (this.buttonElement.is("a")) {
                    this.buttonElement.keyup(function (event) {
                        if (event.keyCode === $.ui.keyCode.SPACE) {
                            // TODO pass through original event correctly (just as 2nd argument doesn't work)
                            $(this).click();
                        }
                    });
                }
            }

            // TODO: pull out $.Widget's handling for the disabled option into
            // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
            // be overridden by individual plugins
            this._setOption("disabled", options.disabled);
            this._resetButton();
        },

        _determineButtonType: function () {
            var ancestor, labelSelector, checked;

            if (this.element.is("[type=checkbox]")) {
                this.type = "checkbox";
            } else if (this.element.is("[type=radio]")) {
                this.type = "radio";
            } else if (this.element.is("input")) {
                this.type = "input";
            } else {
                this.type = "button";
            }

            if (this.type === "checkbox" || this.type === "radio") {
                // we don't search against the document in case the element
                // is disconnected from the DOM
                ancestor = this.element.parents().last();
                labelSelector = "label[for='" + this.element.attr("id") + "']";
                this.buttonElement = ancestor.find(labelSelector);
                if (!this.buttonElement.length) {
                    ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
                    this.buttonElement = ancestor.filter(labelSelector);
                    if (!this.buttonElement.length) {
                        this.buttonElement = ancestor.find(labelSelector);
                    }
                }
                this.element.addClass("ui-helper-hidden-accessible");

                checked = this.element.is(":checked");
                if (checked) {
                    this.buttonElement.addClass("ui-state-active");
                }
                this.buttonElement.prop("aria-pressed", checked);
            } else {
                this.buttonElement = this.element;
            }
        },

        widget: function () {
            return this.buttonElement;
        },

        _destroy: function () {
            this.element
                .removeClass("ui-helper-hidden-accessible");
            this.buttonElement
                .removeClass(baseClasses + " ui-state-active " + typeClasses)
                .removeAttr("role")
                .removeAttr("aria-pressed")
                .html(this.buttonElement.find(".ui-button-text").html());

            if (!this.hasTitle) {
                this.buttonElement.removeAttr("title");
            }
        },

        _setOption: function (key, value) {
            this._super(key, value);
            if (key === "disabled") {
                this.element.prop("disabled", !!value);
                if (value) {
                    this.buttonElement.removeClass("ui-state-focus");
                }
                return;
            }
            this._resetButton();
        },

        refresh: function () {
            //See #8237 & #8828
            var isDisabled = this.element.is("input, button") ? this.element.is(":disabled") : this.element.hasClass("ui-button-disabled");

            if (isDisabled !== this.options.disabled) {
                this._setOption("disabled", isDisabled);
            }
            if (this.type === "radio") {
                radioGroup(this.element[0]).each(function () {
                    if ($(this).is(":checked")) {
                        $(this).button("widget")
                            .addClass("ui-state-active")
                            .attr("aria-pressed", "true");
                    } else {
                        $(this).button("widget")
                            .removeClass("ui-state-active")
                            .attr("aria-pressed", "false");
                    }
                });
            } else if (this.type === "checkbox") {
                if (this.element.is(":checked")) {
                    this.buttonElement
                        .addClass("ui-state-active")
                        .attr("aria-pressed", "true");
                } else {
                    this.buttonElement
                        .removeClass("ui-state-active")
                        .attr("aria-pressed", "false");
                }
            }
        },

        _resetButton: function () {
            if (this.type === "input") {
                if (this.options.label) {
                    this.element.val(this.options.label);
                }
                return;
            }
            var buttonElement = this.buttonElement.removeClass(typeClasses),
                buttonText = $("<span></span>", this.document[0])
                    .addClass("ui-button-text")
                    .html(this.options.label)
                    .appendTo(buttonElement.empty())
                    .text(),
                icons = this.options.icons,
                multipleIcons = icons.primary && icons.secondary,
                buttonClasses = [];

            if (icons.primary || icons.secondary) {
                if (this.options.text) {
                    buttonClasses.push("ui-button-text-icon" + (multipleIcons ? "s" : (icons.primary ? "-primary" : "-secondary")));
                }

                if (icons.primary) {
                    buttonElement.prepend("<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>");
                }

                if (icons.secondary) {
                    buttonElement.append("<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>");
                }

                if (!this.options.text) {
                    buttonClasses.push(multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only");

                    if (!this.hasTitle) {
                        buttonElement.attr("title", $.trim(buttonText));
                    }
                }
            } else {
                buttonClasses.push("ui-button-text-only");
            }
            buttonElement.addClass(buttonClasses.join(" "));
        }
    });

    $.widget("ui.buttonset", {
        version: "1.10.4",
        options: {
            items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
        },

        _create: function () {
            this.element.addClass("ui-buttonset");
        },

        _init: function () {
            this.refresh();
        },

        _setOption: function (key, value) {
            if (key === "disabled") {
                this.buttons.button("option", key, value);
            }

            this._super(key, value);
        },

        refresh: function () {
            var rtl = this.element.css("direction") === "rtl";

            this.buttons = this.element.find(this.options.items)
                .filter(":ui-button")
                .button("refresh")
                .end()
                .not(":ui-button")
                .button()
                .end()
                .map(function () {
                    return $(this).button("widget")[0];
                })
                .removeClass("ui-corner-all ui-corner-left ui-corner-right")
                .filter(":first")
                .addClass(rtl ? "ui-corner-right" : "ui-corner-left")
                .end()
                .filter(":last")
                .addClass(rtl ? "ui-corner-left" : "ui-corner-right")
                .end()
                .end();
        },

        _destroy: function () {
            this.element.removeClass("ui-buttonset");
            this.buttons
                .map(function () {
                    return $(this).button("widget")[0];
                })
                .removeClass("ui-corner-left ui-corner-right")
                .end()
                .button("destroy");
        }
    });

});
