/**
* Provides core functionality for cEasyJs-Framework
*
* @package Ceasy_Core
* @author Ralf Glaser
*
*/

cEasyJs=function() {

	/**
	 * protected members
	 **/
	var that={};
	var _url={
		'print':'http://www.lossburg.de/ceasy/modules/cms/print.php5',
		'recommend':'http://www.lossburg.de/ceasy/modules/cms/recommend.php5',
		'icons':'http://www.lossburg.de/ceasy/etc/icons/core/Basic',
		'jsBasic':'http://www.lossburg.de/ceasy/etc/remote/js/core/Basic',
		'css':'http://www.lossburg.de/ceasy/etc/remote/css'
	};
	var _bundles={
		'jQuery' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/jquery-1.4.4.min.js'}
			}
		},
		'datepicker' : {
			'scripts' :  {
				'main' : {'url' : _url['jsBasic']+'/jquery-ui.datepicker.js'}
			},
			'styles' : {
				'main' : {'url' : _url['css']+'/jquery/jquery-ui.datepicker.css'}
			},
			'required' : ['jQuery']
		},
		'MooTools' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/mootools-core-1.3.1.js', 'mustDoScriptLoadedCall' : true}
			}
		},
		'MooToolsMore' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/mootools-more-1.3.1.1.js', 'mustDoScriptLoadedCall' : true}
			},
			'required' : ['MooTools']
		},
		'MooFlow' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/MooFlow-0.2.js', 'mustDoScriptLoadedCall' : true}
			},
			'styles' : {
				'main' : {'url' : _url['css']+'/MooFlow/MooFlow.css'}
			},
			'required' : ['MooToolsMore']
		},
		'cEasyJs.popupImg' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.p0pupImg.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'popupImg',
			'required' : ['jQuery'],
			'altNames' : ['cEasy.popupImg']
		},
		'cEasyJs.popupIframe' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.p0pupIframe.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'popupIframe',
			'required' : ['jQuery'],
			'altNames' : ['cEasy.popupIframe']
		},
		'cEasyJs.dom' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.dom.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'dom',
			'required' : ['jQuery']
		},
		'cEasyJs.xmlDoc' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.xmlDoc.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'xmlDoc',
			'required' : ['jQuery']
		},
		'cEasyJs.soapWsClient' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.soapWsClient.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'soapWsClient',
			'required' : ['jQuery', 'cEasyJs.xmlDoc']
		},
		'cEasyJs.suggest' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.suggest.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'suggest',
			'required' : ['jQuery']
		},
		'cEasyJs.map' : {
			'scripts' : {
				'base' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.map.base.js', 'mustDoScriptLoadedCall' : true},
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.map.googleMaps3.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'map',
			'required' : ['jQuery', 'cEasyJs.dom']
		},
		'cEasyJs.geoPresenter' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.geoPresenter.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'geoPresenter',
			'required' : ['jQuery', 'cEasyJs.dom', 'cEasyJs.xmlDoc', 'cEasyJs.soapWsClient', 'cEasyJs.suggest', 'cEasyJs.map']
		},

		'cEasyJs.geoEditor' : {
			'scripts' : {
				'main' : {'url' : _url['jsBasic']+'/cEasyJs/cEasyJs.geoEditor.js', 'mustDoScriptLoadedCall' : true}
			},
			'namespace' : 'geoEditor',
			'required' : ['jQuery', 'cEasyJs.dom', 'cEasyJs.map']
		}
	}
	var _loaded={};
	var _loadCallback={};
	var _printWin;
	var _recommendWin;
	var _curtainDiv=false;
	var _curtainDivCss = {
		'background-color':'#000000',
		'position':'absolute',
		'top':'0px',
		'right':'0px',
		'bottom':'0px',
		'left':'0px',
		'opacity':0.8,
		'z-index':1000000000
	};
	var _loadingDiv=false;
	var _loadingImageUrl=_url['icons']+'/cEasyJs/loading.gif';
	var _loadingDivCss = {
		'position':'absolute',
		'width':32,
		'height':32,
		'padding':10,
		'z-index':1000000001
	};


	/**
	 * public members
	 **/
	that.language='de';

	/**
	 * protected methods
	 **/
	// -------------------------------------------------------------------
	_addScript=function (bundleName, scriptName, encoding) {

		encoding= encoding || 'utf-8';
		var url=_bundles[bundleName]['scripts'][scriptName]['url'];

		var _scriptId=_generateScriptNodeId(bundleName+'_'+scriptName);
		var _scriptNode;

		_scriptNode=document.createElement('script');
		_scriptNode.setAttribute('type', 'text/javascript');
		_scriptNode.setAttribute('id', _scriptId);
		_scriptNode.setAttribute('charset', encoding);
		var _head=document.getElementsByTagName('head')[0];
		if (_head) {
			_head.insertBefore(_scriptNode, null);
		} else {
			var _script=document.getElementsByTagName('script')[0];
			_script.parentNode.insertBefore(_scriptNode, _script);
		}

		if (typeof(_scriptNode.addEventListener)!='undefined') { // w3c

			_scriptNode.addEventListener('load', function () {that.scriptLoaded(bundleName, scriptName);}, false);

		} else {// IE bugfix: attaching load-event on an script-node won't work in IE, so we use onreadystatechange

			if (_scriptNode.readyState=='complete') {
				that.scriptLoaded(bundleName, scriptName);
			} else {
				_scriptNode.onreadystatechange=function () {
					if (_scriptNode.readyState=='complete') {
						_scriptNode.onreadystatechange='';
						that.scriptLoaded(bundleName, scriptName);
					}
				}
			}

		}

		_scriptNode.setAttribute('src', url); // set src AFTER attaching onload-event is important, especially for safari

	}

	// -------------------------------------------------------------------
	_addStyle=function (bundleName, styleName) {

		var url=_bundles[bundleName]['styles'][styleName]['url'];
		var _styleId=_generateStyleNodeId(bundleName+'_'+styleName);

		var _newStyleNode=document.createElement('link');
		_newStyleNode.setAttribute('type', 'text/css');
		_newStyleNode.setAttribute('id', _styleId);
		_newStyleNode.setAttribute('href', url);
		_newStyleNode.setAttribute('rel', 'stylesheet');
		setTimeout(function () { // Bugfix for IE6: append with delay, otherwise style will not be executed in IE6. DO NOT ASK WHY!
			var _heads=document.getElementsByTagName('head');
			try {_heads[0].appendChild(_newStyleNode);} catch (e) {} // this may fail in IE7 if head is not yet closed (see http://support.microsoft.com/kb/927917/en)
		}, 100);

	}

	// -------------------------------------------------------------------
	_generateScriptNodeId=function (name) {

		return 'cCore_cEasyJsScript_'+name.replace(/[^0-9a-zA-Z_]/g, '_');

	}

	// -------------------------------------------------------------------
	_generateStyleNodeId=function (name) {
		return 'cCore_cEasyJsStyle_'+name.replace(/[^0-9a-zA-Z_]/g, '_');
	}

	// -------------------------------------------------------------------
	_addBundleScripts=function (bundleName) {
		for (var scriptName in _bundles[bundleName]['scripts']) {
			_addScript(bundleName, scriptName);
		}
	}

	// -------------------------------------------------------------------
	_checkRequiredReady=function (bundleName) {
		var _isReady=true;
		for (var requiredName in _bundles[bundleName]['requiredState']) {
			if (_bundles[bundleName]['requiredState'][requiredName]!='ready') {
				_isReady=false;
				break;
			}
		}
		if (_isReady) {
			_addBundleScripts(bundleName);
		}
	}

	// -------------------------------------------------------------------
	_checkBundleReady=function (bundleName) {

		var _isReady=true;

		if (_bundles[bundleName]['state']!='ready') {
			for (var scriptName in _bundles[bundleName]['scripts']) {
				if (_bundles[bundleName]['scripts'][scriptName]['state']!='ready') {
					_isReady=false;
					break;
				}
			}

			if (_bundles[bundleName]['requiredState']) {
				for (var requiredName in _bundles[bundleName]['requiredState']) {
					if (_bundles[bundleName]['requiredState'][requiredName]!='ready') {
						_isReady=false;
						break;
					}
				}
			}

			if (_isReady) { // everything is ready, call final callbacks
				_bundles[bundleName]['state']='ready';
				window.setTimeout(function () {
					for (var i=0; i < _bundles[bundleName]['callbacks'].length; i++) {
						_bundles[bundleName]['callbacks'][i]();
					}
				}, 100);
			}
		}

	}

	/**
	 * public methods
	 **/
	// -------------------------------------------------------------------
	that.addCONST=function (namespace, consts) {

		if (typeof(cEasyJs.CONST[namespace])=='undefined') {
			cEasyJs.CONST[namespace]={};
		}
		for (var name in consts) {
			cEasyJs.CONST[namespace][name]=consts[name];
		}

	}

	// -------------------------------------------------------------------
	that.addLANG=function (namespace, langs) {

		if (typeof(cEasyJs.LANG[namespace])=='undefined') {
			cEasyJs.LANG[namespace]={};
		}
		for (var name in langs) {
			cEasyJs.LANG[namespace][name]=langs[name];
		}

	}

	// -------------------------------------------------------------------
	that.getUrl=function (name) {

		return _url[name];

	}

	// -------------------------------------------------------------------
	that.scriptLoaded=function (bundleName, scriptName, scriptParsed) {
		if (_bundles[bundleName]['scripts'][scriptName]['state']!='ready') { // this may be called twice (if we have an explicit call within the script)
			if (!_bundles[bundleName]['scripts'][scriptName]['mustDoScriptLoadedCall'] || scriptParsed) {
				_bundles[bundleName]['scripts'][scriptName]['state']='ready';
				_checkBundleReady(bundleName);
			}
		}
	}

	// -------------------------------------------------------------------
	that.load=function (bundleName, callback) {

		var _bundle=false;
		if (_bundles[bundleName]) {
			_bundle=_bundles[bundleName];
		} else { // repair bundleName
			for (checkBundleName in _bundles) {
				if (checkBundleName.toLowerCase()==bundleName.toLowerCase()) {
					bundleName=checkBundleName;
				} else if (_bundles[checkBundleName]['altNames'] && _bundles[checkBundleName]['altNames'].length>0) {
					for (var i=0; i < _bundles[checkBundleName]['altNames'].length; i++) {
						if (_bundles[checkBundleName]['altNames'][i].toLowerCase()==bundleName.toLowerCase()) {
							bundleName=checkBundleName;
							break;
						}
					}
				}
				if (_bundles[bundleName]) {
					_bundle=_bundles[bundleName];
					break;
				}
			}
		}

		if (_bundle) {

			if (_bundle['namespace']) {
				if (typeof(cEasyJs[_bundle['namespace']])=='undefined') {
					cEasyJs[_bundle['namespace']]={};
				}
				if (typeof(cEasyJs.CONST[_bundle['namespace']])=='undefined') {
					cEasyJs.CONST[_bundle['namespace']]={};
				}
				if (typeof(cEasyJs.LANG[_bundle['namespace']])=='undefined') {
					cEasyJs.LANG[_bundle['namespace']]={};
				}
			}

			if (typeof(_bundle['state'])=='undefined') {
				_bundle['state']='unloaded';
			}

			if (_bundle['state']=='ready') {

				if (callback) callback();

			} else if (_bundle['state']=='loading') {

				window.setTimeout(function() {
					that.load(bundleName, callback);
				}, 200);

			} else {

				_bundle['state']='loading';
				_bundle['callbacks']=[(callback ? callback : function (){})];
				_bundle['requiredState']={};

				// load styles
				if (_bundle['styles']) {
					for (styleName in _bundle['styles']) {
						_bundle['styles'][styleName]['loaded']=0;
						_addStyle(bundleName, styleName, false);
					}
				}

				// load required
				if (_bundle['required'] && _bundle['required'].length>0) {
					for (var i=0; i < _bundle['required'].length; i++) {
						var _requiredName=_bundle['required'][i];
						var _requiredReadyCallback=function () {
							var _requiredBundleName=_requiredName;
							var _bundleName=bundleName;
							return function () {
								_bundles[_bundleName]['requiredState'][_requiredBundleName]='ready';
								_checkRequiredReady(_bundleName);
							}
						}();
						_bundle['requiredState'][_requiredName]=(_bundles[_requiredName] && _bundles[_requiredName]['state'] ? _bundles[_requiredName]['state'] : 'unloaded');
						if (_bundle['requiredState'][_requiredName]=='ready') {
							// nothing to do
						} else if (_bundle['requiredState'][_requiredName]=='loading') {
							_bundles[_requiredName]['callbacks'].push(_requiredReadyCallback);
						} else { // not yet ready or loading
							that.load(_requiredName, _requiredReadyCallback);
						}
					}
					_checkRequiredReady(bundleName);
				} else {
					_addBundleScripts(bundleName);
				}

			}

		} else {
			alert('cEasyJs.load(): unknown bundleName \''+bundleName+'\'');
		}

	}

	// -------------------------------------------------------------------
	that.print=function (useWin, width, height) {

		useWin= (useWin===false ? false : true);
		width= width || 680;
		height= height || 500;

		if (useWin) {
			_printWin=window.open(this.getUrl('print')+location.search, 'cEasyPrintWin', 'top=10, left=10, width='+width+', height='+height+', status=no, resizable=yes, scrollbars=yes');
			_printWin.focus();
		} else {
			that.popupIframe(this.getUrl('print')+location.search, width, height);
		}

	};

	// -------------------------------------------------------------------
	that.recommend=function (useWin, width, height) {

		width= width || 600;
		height= height || 600;

		if (useWin) {
			_recommendWin=window.open(this.getUrl('recommend')+location.search, 'cEasyRecommendWin', 'top=10, left=10, width='+width+', height='+height+', status=no, resizable=yes, scrollbars=yes');
			_recommendWin.focus();
		} else {
			that.popupIframe(this.getUrl('recommend')+location.search, width, height);
		}

	};

	// -------------------------------------------------------------------
	that.showCurtain=function (bindEvents, doNotShowLoadingDiv) {

		doNotShowLoadingDiv= doNotShowLoadingDiv || false;

		this.load('jQuery', function () {

			if (doNotShowLoadingDiv) {
				if (_loadingDiv) {
					_loadingDiv.hide();
				}
			} else {

				if (_loadingDiv) {
					_loadingDiv.show();
				} else {
					/* firefox-opacity-hack:
					 * ---------------------
					 * It is no good idea to append imgDiv and loadingDiv to this.curtainDiv, cause then imgDiv would inherit
					 * opacity of this.curtainDiv (at least in FF) and there is no way to restore none-opacity for imgDiv.
					 * So we append imgDiv and loadingDiv to body
					 */
					_loadingDiv=jQuery('<div id="cCore_cEasyJsLoadingDiv"><img src="'+_loadingImageUrl+'" /></div>').css(_loadingDivCss).appendTo('body');
				}

			}

			if (_curtainDiv) {
				_curtainDiv.show();
			} else {
				_curtainDiv=jQuery('<div id="cCore_cEasyJsOverlayDiv"></div>').css(_curtainDivCss).appendTo('body');
			}
			that.refitCurtain(true);

			if (bindEvents) {
				for (var i=0; i < bindEvents.length; i++) {
					_curtainDiv.bind(bindEvents[i]['type'], bindEvents[i]['func']);
				}
			}

		});

	}

	// -------------------------------------------------------------------
	that.refitCurtain=function (doNotHideLoadingDiv) {

		doNotHideLoadingDiv= doNotHideLoadingDiv || false;

		_curtainDiv.css({
			'height':jQuery(document).height()
		});
		if (jQuery.browser.msie && parseFloat(jQuery.browser.version)<7) {
			_curtainDiv.css({
				'width':jQuery(document).width()
			});
		}
		if (_loadingDiv) {
			_loadingDiv.css({ // refit position
				'left':jQuery('html').scrollLeft()+Math.floor((jQuery(window).width()-32)/2)-10,
				'top':jQuery('html').scrollTop()+Math.floor((jQuery(window).height()-32)/2)-10
			});
			if (!doNotHideLoadingDiv) {
				_loadingDiv.hide();
			}
		}

	}

	// -------------------------------------------------------------------
	that.hideCurtain=function (unbindEvents) {

		if (typeof('jQuery')!='undefined') {

			if (_loadingDiv) {
				_loadingDiv.hide();
			}
			if (_curtainDiv) {
				_curtainDiv.fadeOut();
			}
			if (unbindEvents) {
				for (var i=0; i < unbindEvents.length; i++) {
					_curtainDiv.unbind(unbindEvents[i]['type'], unbindEvents[i]['func']);
				}
			}

		}

	}

	// -------------------------------------------------------------------
	that.popupImg=function (url, groupClass) { // dummy that does load implementation and replaces itself

		var _name='cEasyJs.popupImg';
		if (_loaded[_name] || _loaded[_name]===0) {
			alert('Beim Nachladen der Funktion »'+_name+'« ist ein Fehler aufgetreten');
			this.hideCurtain([{
				'type':'click.loadPopupImg',
				'func':null
			}]);
		} else {
			this.showCurtain([{
				'type':'click.loadPopupImg',
				'func':function () {
					that.hideCurtain([{
						'type':'click.loadPopupImg',
						'func':null
					}]);
				}
			}]);
			this.load(_name, function () {
				cEasyJs.popupImg(url, groupClass);
			});
		}
	}

	// -------------------------------------------------------------------
	that.popupIframe=function (url, width, height, callback) { // dummy that does load implementation and replaces itself
		var _name='cEasyJs.popupIframe';
		if (_loaded[_name] || _loaded[_name]===0) {
			alert('Beim Nachladen der Funktion »'+_name+'« ist ein Fehler aufgetreten');
			this.hideCurtain([{
				'type':'click.loadPopupIframe',
				'func':null
			}]);
		} else {
			this.showCurtain([{
				'type':'click.loadPopupIframe',
				'func':function () {
					that.hideCurtain([{
						'type':'click.loadPopupIframe',
						'func':null
					}]);
				}
			}]);
			this.load(_name, function () {
				cEasyJs.popupIframe(url, width, height, callback);
			});
		}
	}

	// -------------------------------------------------------------------
	that.swapList=function (div, img, masterSwitch) {
		if (masterSwitch) {
			var _doOpen=(typeof(masterSwitch.innerText)=='undefined' ? (masterSwitch.textContent==cEasyJs.LANG.swapList.showAll ? true : false) : (masterSwitch.innerText==cEasyJs.LANG.swapList.showAll ? true : false));
		 	var _imgObjs=document.getElementsByTagName('img');
		 	var _imgPrefixLength=img.length;
		 	for (var i=0; i < _imgObjs.length; i++) {
		 		var _imgObj=_imgObjs[i];
		 		if (_imgObj.id && _imgObj.id.substring(0, _imgPrefixLength)==img) {
		 			_imgObj.src=_url['icons']+'/cEasyJs/swapList/'+(_doOpen ? 'minus' : 'plus')+'.gif';
		 		}
		 	}
		 	var _divObjs=document.getElementsByTagName('div');
		 	var _divPrefixLength=div.length;
		 	for (var i=0; i < _divObjs.length; i++) {
		 		var _divObj=_divObjs[i];
		 		if (_divObj.id && _divObj.id.substring(0, _divPrefixLength)==div) {
		 			_divObj.style.display=(_doOpen ? 'block' : 'none');
		 		}
		 	}
		 	if (typeof(masterSwitch.innerText)=='undefined') {
		 		masterSwitch.textContent=(_doOpen ? cEasyJs.LANG.swapList.hideAll : cEasyJs.LANG.swapList.showAll);
		 	} else {
		 		masterSwitch.innerText=(_doOpen ? cEasyJs.LANG.swapList.hideAll : cEasyJs.LANG.swapList.showAll);
		 	}
		} else {
			var _doOpen=(div.style.display=='none' ? true : false);
			img.src=_url['icons']+'/cEasyJs/swapList/'+(_doOpen ? 'minus' : 'plus')+'.gif';
			div.style.display=(_doOpen ? 'block' : 'none');
		}
	}

	return that;

}();

