/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
({

    /*
    * We do the event attachment programatically to avoid
    * adding DOM handlers when no actions are provided.
    */
    EVENT_DISPATCH: { 
        'keydown'   : 'onkeydown',
        'mouseover' : 'onmouseover',
        'mouseout'  : 'onmouseout',
        'focus'     : 'onfocus',
        'blur'      : 'onblur',
        'press'     : 'onclick'
    },

    /*
     * In order to not attach all declared dom handlers automatically, we just
     * attach the ones that have an action to be dispatched 
    */
    initializeHandlers: function (cmp) {
        var htmlButton = cmp.find('button');
        var htmlAttr   = htmlButton.get('v.HTMLAttributes');
        var dispatcher = cmp.getEventDispatcher();

        for (var e in this.EVENT_DISPATCH) {
            if (dispatcher[e]) {
                htmlAttr[this.EVENT_DISPATCH[e]] = cmp.getReference('c.' + e);
            }
        }
    },

    /*
    * See initializeHandlers comments, then:
    * In order to add handlers dynamically, we need to override the original function.
    * We need to programatically add the aura handler and the DOM event.
    */
    addHandler: function (cmp, handlerParams) {
        var eventName = handlerParams.eventName;
        var htmlEventName = this.EVENT_DISPATCH[eventName];
        $A.assert(htmlEventName, 'Type of event not supported');

        var valueProvider = handlerParams.valueProvider;
        var actionExpression = handlerParams.actionExpression;
        var htmlButton = cmp.find('button');
        var originalAddHandler = htmlButton.addHandler;
        var htmlAttr = htmlButton.get('v.HTMLAttributes');

        // Set the attribute so the aura:html will add the dom handler
        htmlAttr[htmlEventName] = cmp.getReference('c.' + eventName);
        // Set the attribute back so if the button is render will attach the handlers correctly
        htmlButton.set('v.HTMLAttributes', htmlAttr);

        // Call the origin addHandler method  with the given attributes
        originalAddHandler.call(cmp, eventName, valueProvider, actionExpression);

    },
    catchAndFireEvent: function (cmp, event, eventName) {
        if (eventName === 'press' && $A.util.getBooleanValue(cmp.get("v.stopPropagation"))) {
            $A.util.squash(event);
        }

        if ($A.util.getBooleanValue(cmp.get("v.disabled"))) {
            return event.preventDefault();
        }

        cmp.getEvent(eventName).fire({"domEvent": event});
    },

    getClassList: function (cmp) {
        var vclass = cmp.get('v.class');
        var stateful = cmp.get('v.stateful');
        if(stateful) {
            return this.updateStatefulClasses(cmp);
        } else if (vclass) {
            return vclass;
        } else {
            return '';
        }
    },

    updateStatefulClasses: function (cmp) {
        var classList = [];
        var selected = cmp.get('v.selected');
        var vClass = cmp.get('v.class');

        if(vClass) {
            classList.push(vClass);
        }

        if(selected) {
            classList.push('is-selected');
        } else {
            classList.push('not-selected');
        }

        return classList.join(' ');
    }
})// eslint-disable-line semi

@@ -758,17 +758,16 @@
 PATCH: %7B
- 
 %0A       
@@ -1117,17 +1117,16 @@
 spatched
- 
 %0A    */%0A
@@ -1297,24 +1297,47 @@
 tcher = cmp.
+getConcreteComponent().
 getEventDisp

fix initializeHandlers for components extending ui:button @bug W-2889973@