/*
    here is an example of data is stored in this.eventListeners
    this.eventListeners["mouseover"] =    [
                                            {"functionRef":func1 , "groupingObject": 2},
                                            {"functionRef":func2 , "groupingObject": 3}
                                          ];
    this.eventListeners.["mouseout"] =    [
                                            {"functionRef":func3 , "groupingObject": 2},
                                            {"functionRef":func4 , "groupingObject": 3}
                                          ];
*/

//---------------------------------------------------------------------------------------------------------
// @param objectToListenTo . This is the jQuery or DOM object that will be listened to
//---------------------------------------------------------------------------------------------------------
function Afk_EventListener(objectToListenTo){
    this.objectToListenTo = objectToListenTo;
    this.eventListeners = {};
    this.isJquery = false;
    if(objectToListenTo.jquery !== undefined){
        this.isJquery = true;
    }

    //-----------------------------------------------------------------------------------------
    // This is the function that is called by the listened to object when one of its listened to events occurs.
    // So when the event "onmouseover" fires, AND this is one of the events being listened to, this function is called with parameter "onmousedown"
    // You can also call this function to simulate an event being fired.
    //
    // If one of the called functions returns false, no further functions will be called
    //-----------------------------------------------------------------------------------------
    this.callEvent = function(eventName){
        var arr = this.eventListeners[eventName];
        for (var handler in arr) {
            if(arr[handler].functionRef() == false){
                //they told us to stop calling functions
                return false;
            }
        }
        return true;
    }

    // Add a function to be called on a listened to event
    //-----------------------------------------------------------------------------------------
    // @param groupingObject = the object used to "group" this function reference (used for removing handlers)
    // @param eventName = for jQuery use jQuery names ("mouseup", "mousedown", ...), else use DOM event names ("onmouseup", "onmousedown")
    // @param functionRef = the function that will be called upon the event
    // @param forceDom = if true, the object will be treated like a simple DOM object (overwriting existing function)
    //-----------------------------------------------------------------------------------------
    this.add = function(groupingObject, eventName, functionRef, forceDom){
        //if forceDom not given as a parameter, set it as a default to false
        if(forceDom==undefined){
            forceDom = false;
        }

        //if this is the first listener for the specified eventName, do a special setup
        if( this.eventListeners[eventName] === undefined || this.eventListeners[eventName] == null || this.eventListeners[eventName].length == 0 ){
            this.eventListeners[eventName] = [];
            linkBack = this; //used in event handlers. Have to use another variable other than 'this' as it has a different meaning inside an event handler function

            //overwrite objectToListenTo's function handler with new this.callEvent (used for a DOM object)
            // or place this.callEvent inside the existing method (used for a jQuery object)
            if(this.isJquery && forceDom == false){ //add handler to listened object using JQuery
                this.objectToListenTo[eventName](function(){
                    linkBack.callEvent(eventName);
                });
            }else{ //add handler to listened object using DOM
                this.objectToListenTo[eventName] = function(){
                    linkBack.callEvent(eventName);
                }
            }
        }
        //now add the event listener to
        this.eventListeners[eventName].push ( {
            "functionRef":functionRef,
            "groupingObject":groupingObject
        });
    }

    // Removes all listening functions that were added using an equal groupingObject and the specified eventName
    //-----------------------------------------------------------------------------------------
    // @param groupingObject = all functions listenting to 'eventName' that were added using this groupObject  will be removed
    // @param eventName = name of normal event handler ("onmouseover", ...)
    // @return true if at least one was removed, else false
    //-----------------------------------------------------------------------------------------
    this.removeGroupEvent = function(groupingObject, eventName){
        result = false;
        var arr = this.eventListeners[eventName];
        for(i=0;i<arr.length;i++){
            if(arr[i].groupingObject === groupingObject){
                arr.splice(i,1);
                i--;
                result = true;
            }
        }
        if(this.eventListeners[eventName].length == 0){
            delete this.eventListeners[eventName];
        }
        return result;
    }

    // Removes all listening functions that were added with the passed 'groupingObject'
    //-----------------------------------------------------------------------------------------
    // @return true if at least one was removed, else false
    //-----------------------------------------------------------------------------------------
    this.removeListener = function(groupingObject){
        result = false;
        for (var eventName in this.eventListeners) {
            result |= this.removeGroupEvent(groupingObject, eventName);
        }
        return result;
    }
}





