/**

 * @author cakers

 * 

 * Typical Usage Example:

 *     Handlers need to be added to the navigation links in a certain fragment of HTML with a specific ID.

 * 

 * HTML:

 *     <ul id="cruiseNavigation">

 *         <li><a href="http://disn...">Link 1<a></li>

 *         <li><a href="http://disn...">Link 2<a></li>

 *         <li><a href="http://disn...">Link 3<a></li>

 *     </ul>

 * 

 * JS:

 *     WDPRO.ASDW.CodeRegistry.register('cruiseNavigation', function(div){

 *         var links = YAHOO.util.Dom.getChildren(div);

 *         YAHOO.util.Event.on(links, 'click', function(e){

 *             coolAjaxFunction(this.href);

 *             YAHOO.util.Event.preventDefault(e);

 *         });

 *     });

 * 

 * Notes:

 *     The first parameter passed can be an array of IDs. The supplied function will be executed for each ID.

 *     The second parameter passed can be an array of functions. The functions will be executed in order for each ID found.

 *     The HTMLElement that matches the ID is passed to the supplied functions as the first parameter.

 *     The function is called in the context of the HTMLElement. "this" in the function will refer to the HTMLElement.

 * 

 * 

 * Advanced Usage:

 * 

 * JS:

 *     WDPRO.ASDW.CodeRegistry.register({selector: 'form.validate'}, function(frm){

 * 

 * 

 * 

 */



(function(){



    var L   = YAHOO.lang,

        D   = YAHOO.util.Dom,

        Q   = YAHOO.util.Selector.query,

        AS;



    window.WDPRO = window.WDPRO || {};

    AS = WDPRO.ASDW = WDPRO.ASDW || {};

    

    AS.CodeRegistry = {

        

        placeholderClass: 'placeholder',

        

        _registry: {},

        

        register: function(elementSelector, applyFunction){

            var objEntry, objSelector, intSelector, maxSelector, intFn, maxFn, strKey;

            

            if (!L.isArray(elementSelector)) {

                elementSelector = [elementSelector];

            }

            if (!L.isArray(applyFunction)) {

                applyFunction = [applyFunction];

            }

            

            for ( intSelector = 0, maxSelector = elementSelector.length; intSelector < maxSelector; intSelector++ ) {

                objSelector = elementSelector[intSelector];

                if (L.isString(objSelector)) {

                    objSelector = {id: objSelector};

                }

                if ('id' in objSelector) {

                    strKey = 'id:' + objSelector.id;

                } else if ('selector' in objSelector) {

                    strKey = 'selector:' + objSelector.selector;

                } else {

                    //invalid object - does not have "id" nor "selector"

                    continue;

                }

                

                for ( intFn = 0, maxFn = applyFunction.length; intFn < maxFn; intFn++ ) {

                    objEntry = this._registry[strKey];

                    if (objEntry) {

                        objEntry.functions.push(applyFunction[intFn]);

                    } else {

                        objEntry = {

                            functions: [applyFunction[intFn]]

                        };

                        if ('id' in objSelector){

                            objEntry.id = objSelector.id;

                        } else {

                            objEntry.selector = objSelector.selector;

                        }

                        this._registry[strKey] = objEntry;

                    }

                }

            }

        },

        

        fire: function(element){

            var foundElement, foundElements, strKey, arrFn, intFn, maxFn, testFn, objEntry, strSelector, intEl, maxEl;



            for (strKey in this._registry) {

                foundElements = [];

                objEntry = this._registry[strKey];

                if ('id' in objEntry) {

                    strSelector = objEntry.id;

                    

                    if (element) {

                        testFn = function(el){

                            return el.id && el.id === strSelector;

                        };

                        if (testFn(element)) {

                            foundElement = element;

                        } else {

                            foundElement = D.getElementsBy(testFn, '*', element)[0];

                        }

                    } else {

                        foundElement = document.getElementById(strSelector);

                    }

                    if (foundElement) {

                        foundElements.push(foundElement);

                    }

                    

                } else {

                    strSelector = objEntry.selector;

                    if (element){

                        foundElements = Q(strSelector, element);



                        // Query doesn't include the root element

                        if (YAHOO.util.Selector.test(element, strSelector)) {

                            foundElements.push(element);

                        }

                    } else {

                        foundElements = Q(strSelector);

                    }

                }

                

                for ( intEl = 0, maxEl = foundElements.length; intEl < maxEl; intEl++ ) {

                    foundElement = foundElements[intEl];

                    

                    if (D.hasClass(foundElement, this.placeholderClass)) {

                        continue;

                    }

                    

                    arrFn = objEntry.functions;

                    for ( intFn = 0, maxFn = arrFn.length; intFn < maxFn; intFn++ ) {

                        arrFn[intFn].call(foundElement, foundElement);

                    }

                }

            }

        }

    };

    

    YAHOO.util.Event.onDOMReady(function(){

        AS.CodeRegistry.fire.call(AS.CodeRegistry);

    });

    

})();

