/**	lib:			js-dfc*	*	description:	DOM foundation classes**	created:		Sep. 6, 2002*	*	contributed:	Wolfgang Schramm**	methods:						callWithTimeout0				getUrlTimeStamp				preventTextSelection								assertUndefined				intError				dfc.load								getGlobalRef				setGlobalRef*/window.onload = function() { dfc._init(); }dfc		= new Object();dfc._init = function() {		// init web app framework, HTML doc must be loaded, don't call this earlier than the onload event	// get url parameter	//this._isBrowserCheck	= (this.sHRefLo.indexOf('nobrowsercheck')	== -1);	//this._isShowSniffer	= (this.sHRefLo.indexOf('showbrowsercheck')	!= -1);	this.defaultCharset	= 'UTF-8';	// check if we support current browser	this._browserSniffer();	if (!this._isBrowserSupported()) return;		// init script loader	this.hLoader = new DFCScriptLoader();	// check for debugging	//if (this._checkDebugMode()) return;	//this._checkDebugMode();			this._startApplication();}dfc._startApplication = function() {	// init custom app	if (this.app) {		this.app();	} else {		alert('dfc: dfc.app() is not implemented')	}}dfc._browserSniffer = function() {	// set info about used browser		// browser sniffer	var sAgent	= navigator.userAgent.toLowerCase();	var sVersion	= navigator.appVersion.toLowerCase();		// check for hard facts	this.isOpera	= window.opera					? true : false;	this.isIE		= document.all && !this.isOpera	? true : false;	this.isDOM	= document.getElementById		? true : false;	this.isNN7	= this.isDOM && !this.isOpera && navigator.appName == 'Netscape';		// plattform sniffer	this.isX		= (sAgent.indexOf('x11') != -1);	this.isMAC	= (sAgent.indexOf('mac') != -1);	this.isWIN	= (sAgent.indexOf('win') != -1);}dfc._isBrowserSupported = function() {	// check if current user agent is supported by the DFC framework		// TBD		// for now we accept every browser	return true;}dfc._checkDebugMode = function() {	// check if debugging was enabled, url parameter: &EnableDebugging	this.isDebugMode	= (location.href.toLowerCase().indexOf('enabledebugging') == -1);	var aLibs	= [				'js-dfc-tools',				'js-dfc-layer',				'js-dfc-debug'			  ]		   	this.load(aLibs, dfc._onloadDebugger);	return true;}dfc._onloadDebugger = function() {	this.hDebug	= new DFCDebug();	this.hDebug.debugMouseEvents(window, window.document);}/* -------------------------------------------------------------------------  tools  -------------------------------------------------------------------------- */ dfc.callWithTimeout = function(hFunctionRef, iDelay) {	// call a function with a delay	setTimeout('dfc.getGlobalRef("' + dfc.setGlobalRef(hFunctionRef) + '")()', iDelay);}dfc.getUrlTimeStamp = function() {		// return a timestamp to make a url unique	return('&' + (new Date().getTime()));}/* -------------------------------------------------------------------------  error handling  -------------------------------------------------------------------------- */ dfc.assertUndefined = function(hParam, sModule, sParamName) {	if (typeof hParam == 'undefined') {		alert('ASSERT in ' + sModule + ': ' + sParamName + ' is "undefined"');		return true;	} else {		return false;	}}	dfc.intError = function(sModule, sErrorMessage) {	// internal errors	alert(sModule + ': ' + sErrorMessage);}/* -------------------------------------------------------------------------  facility to make an object globally available, used in setTimeout or event handler  -------------------------------------------------------------------------- */ dfc._iRef		= 0;dfc._aRef		= new Array();dfc.setGlobalRef = function(hRef) {	// returns an id for an object which can be accessed globally	dfc._iRef++;	var sRef = dfc._iRef.toString();	dfc._aRef[sRef] = hRef;	return sRef;}dfc.getGlobalRef = function(sRef) {	// returns the reference for a given id	return this._aRef[sRef];}/* -------------------------------------------------------------------------  generic event handling for DOM elements  -------------------------------------------------------------------------- */dfc.addEventListener = function(hDOMNode, sEvent, hFktRef, opt_isCapture) {	var isCapture = opt_isCapture || false;		if (hDOMNode.addEventListener) {		hDOMNode.addEventListener(sEvent, hFktRef, isCapture)	} else {		switch (sEvent) {		case 'click':		hDOMNode.onclick		= hFktRef;			break;		case 'dblclick':	hDOMNode.ondblclick		= hFktRef;			break;		case 'focus':		hDOMNode.onfocus		= hFktRef;			break;		case 'load':		hDOMNode.onload		= hFktRef;			break;		case 'keydown':	hDOMNode.attachEvent('onkeydown',	hFktRef);		break;		case 'mouseover':	hDOMNode.onmouseover	= hFktRef;			break;		case 'mouseout':	hDOMNode.onmouseout		= hFktRef;			break;		case 'mouseup':	hDOMNode.onmouseup		= hFktRef;			break;		case 'mousedown':	hDOMNode.onmousedown	= hFktRef;			break;		case 'mousemove':	hDOMNode.onmousemove	= hFktRef;			break;		default: 	dfc.intError('dfc.addEventListener', sEvent + ' is not supported');	break;		}	}}// stop propagating an eventdfc.stopPropagation = function(hEvent) {	if (hEvent.stopPropagation) {		// W3C		hEvent.stopPropagation();	} else {		// IE		hEvent.cancelBubble = true;	}}// prevent default action dfc.preventDefault = function(hEvent) {	if (hEvent.preventDefault) {		// W3C		hEvent.preventDefault();	} else {		// IE		hEvent.returnValue = false;	}	return false;}// prevent selecting text on a DOM nodedfc.preventTextSelection = function(hDOMNode) {	if (hDOMNode.addEventListener) {		hDOMNode.addEventListener(			'mousedown', 			function (hEvent) { 				hEvent.preventDefault();			},			true)	} else {		// IE		hDOMNode.onselectstart = function() { return false; }	}}// return event object depending on MOZ/IEdfc.event = function(domElement, hEvent) {	if (hEvent) {		// MOZ		return hEvent;	} else {		// IE		return domElement.document.parentWindow.event;	}}// check if a mouseover event occureddfc.isMouseOver = function(hDOMNode, hEvent) {	if (hEvent.type == 'mouseover') {		if (hDOMNode.contains) {	// IE			if (!hDOMNode.contains(hEvent.fromElement)) {				return true;			}		} else {			return true;		}	}		return false;}// check if a mouseout event occureddfc.isMouseOut = function(hDOMNode, hEvent) {	if (hEvent.type == 'mouseout') {				if (hDOMNode.contains) {	// IE			if (!hDOMNode.contains(hEvent.toElement)) {				return true;			}		} else {			return true;		}	}		return false;}// extend mozilla event modelif (typeof Event != 'undefined' && Event.prototype) {	Event.prototype.__defineGetter__("fromElement",		function () {			var hNode;			if (this.type == "mouseover")			hNode = this.relatedTarget;			else if (this.type == "mouseout")		hNode = this.target;			else								return null;				if (hNode) {				while (hNode.nodeType != hNode.ELEMENT_NODE) hNode = hNode.parentNode;			}			return hNode;		}	);		Event.prototype.__defineGetter__("toElement",		function () {			var hNode;			if (this.type == "mouseout")			hNode = this.relatedTarget;			else if (this.type == "mouseover")		hNode = this.target;			else								return null;						if (hNode) {				while (hNode.nodeType != hNode.ELEMENT_NODE) hNode = hNode.parentNode;			}			return hNode;		}	);		Event.prototype.__defineGetter__("srcElement",		function () {			var hNode = this.target;			if (hNode) {				while (hNode.nodeType != hNode.ELEMENT_NODE) hNode = hNode.parentNode;			}			return hNode;		}	);}dfc.createAccessableText = function(domParent, sText) {	// create a text node which is accessable by the tab key		// return:	DOM text element		var domDoc = domParent.ownerDocument || domParent.document; 	// W3C / IE		if (typeof domParent.tabIndex == 'undefined') {		// for MOZ we create a button		var domBtn	= domDoc.createElement('input');		domBtn.type	= 'button';		domBtn.value	= sText;		// remove all formatting from the default button		var hStyle = domBtn.style;		hStyle.fontSize		= 'inherit';		hStyle.fontFamily		= 'inherit';		hStyle.fontWeight		= 'inherit';		hStyle.height			= 'inherit';		hStyle.lineHeight		= 'inherit';		hStyle.color			= 'inherit';		hStyle.border			= '0px';		hStyle.padding			= '0px';		hStyle.paddingBottom	= '0px';		hStyle.margin			= '0px';		hStyle.backgroundColor	= 'transparent';		return domParent.appendChild(domBtn);			} else {			// IE supports tabIndex in div's		var domDiv = domDoc.createElement('div');				domDiv.style.paddingLeft		= '2px';		domDiv.style.paddingRight	= '2px';				domDiv.appendChild(domDoc.createTextNode(sText));				domParent.tabIndex			= 1;		return domParent.appendChild(domDiv).parentNode;	}}dfc.removeClass = function(domNode, sClassName) {	if (!(domNode && domNode.className)) {		return;	}		var aOld = domNode.className.split(' ');	var aNew = new Array();		for (var i = aOld.length; i > 0;) {		if (aOld[--i] != sClassName) {			aNew[aNew.length] = aOld[i];		}	}	domNode.className = ar.join(' ');};dfc.addClass = function(domNode, sClassName) {	dfc.removeClass(domNode, sClassName);	domNode.className += ' ' + sClassName;};dfc.getAbsolutePos = function (hElement) {	// return absolute x,y coordinates of an element	var top	= 0;	var left	= 0;		do {		top	+= hElement.offsetTop;		left	+= hElement.offsetLeft;	}	while (hElement = hElement.offsetParent)		return {top: top, left: left}}/* -------------------------------------------------------------------------  class:		DFCObject	  description:	generic DFC object  -------------------------------------------------------------------------- */DFCObject = function() {	this.DFCObject			= true;	this._sGlobalRef		= dfc.setGlobalRef(this);		this._hWin			= null;	this._hDoc			= null;	this._domParent		= null;	}/* -------------------------------------------------------------------------  class:		DFCEventListener  			  description:	helper - single event listener  -------------------------------------------------------------------------- */DFCEventListener = function(hListenerSub, hListenerObj) {	this._hListenerSub	= hListenerSub;	this._hListenerObj	= hListenerObj;}/* -------------------------------------------------------------------------  class:		DFCEvent  methods:	addEventListener  			removeEventListener  			  description:	event facility for every DFCObject  -------------------------------------------------------------------------- */DFCEvent = function() {	DFCObject.call(this);	this.DFCEvent			= true;		this._aEventListener	= [];	this._aRegisteredEvents	= [];}DFCEvent.prototype = new DFCObject();DFCEvent.prototype.addEventListener = function(sEvent, hListenerFunc, hListenerObj) {	// return:	handle to the added event listener		if (this._aRegisteredEvents[sEvent] == null) {		dfc.intError('DFCEvent', 'Event "' + sEvent + '" is unknown');	}		if (this._aEventListener[sEvent] == null) {		this._aEventListener[sEvent] = new Array();	}		var hEvent = new DFCEventListener(hListenerFunc, hListenerObj);	var aEvent = this._aEventListener[sEvent];	aEvent[aEvent.length] = hEvent;	return hEvent;}DFCEvent.prototype.removeEventListener = function(sEvent, hListenerFunc, hListenerObj) {/* TBD	// opt_hEvent		if set removes only this event listener	if (opt_hEvent == null) {		// remove all eventlistener		this._aEventListener[sEvent] == null;	} else {			}*/}DFCEvent.prototype._raiseEvent = function(sEvent, opt_hParam1, opt_hParam2) {	// called from dfc object, raises a registered Event	var aEvents = this._aEventListener[sEvent];	// loop: all eventlistener 	for (iEvent in aEvents) {		var hEvent = aEvents[iEvent];				if (hEvent != null) {			// raise event			if (hEvent._hListenerObj) {				hEvent._hListenerSub.call(hEvent._hListenerObj, opt_hParam1, opt_hParam2);			} else if (hEvent._hListenerSub) {				hEvent._hListenerSub(opt_hParam1, opt_hParam2);			}		}	}}DFCEvent.prototype._registerEvent = function(sEvent) {	// this will register an event, each event a DFC object can raise must be registered	this._aRegisteredEvents[sEvent] = sEvent;}/* -------------------------------------------------------------------------  DFCConfig    methods:	create  			get  			  this implements a hierarchical configuration facility  -------------------------------------------------------------------------- */ DFCConfig = function(hConfigConstructor) {	this._aConfig			= new Array();	this._hConfigConstructor	= hConfigConstructor;		this._sDefaultKey		= 'DFCConfigDefault';	// create default configuration	this._aConfig[this._sDefaultKey] = new this._hConfigConstructor();}DFCConfig.prototype.create = function(hConfig, opt_sKey, opt_sParentKey) {	var sKey = opt_sKey  || this._sDefaultKey;	// if opt_sParentKey is set, configuration is inherited from opt_sParentKey	var hConfigInherit = (opt_sParentKey == null)	?						this._aConfig[this._sDefaultKey] : 						this._aConfig[opt_sParentKey];	var hConfigNew = new this._hConfigConstructor();	// overwrite all properties which are set in hConfigReg	for (var sPropName in hConfigNew) {		hConfigNew[sPropName] = (typeof hConfig[sPropName] == 'undefined') ? 								hConfigInherit[sPropName] : 								hConfig[sPropName];	}	this._aConfig[sKey]	= hConfigNew;		return hConfigNew;}DFCConfig.prototype.get = function(opt_sKey) {		var sKey = opt_sKey  || this._sDefaultKey;	return hConfig = this._aConfig[sKey];}/* -------------------------------------------------------------------------  class:		DFCMultiScriptLoader	  description:	helper to load  1..n script libraries  -------------------------------------------------------------------------- */function DFCMultiScriptLoader() {	this._iLoading			= 0;	this._isLoadingForced	= false;	this._aLibs			= new Array();	this._hCallbackObj		= null;	this._hCallbackSub		= null;}/* -------------------------------------------------------------------------  class:		DFCScriptLoader  events:		onLoad    description:	facility to load js libraries from the server  -------------------------------------------------------------------------- */function DFCScriptLoader() {	DFCEvent.call(this);	this._hDoc		= window.document;		// loaded scripts are added as child to the <HEAD>	this._hHead		= this._hDoc.getElementsByTagName('head')[0];		this._iLoading		= 0;					// number of libs being currently loaded	// define and register event which can be raised by this widget	this._sEvent_onLoad		= 'onLoad'	this._registerEvent(this._sEvent_onLoad);}DFCScriptLoader.prototype = new DFCEvent();DFCScriptLoader.prototype._load = function(aLibs, opt_hCallbackSub, opt_hCallbackObj, opt_isLoadingForced) {	// load all libraries in aLibs from the server		// aLibs 					is either string or array containing the js lib to be loaded	// opt_hCallbackSub			callback function called when all libraries are loaded	// opt_hCallbackObj			object for callback function	// opt_isLoadingForced		if set to true, the url is forced to be unique		// return					loading context, can be used by the caller to store custom data		var hScript;	var hMSL;		// convert aLibs into an array if parameter is a string	if (typeof aLibs == 'string') {		aLibs = [aLibs];	}		hMSL = new DFCMultiScriptLoader();		hMSL._hCallbackObj		= opt_hCallbackObj;	hMSL._hCallbackSub		= opt_hCallbackSub;	hMSL._isLoadingForced	= opt_isLoadingForced || false;		// loop: all libraries which should be loaded	for (var iLib = 0; iLib < aLibs.length; iLib++) {			var sLib = aLibs[iLib];				if (hMSL._isLoadingForced) {			sLib += dfc.getUrlTimeStamp();		}				// setup script element		hScript = this._hDoc.createElement("script");		hScript.setAttribute("src",		sLib);		hScript.setAttribute("type",		'text/javascript');		hScript.setAttribute("charset",	dfc.defaultCharset);								// put loader context into the DOM		hScript.DFCScriptLoader		= this;		hScript.DFCMultiScriptLoader	= hMSL;				// add listener for the onload event of the script library		if (hScript.addEventListener) {			// DOM			hScript.addEventListener('load', this._onLoadScript, false);		} else {			// IE			hScript.onreadystatechange = this._onLoadScript;		}		hMSL._iLoading++;		hMSL._aLibs[hMSL._aLibs.length] = sLib;		this._hHead.appendChild(hScript);		// set status that lib is loading		this._iLoading++;	}		return  hMSL;}DFCScriptLoader.prototype._onLoadScript = function() {	var hLoader	= this.DFCScriptLoader;	var hMSL		= this.DFCMultiScriptLoader;	if (this.addEventListener || window.event.srcElement.readyState == 'loaded') {			hLoader._iLoading--;		hMSL._iLoading--;				// call callback function		if (hMSL._iLoading < 0) {			dfc.intError('DFCScriptLoader', 'hMSL._iLoading < 0')		}				if (hMSL._iLoading == 0) {			// loading has finished			if (hMSL._hCallbackObj) {				hMSL._hCallbackSub.call(hMSL._hCallbackObj, hMSL);			} else if (hMSL._hCallbackSub) {				hMSL._hCallbackSub(hMSL);			}		}	}}// map private methods to dfc public methodsdfc.load		= function(p1, p2, p3, p4)	{ return this.hLoader._load(p1, p2, p3, p4); }