cEasyJs.CONST={};
cEasyJs.LANG={'swapList' : {}};

if (cEasyJs.language=='en') {
	cEasyJs.addLANG('swapList', {
		'showAll' : 'show all',
		'hideAll' : 'hideAll'
	});
} else if (cEasyJs.language=='fr') {
	cEasyJs.addLANG('swapList', {
		'showAll' : 'afficher toutes',
		'hideAll' : 'masquer toutes'
	});
} else {
	cEasyJs.addLANG('swapList', {
		'showAll' : 'alle anzeigen',
		'hideAll' : 'alle ausblenden'
	});
}

cEasyJs.addCONST('map', {
	'MAPTYPE_OSM' : 'osm',
	'MAPTYPE_OSMTAH' : null,
	'MAPTYPE_OPNV' : 'opnv',
	'MAPTYPE_CYCLE' : 'cycle',
	'MAPTYPE_CUSTOM' : null,
	'MAPTYPEDATA_CUSTOM' : null});

function cEasyPrint() { // deprecated (for backward-compatibility only)
	return cEasyJs.print();
}

function cEasyRecommend() { // deprecated (for backward-compatibility only)
	return cEasyJs.recommend();
}

cEasyJs.load('jQuery');

cEasy=cEasyJs; // use of namespace "cEasy" is deprecated (for backward-compatibility only)




