/*
----o0o=====================================================================================o0o----
Name:    EventManager
Author:  Tom Noogen
Date:    11.27.2005
Desc:    handle register and unregister events to support multiple browser and prevent
         memory leak issues.

Example: EventManager.add("ctrlId", "mouseover", function_pointer);

Copyright (c) Tom Noogen, 2005-2006.
http://www.noogen.net

All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
(CPL) which accompanies this distribution, and is available at
http://www.opensource.org/licenses/cpl.php
----o0o=====================================================================================o0o----
*/

var EventManager =
{
    _events: null,		// array of all events
    _onloads: null,		// array of window onload functions
    windowloaded: null,	// pointer to function call after all onload handlers
    
    // call to unwire all events when form is unloaded
	dispose: function()
    {
		if (EventManager._events != null) {
			for (var i = 0; i < EventManager._events.length; i++)
			{
				with (EventManager._events[i])
					EventManager.unregister(ctrl, evtype, handler, useCapture);
			}
        }

        EventManager._events = null;
        EventManager._onloads = null;
    },
	
	// allow for multiple onload of the window object
	windowloading: function()
	{
		var handled = false;
		
		// loop backward to guarrentee LIFO
		for(var i = (EventManager._onloads.length - 1); EventManager._onloads != null && i >= 0; i--)
		{
			var handler = EventManager._onloads[i];
			if (handler != null && typeof(handler) == "function")
				handled = handler();
			
			if (handled == true)
				EventManager._onloads = null;
		}
		
		// call loaded handler once complete all _onloads
		if (EventManager.windowloaded != null && typeof(EventManager.windowloaded) == "function")
			EventManager.windowloaded();
	},

	// call once to initialize EventManager object
	initialize: function() {
		if (this._events == null) {
			this._events = new Array();
			this.add(window, "load", EventManager.windowloading);
			this.add(window, "unload", EventManager.dispose);			
			this._onloads = new Array();
		}
	},
	
    /*
    ----o0o=====================================================================================o0o----
    Desc:	method to wire an event manage by EventManager
    Inputs:
		    ctrl			- table control reference or id string
		    evtype			- event name string ("click", "mouseover", etc..)
		    handler			- handler function pointer
		    useCapture		- true to use capture (ignore if don't know what this is).

	Example: EventManager.add("ctrlId", "mouseover", function_pointer);
    ----o0o=====================================================================================o0o----
    */	
    add: function(ctrl, evtype, handler, useCapture)
    {
		this.initialize();

        if (typeof (ctrl) == "string")
            ctrl = document.getElementById(ctrl);
			
        if (ctrl != null && handler != null)
        {
			if (this._onloads != null && ctrl == window && evtype == "load")
			{
				this._onloads[this._onloads.length] = handler;
			}
			else {
				this.register(ctrl, evtype, handler, useCapture);
				this._events[this._events.length] = {ctrl: ctrl, evtype: evtype, handler: handler, useCapture: useCapture};
			}
        }
    },
	
	// overloaded to wire event manage by EventManager
	Add: function(ctrl, evtype, handler, useCapture) {
		this.add(ctrl, evtype, handler, useCapture);
	},


	// Non-Browser Depedent: allow wiring of events
    register: function(ctrl, evtype, handler, useCapture) {
	    if (ctrl.addEventListener)
	        ctrl.addEventListener(evtype, handler, useCapture);
		else if (ctrl.attachEvent)
			ctrl.attachEvent("on" + evtype, handler);
    },
    
   	// Non-Browser Depedent: allow unwiring of events
    unregister: function(ctrl, evtype, handler, useCapture) {
		if (ctrl.removeEventListener)
			ctrl.removeEventListener(evtype, handler, useCapture);
		else if (ctrl.detachEvent)
			ctrl.detachEvent("on" + evtype, handler);
    },
	
	// Non-Browser Depedent: allow for getting input target from event object
	getInputObject: function(evt)
	{		
		var ctrl;
		if (evt.target)
			ctrl = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target;
		else 
			ctrl = evt.srcElement;
			
		return ctrl;
	},
	
	// Non-Browser Depedent: allow to get keycode of input events
	getKeyCode: function(evt)
	{
		return (evt.target) ? evt.which : evt.keyCode;
	},
	
	isMetaKey: function(evt) { 
		return (evt.metaKey) ? evt.metaKey : evt.modifiers & 8 > 0;
	},
	
	isAltKey: function(evt) {
		return (evt.altKey) ? evt.altKey : evt.modifiers & 1 > 0;
	},
	
	isCtrlKey: function(evt) {
		return (evt.ctrlKey) ? evt.ctrlKey : evt.modifiers & 2 > 0;
	},
	
	isShiftKey: function(evt) {
		return (evt.shiftKey) ? evt.shiftKey : evt.modifiers & 4 > 0;
	}
};