/**
 * Publisher Version 1.00.1
 *
 */

/**
 *  Adds methods for adding and removing of subscribers from a ECMAScript
 *  Object.
 *
 *  This is a wrapper. This class should NOT be instantiated.
 *
 *	@param Object any ECMAScript object that does not have an addSubscriber
 *	@return Object the orginal object passed in.
 */
function Publisher() {

        var publisher = function(el){

            // Private subscribers
            var subscribers = [];
            
            /*
             * Make sure the element being passes in is valid
             */
            if(((typeof el !== "function") && (typeof el !== "object")) || el === null){
                throw "Publisher can only wrap Objects. Type Error. " + el;
            }

            /*
             * Make sure that we are not adding anything that could be destructive
             * to another Library or user.
             * Better to abort than hose someone.
             */
            if(el.addSubscriber !== undefined){
                    return null;
            }

            var findSubscriptionList = function(listname){
                    for(var index in subscribers) {
                            if(subscribers[index][0] === listname){
                                    return subscribers[index];
                            }
                    }
                    return null;
            };


            /**
             * Adds a subscriber to a list to be triggered when the action specified
             * is triggered.
             * @param String action name
             * @param Object/Function callback
             * @param String return value
             *
             * @return String specified return value
             */
            el.addSubscriber=function(action, callback, returnValue){
                if(( (typeof callback!=="function") && (typeof callback!=="object") ) || callback===null){
                    throw "addSubscriber(callback is not of type Object) [\""+action+"\"]["+callback+"]";
                }
                var list = findSubscriptionList(action);
                if(list === null){
                    list = [action];
                    subscribers.push(list);
                    if(el[action] !== undefined && el[action] !== null){
                        list.push(el[action]);
                    }
                    el[action] = function(event){
                        var l = list;
                        for(var i = 1; i < l.length; i++){
                            l[i](el, event);
                        }
                        returnValue = (returnValue === "false") ? false : returnValue;
                        returnValue = (returnValue === "true") ? true : returnValue;
                        return returnValue;
                    };
                }
                list.push(callback);
            };

            /**
             * Removes an instance of a subscriber or every instance of a subscriber.
             *
             * @param Object Subscriber
             * @param String Action - the name of the action where the subscriber is attached
             * @param Boolean (Optional) If all instances are to be removed, default false
             */
            el.removeSubscriber = function(subscriber, action, allInstances){
                    var list = findSubscriptionList(action);

                    if(list === null){
                            return false;
                    }

                    if(allInstances === undefined || allInstances === false){
                            list.removeInstanceOf(subscriber);
                    }
                    else {
                            list.removeAllInstancesOf();
                    }
                    return true;
            };

            return el;
        };

        System.publish = publisher;
}

