/*
 * Copyright (C) 2012 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.
 */
({
    /**
     * Adds an event handler for every DOM event for which this input has a Aura-equivalent handler
     */
    addDomEvents : function(component) {
        var events = this.getHandledDOMEvents(component);
        for (var event in events) {
            this.addDomHandler(component, event);
        }
    },

    /**
     * Adds an event handler for the given DOM event
     */
    addDomHandler : function(component, event) {
        var el = component.getElement();
        $A.util.on(el, event, this.domEventHandler);
    },

    /**
     * Handles a DOM-level event and throws the Aura-level equivalent.
     *
     * This same function is used for all DOM->Aura event wireup on components, which has multiple benefits:
     * - decreased memory footprint
     * - no need to protect against a handler being added more than once
     * - no need to track event->handler function mappings for later removal
     */
    domEventHandler : function (event) {
        var element = event.target;
        var htmlCmp = $A.componentService.getRenderingComponentForElement(element);
        var component = htmlCmp.getAttributes().getComponentValueProvider().getConcreteComponent();
        var helper = component.getDef().getHelper();

        // extended components can do some event processing before the Aura event gets fired
        helper.preEventFiring(component, event);

        // fire the equivalent Aura event
        helper.fireEvent(component, event, helper);
    },
    
    /**
     * Fire the equivalent Aura event for DOM one.
     * This can be overridden by extended component
     */
     fireEvent : function (component, event, helper) {
        var e = component.getEvent(event.type);
        helper.setEventParams(e, event);
        e.fire();
     },

    /**
     * Returns the list of valid DOM events this component may handle
     *
     * NOTE: this currently assumes that interactive.cmp only handles events that are valid DOM events.
     * We may wish to change this to an explicit list at some point.
     */
    getDomEvents : function(component) {
        return component.getDef().getAllEvents();
    },

    /**
     * Returns an object whose keys are the lower-case names of DOM-equivalent Aura events for which this component currently has handlers
     */
    getHandledDOMEvents : function(component){
        var ret = {};
        var handledEvents = component.getHandledEvents();
        var domEvents = this.getDomEvents(component);

        if(domEvents){
            for(var i=0,len=domEvents.length; i<len; i++){
                var eventName = domEvents[i].toLowerCase();
                if (handledEvents[eventName]) {
                    ret[eventName] = true;
                }
            }
        }
        return ret;
    },

    /**
     * This method is intended to be overridden by extended components to do event related stuff before the event gets fired.
     * For example, input component uses this method to update its value if the event is the "updateOn" event.
     */
    preEventFiring : function(component, event){
    },
    
    /**
     * Set event's parameters with the value from DOM event.
     * The event's parameter name should be the same as the property name in DOM event.
     */
    setEventParams: function(e, DOMEvent) {
        // set parameters if there is any
        var attributeDefs = e.getDef().getAttributeDefs();
        var params = {};
        for (var key in attributeDefs) {
            if (key === "domEvent") {
                params[key] = DOMEvent;
            } else {
                params[key] = DOMEvent[key];
            }
        };
        e.setParams(params);
    }
})

@@ -2087,36 +2087,32 @@
 helper);%0A    %7D,%0A
-    
 %0A    /**%0A     * 
@@ -3704,13 +3704,9 @@
  %7D,%0A
-    
 %0A
+
     
@@ -3884,16 +3884,17 @@
 ntParams
+ 
 : functi
@@ -4276,17 +4276,441 @@
 arams);%0A
-
     %7D
+,%0A%0A    /**%0A     * Toggle a component's offline state.%0A     * @param %7BComponent%7D component The component being toggled.%0A     * @param %7BBoolean%7D offline True to set offline state; false for online state.%0A     */%0A    setOffline: function(component, offline) %7B%0A        component.setValue('v.disabled', offline);%0A        var fn = offline ? component.addClass : component.removeClass;%0A        fn.call(component, 'offline');%0A    %7D%0A
 %0A%7D)%0A

Define setOffline() in ui:interactive's helper.js