// (c) Benoît PIN 2006-2008
// http://plinn.org
// Licence GPL
// $Id: javascript_events_api.js 1296 2008-05-26 09:25:49Z pin $
// $URL: http://svn.cri.ensmp.fr/svn/Plinn/trunk/skins/ajax_scripts/javascript_events_api.js $
// Meta functions for events management.

var addListener; /* (ob, eventName, listenerFunction, group) add event listener eventName without "on" prefix.
				 *  optionally, listeners can be grouped to make removing convenient.
				 */
var removeListener; // (ob, eventName, listenerFunction, group) remove event listener.
var removeGroupListeners; // (group) remove all listeners in group.
var raiseMouseEvent; // (ob, eventName) raise mouse event (without "on" prefix) on object.

var getTargetedObject; // (event) retrieves the object that fired the event. Event parameter is optional.
var getEventObject; // (event) return the event object. Event parameter is optional.
var disableDefault; // (event) disable default event's action. Event parameter is optional.
var disablePropagation; // (event) disable event propagation or bubbling.

// etc utils
var getWindowWidth; // returns browser's window width
var getWindowHeight; // returns browser's window height
var clearSelection; // clear current selection (useful on drag and drop)

(function(){

function buildMetaFunctions() {
	addListener = _build_addListener();
	removeListener = _build_removeListener();
	raiseMouseEvent = _build_raiseMouseEvent();

	getTargetedObject = _build_getTargetedObject();
	getEventObject = _build_getEventObject();
	disableDefault = _build_disableDefault();
	disablePropagation = _build_disablePropagation();
	getWindowWidth = _build_getWindowWidth();
	getWindowHeight = _build_getWindowHeight();
	clearSelection = _build_clearSelection();
}

__groupListeners = {};

function _build_addListener() {
	var _browserSpecific;
	if (browser.isIE55 || browser.isIE6up) {
		_browserSpecific = function(ob, eventName, listenerFunction) {
			eventName = "on" + eventName;
			ob.attachEvent(eventName, listenerFunction);
		};
	}
	else if (browser.isDOM2Event) {
		_browserSpecific = function(ob, eventName, listenerFunction) {
			ob.addEventListener(eventName, listenerFunction, false); // only bubbling events :-(
		};
	}
	var common = function(ob, eventName, listenerFunction, group) {
		_browserSpecific(ob, eventName, listenerFunction);
		if (group) {
			if(!__groupListeners[group])
				__groupListeners[group] = new Array();
			__groupListeners[group].push([ob, eventName, listenerFunction]);
		}
	}
	return common;
}

function _build_removeListener() {
	if (browser.isIE55 || browser.isIE6up) {
		var _ie_removeListener = function(ob, eventName, listenerFunction) {
			eventName = "on" + eventName;
			ob.detachEvent(eventName, listenerFunction);
		}
		return _ie_removeListener;
	}
	else if (browser.isDOM2Event) {
		var _dom2_removeListener = function(ob, eventName, listenerFunction) {
			ob.removeEventListener(eventName, listenerFunction, false); // only bubbling events :-(
		}
		return _dom2_removeListener;
	}
}

removeGroupListeners = function(group) {
	var listeners = __groupListeners[group];
	var l;
	for (var i=0 ; i<listeners.length ; i++){
		l = listeners[i];
		removeListener(l[0], l[1], l[2])
	}
	__groupListeners[group] = null;
		
}

function  _build_raiseMouseEvent() {
	if (browser.isIE55 || browser.isIE6up) {
		var _ie_raiseMouseEvent = function(ob, eventName) {
			ob.fireEvent("on" + eventName);
		}
		return _ie_raiseMouseEvent;
	}
	else if (browser.isDOM2Event) {
		var _dom2_raiseMouseEvent = function(ob, eventName) {
			var event = document.createEvent("MouseEvents");
			event.initEvent(eventName, true, true);
			ob.dispatchEvent(event);
		}
		return _dom2_raiseMouseEvent;
	}
}

function _build_getTargetedObject(){
	if (browser.isIE55 || browser.isIE6up) {
		var _ie_getTargetedObject = function() {
			return window.event.srcElement;
		}
		return _ie_getTargetedObject;
	}
	else if (browser.isDOM2Event) {
		var _appleWebKit_getTargetedeObject = function(evt) {
			var target = evt.target;
			// is it really safe ?...
			return (target.nodeType == 3) ? target.parentNode : target;
		}
		var _dom2_getTargetedObject = function(evt) {
			return evt.target
		}
		return (browser.isAppleWebKit) ? _appleWebKit_getTargetedeObject : _dom2_getTargetedObject;
	}
}

function _build_getEventObject(){
	if (browser.isIE) {
		var _ie_getEventObject = function() {
			return window.event;
		}
		return _ie_getEventObject;
	}
	else if (browser.isDOM2Event) {
		var _dom2_getEventObject = function(evt) {
			return evt;
		}
		return _dom2_getEventObject;
	}
}


function _build_disableDefault(){
	if (browser.isIE55 || browser.isIE6up) {
		var _ie_disableDefault = function() {
			window.event.returnValue = false;
		}
		return _ie_disableDefault;
	}
	else if (browser.isDOM2Event) {
		var _dom2_disableDefault = function(evt) {
			evt.preventDefault();
		}
		return _dom2_disableDefault;
	}
}

function _build_disablePropagation() {
	if (browser.isIE55 || browser.isIE6up) {
		var _ie_disablePropagation = function() {
			window.event.cancelBubble = true;
		}
		return _ie_disablePropagation;
	}
	else if (browser.isDOM2Event) {
		var _dom2_disablePropagation = function(evt) {
			evt.stopPropagation();
		}
		return _dom2_disablePropagation;
	}
}

function _build_getWindowWidth() {
	if (window.innerWidth != undefined){
		return function(){
			return window.innerWidth;
			};
	}
	else {
		return function(){
			return document.body.clientWidth;
		};
	}
}

function _build_getWindowHeight() {
	if (window.innerHeight != undefined) {
		return function(){
			return window.innerHeight;
		};
	}
	else {
		return function(){
			return document.body.clientHeight;
		};
	}
}

function _build_clearSelection() {
	if (document.selection) {
		return function() {
			document.selection.clear();
		};
	}
	else {
		return function() {
			window.getSelection().removeAllRanges();
		}
	}
}


buildMetaFunctions();

})();
