﻿//REQUIRES: - com/CS/Forms/Validation.js 
//                 - com/cs/util/Date.js

if (!com) var com = new Object();
if (!com.cs) com.cs = new Object();
if (!com.cs.util) com.cs.util = new Object();
if (!com.cs.util.event) com.cs.util.event = new Object();

if (!com.cs.util.event.EVENT_DISPATCHERS) com.cs.util.event.EVENT_DISPATCHERS = new Array();
//com.cs.util.Event = event;
//Adds an event to an element.  
//Elem - Element, or ID of element
//EventName - Name of event, example 'onfocus'
//func - New function to be added
com.cs.util.event.AddEvent = function(elem,eventName,func){
    if (typeof(elem) == "string")
        elem = document.getElementByID(elem);
        
    var newfunc = func;
    if (elem[eventName]) 
    {
        var oldfunc = elem[eventName];
        newfunc = function(event) 
        {
            var ret1 = oldfunc(event);
            var ret2 = func(event);
            return ret1 && ret2;
        }
    }
    elem[eventName] = newfunc;
}

/**
This will create an event handler for a particular event
*/
com.cs.util.event.EventHandler = function(eventName, handler) {
    this._eventName = eventName;
    this._eventHandler = handler;
    
    var scope = this;
    
    this.call = function(arguments) {
        scope._eventHandler.apply(this,arguments);
    }
    this.getEventName = function() { return scope._eventName; }
    this.getEventHandler = function() { return scope._eventHandler; }
    
    this.toString = function() { return "[com.cs.util.event.EventHandler]"; }
}

/**
This will create an event dispatcher object for a particular element
*/
com.cs.util.event.EventDispatcher = function(element) {
    this._element = element;
    this._handlers = new Array();
    
    var scope = this;
    
    /*
    Initialize the call for the particular event with that element
    */
    this._initDispatcherForEvent = function(eventName) {
        scope._element[eventName] = function(event) {
            for (var i = 0;i<scope._handlers.length;i++) {
                var handler = scope._handlers[i];
                if (handler.getEventName() == eventName) {
                    
                    handler.call(arguments);
                }
            }
        }
    }
    
    /**
    Add an observer for a particular event
    */
    this.addEventObserver = function(eventName, handler) {
        var handler = new com.cs.util.event.EventHandler(eventName, handler);
        scope._handlers.push(handler);
        
        scope._initDispatcherForEvent(eventName);
    }
    
    /**
    Remove an obsrever for a particular event
    */
    this.removeEventObserver = function(eventName, handler) {
        var removeIndex = -1;
        for (var i = 0;i<scope._handlers.length;i++) {
            var eh = scope._handlers[i];
            if (eh.getEventName() == eventName && eh.getEventHandler() == handler) {
                removeIndex = i;
                break;
            }
        }
        
        if (removeIndex != -1) {
            var part1 = scope._handlers.slice(0, removeIndex);
            var part2 = scope._handlers.slice(removeIndex+1);
            scope._handlers = part1.concat(part2);
        }
    }
    
    this.removeAllEventsFor = function(eventName) {
        for (var i = 0;i<scope._handlers.length;i++) {
            var handler = scope._handlers[i];
            if (handler.getEventName() == eventName) {
                scope.removeEventObserver(eventName, handler.getEventHandler());
                i--;
            }
        }
    }
    
    this.removeAllHandlers = function() {
        scope._handlers = new Array();
    }
    
    this.init = function() {
    
    }
    
    this.init();
    
    this.getElement = function() { return scope._element; }
    this.toString = function() { return "[com.cs.util.event.EventDispatcher]"; }
}

/**
Gets an instance of the event dispatcher for this particular
element.  Event Dispatchers are stored statically
*/
com.cs.util.event.getInstance = function(element) {
    if (typeof(element) == "string") element = document.getElementById(element);

    for (var i = 0; i<com.cs.util.event.EVENT_DISPATCHERS.length;i++) {
        var eventDispatcher = com.cs.util.event.EVENT_DISPATCHERS[i];
        if (eventDispatcher.getElement() == element) {
            return eventDispatcher;
        }            
    }
    var eventDispatcher = new com.cs.util.event.EventDispatcher(element);
    com.cs.util.event.EVENT_DISPATCHERS.push(eventDispatcher);
    return eventDispatcher;
}
/**
Regiser an event observer for a particular event within an element

Params:
-------

element     - The element to attach the event to
eventName   - The event name to attach the event to. e.g. "onload", "onclick"
handler     - A function to call when the event triggers
*/
com.cs.util.event.AddEventObserver = function(element, eventName, handler) {

    var eventDispatcher = com.cs.util.event.getInstance(element);
    eventDispatcher.addEventObserver(eventName, handler);
}
/**
Remove a registered event(s) from an element.  This is an overridden method.
It has the following options:

1. No parameters:                   Remove ALL events from ALL elements
2. element:                         Remove ALL events for that element
3. element & eventName:             Remove ALL events for that element for that particular event
4. element & eventName & handler:   Remove only one particular event for that particular element

Params:
-------

element     - The element to detach the event from
eventName   - The event name to detach the event from . e.g. "onload", "onclick"
handler     - The function which is being called
*/
com.cs.util.event.RemoveEventObserver = function(element, eventName, handler) {
    if (!element && !eventName && !handler) {
        com.cs.util.event.RemoveAllEventObservers();
    }
    else if (!eventName && !handler) {
        com.cs.util.event.RemoveAllEventObserversFor(element);
    }
    else if (!handler) {
        com.cs.util.event.RemoveAllEventObserversForEvent(element, eventName);
    }
    else {
        var eventDispatcher = com.cs.util.event.getInstance(element);
        eventDispatcher.removeEventObserver(eventName, handler);
    }
}

/**
This will detach all events for a particular element
*/
com.cs.util.event.RemoveAllEventObserversForEvent = function(element, eventName) {    
    var eventDispatcher = com.cs.util.event.getInstance(element);
    eventDispatcher.removeAllEventsFor(eventName);
}

/**
This will detach all events for a particular element
*/
com.cs.util.event.RemoveAllEventObserversFor = function(element) {    
    var eventDispatcher = com.cs.util.event.getInstance(element);
    eventDispatcher.removeAllHandlers();
}
/**
This will detach ALL events attached to any elements using the event dispatcher
*/
com.cs.util.event.RemoveAllEventObservers = function() {
    for (var i = 0;i<com.cs.util.event.EVENT_DISPATCHERS.length;i++) {
        var ed = com.cs.util.event.EVENT_DISPATCHERS[i];
        ed.removeAllHandlers();
    }
}
