//event object

/**
 * usage examples:
 * 1. eventObject(window).addEvent('keydown', handler_function);
 * 2. ev = new eventObject(e);
 *
 * properties:
 * -        type : type of event (if event) ex: keydown, keypress, click, ...
 * -      target : which DOM node is the source (target) of the event
 * -     keyCode : which key was pressed (if any)
 * -   leftClick : true if the left mousebutton was clicked
 * - middleClick : true if the middle mousebutton was clicked
 * -  rightClick : true if the right mousebutton was clicked
 * -      mouseX : x mouse coordiante
 * -      mouseY : y mouse coordiante
 * -      layerX : x layer mouse event position ???
 * -      layerY : y layer mouse event position ???
 * -        scrX : screen position, x coordinate
 * -        scrY : screen position, y coordinate
 * -   character : which carachter was pressed
 *
 * functions:
 * -    cancelBubble : stop the event from firing on the parent nodes
 * -  preventDefault : prevent the brosers default action
 * - getTargetObject : returns the source (target) of the event (a DOM node)
 */

function eventObject(obj) {
    var SELF = this;
    this.e = null;
    this.isEvent = false;
    this.CurrentFramePos = null;
	
    if (this instanceof eventObject && (typeof obj === 'object')) {
        if (UA.isIE()) {
            if (window.event !== null) {
                this.e = window.event;
            } else {
                this.e = obj;
            }
        } else {
            this.e = obj;
        }
        this.isEvent = true;
    } else if (typeof obj != 'undefined') {
        obj = Element(obj);
    }
			
    //add events to objects
    this.addEvent = function(name, func, capture) {
        if (typeof func != 'function') {
            throw new Error("The function does not exists!");
        }
        if (typeof capture != 'boolean') {
            capture = false;
        }
        if (capture && UA.isOpera()) {
            capture = false;
        }
        try {

            var index = "Event_" + (Math.random() * (new Date().getTime())).toString().replace(/\./,"");
            eventObject.EventListeners[index] = {
                "func" : func,
                "capture" : capture
            };
            if (UA.isIE()) {
                obj.attachEvent("on" + name,eventObject.EventListeners[index].func);
            } else {
                obj.addEventListener(name,eventObject.EventListeners[index].func,capture);
            }
            if (typeof eventObject.EventListeners[obj] === "undefined") {
                eventObject.EventListeners[obj] = [];
            }
            
            if (obj == window) {
                if (typeof eventObject.EventListeners['window'] === 'undefined') {
                    eventObject.EventListeners['window'] = [];
                }
                eventObject.EventListeners['window'].push(index);
            }
            
            return index;
        } catch (ex) {
            throw new Error('eventObject::addEvent("' + name + '", ..., ...)\n' + ex.message);
        }
    };
	
    //remove events from objects
    this.removeEvent = function(name, index) {
        try {
            if (index) {
                if (UA.isIE()) {
                    obj.detachEvent("on" + name,eventObject.EventListeners[index].func);
                } else {
                    obj.removeEventListener(name, eventObject.EventListeners[index].func, eventObject.EventListeners[index].capture);
                }
                
                delete eventObject.EventListeners[index];
                return true;
            } else {
                return false;
            }
        } catch(e) {
            return false;
        }
    };

    this.fireEvent = function(event){
        if (document.createEventObject) {
            // dispatch for IE
            if (typeof e === 'undefined') {
                var evt = document.createEventObject();
            } else {
                var evt = document.createEventObject(e);
            }

            return obj.fireEvent('on'+event,evt);
        } else {
            // dispatch for firefox + others
            e = document.createEvent("HTMLEvents");
            e.initEvent(event, true, true ); // event type,bubbling,cancelable
            return !obj.dispatchEvent(e);
        }
    };
	
    if (this.isEvent) {

        this.getTargetObject = function() {
            return this.target;
        };

        this.getRelatedTarget = function() {
            if (UA.isIE()) {
                return this.e.fromElement || this.e.toElement;
            } else {
                return this.e.relatedTarget;
            }
        };

        this.cancelBubble = function() {
            switch(UA.Get('name').toUpperCase()) {
                case 'MSIE':
                    this.e.cancelBubble = true;
                    break;

                default:
                    this.e.stopPropagation();
                    break;
            }
        };

        this.preventDefault = function() {
            switch(UA.Get('name').toUpperCase()) {
                case 'MSIE':
                    this.e.returnValue = false;
                    break;

                default:
                    this.e.preventDefault();
                    break;
            }
        };

        this.GetTopLevelMousePositions = function(win) {
            var tmp = this.GetFramePositions(win);
			
            this.CurrentFramePos = {
                "Top"	: tmp.Top,
                "Left"	: tmp.Left
            };
			
            var posX = tmp.Left + this.mouseX;
            var posY = tmp.Top + this.mouseY;
			
            if (!UA.isIE() && !(UA.isFirefox() && win == top)) {
                posX -= win.document.body.scrollLeft;
                posX -= win.document.body.parentNode.scrollLeft;
                posY -= win.document.body.scrollTop;
                posY -= win.document.body.parentNode.scrollTop;
            }
			
            if (UA.isIE() && win != top) {
                posX -= top.document.body.scrollLeft;
                posX -= top.document.body.parentNode.scrollLeft;
                posY -= top.document.body.scrollTop;
                posY -= top.document.body.parentNode.scrollTop;
            }

            return {
                "X":posX,
                "Y":posY
            };
        };
		
        this.type = this.e.type;
        switch(UA.Get('name').toUpperCase()) {
            case 'MSIE':
                //target
                this.target = this.e.srcElement;
				
                //keypressed
                this.keyCode = this.e.keyCode;
				
                //mouse buttons
                this.rightClick = (this.e.button == 2?true:false);
                this.leftClick = (this.e.button == 1?true:false);
                this.middleClick = (this.e.button == 4?true:false);
				
                //mouse coords
                this.mouseX = this.e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                this.mouseY = this.e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
				
                //layer mouse events
                this.layerX = this.e.x;
                this.layerY = this.e.y;
				
                //screen pos
                this.scrX = this.e.screenX;
                this.scrY = this.e.screenY;
                break;
			
            default:
                //target
                this.target = this.e.target;
                if (this.target.nodeType == 3) {
                    //safari bug
                    this.target = this.target.parentNode;
                }
				
                //keypressed
                this.keyCode = this.e.which || this.e.keyCode; // Opera uses keyCode too!!!
				
                //mouse buttons
                this.rightClick = (this.e.which == 3?true:false);
                this.leftClick = (this.e.which == 1?true:false);
                this.middleClick = (this.e.which == 2?true:false);
				
                //mouse coords
                this.mouseX = this.e.pageX;
                this.mouseY = this.e.pageY;
				
                //layer mouse events
                if (UA.Get('name').toUpperCase() == 'OPERA') {
                    this.layerX = this.e.x;
                    this.layerY = this.e.y;
                } else {
                    this.layerX = this.e.layerX;
                    this.layerY = this.e.layerY;
                }
				
                //screen pos
                this.scrX = this.e.pageX - document.body.scrollLeft - document.documentElement.scrollLeft;
                this.scrY = this.e.pageY - document.body.scrollTop - document.documentElement.scrollTop;
				
                break;
        }
		
        this.character = String.fromCharCode(this.keyCode);
		
        this.shiftKey = this.e.shiftKey;
        this.altKey = this.e.altKey;
        this.ctrlKey = this.e.ctrlKey;

    }
	
    return this;
}

eventObject.EventListeners = {};

var EventTypes = {
	"MouseOver": 'mouseover',
	"MouseOut": 'mouseout',
	"MouseUp": 'mouseup',
	"MouseDown": 'mousedown',
	"MouseMove": 'mousemove',
	"Click": 'click',
	"DoubleClick": 'dblclick',
	"Change": 'change',
	"KeyPress": 'keypress',
	"KeyDown": 'keydown',
	"KeyUp": 'KeyUp'
};

eventObject.CreateEventObject = function(e) {
	var evt;
	if (document.createEventObject) {
		// dispatch for IE
		if (typeof e === 'undefined') {
			var evt = document.createEventObject();
		} else {
			var evt = document.createEventObject(e);
		}
	} else {
		// dispatch for firefox + others
		evt = document.createEvent("HTMLEvents");
	}

	return evt;
};

