/**
 * Request.implement
 * 
 * Requestfunktionen
 * Connectbereich für den Verzeichnisaufruf
 * 
 * @version		1.1.1
 * 
 * @author		GO4WEB Internet Agentur
 * @copyright		2010 Author
 */

/**
* GO4WEBDESK - CLASS
* - Verzeichnisfunctions
*	- Requests / Mulirequest
*	- Autorubrikbuilder
*	- Requestsorter
* - DOM Prerenderer
*/
/**
 * GO4WEBDESK - CLASS
 *  - Verzeichnisfunktionen
 *  - Ajax-Sitefunktionen
 *  
 *  Parameters:
 *    verzDebug: Debugmode fÃ¼r externes-Debuging
 *    verzLocal: Lokal DB verwenden
 *    plugins: Pluginpfade - FÃ¼r die Pluginerweiterung ausbauen
 *  
 *  Methods:
 *    _verzReqData: Dummy-Requestgrid
 *    _verzReq: 
 *    _verReqChange: 
 *    _verzFormMulti: 
 *    _verzFormSort: 
 *    
 *    _siteReq: 
 *    
 *    _jsPreload: 
 *    deskError: 
 *    
 */
var addDeskJS = new Class({
	
	// implements
	Implements: [Options, Events]
	
	// options
	,options: {
		verzDebug: 0
		,verzLocal: 0
		,verzUser: '4c_testuser'
		
		,plugins: {
			// classes
			templating: TROOT + 'mootools/_ejs/ejs.js'
			,historymanager: TROOT + 'mootools/_historymanager/hm.js'
			,menu: TROOT + 'mootools/_menu/menu.js'
			,accordionMenu: TROOT + 'mootools/_accordionMenu/accordionMenu.js'
			,slider: TROOT + 'mootools/_slider/slider.js'
			,scroller: TROOT + 'mootools/_scroller/scroller.js'
			,viewer: TROOT + 'mootools/_viewer/viewer.js'
			,scrollspy: TROOT + 'mootools/_scrollspy/scrollspy.js'
			,popup: TROOT + 'mootools/_popup/popup.js'
			
			// functions
			,sortOn: TROOT + 'mootools/_sortOn/sortOn.js'
		}
	}
	
	// initialize
	,initialize: function(options){
		this.setOptions(options);
	}
	
	// Dummy-Request auf gewÃ¤lten user
	,_verzReqData: function(){
		
		this._verzReqStr = {
			type: 'all'
			,user: this.options.verzUser
			,table: {
				listingdatas: 'ld'
				,listingrows: 'lr'
				//,listings: 'l'
			}
			,condition: {
//				OR abfrage
//				0: {
//					'm.sommer': '1',
//					'm.winter':'1'
//				}
			}
			,fields: 'lr.*,ld.*'
			,order: 'ld.id DESC'
			,language: 'de'
		}
	}
	
	// Verzeichnisrequest mit Verweiss auf Folgefunktion
	,_verzReq: function(onCompletFunc){
		
		if(this.options.verzDebug == 1) debugStr = '&debug=1';
		else debugStr = '';
		
		if(!this._verzReqStr) this._verzReqData();
		
		// tempsStr
		if($defined(this._verzTempReqStr) && this._verzTempReqStr){
			reqStr = this._verzTempReqStr;
			this._verzTempReqStr = false;
		}else{
			reqStr = this._verzReqStr;
		}
		
		// Falls Arrayreq nur mit einem Element
		if(reqStr.length == 1) reqStr = reqStr[0];
		
		new Request({
			url: 'index.php'
			,method: 'post'
			,data: 'mode=verzeichnis&local=' + this.options.verzLocal + debugStr +'&request=' + encodeURIComponent(JSON.encode(reqStr))
			,noCache: true
			,onComplete: function(response){
				var req = JSON.decode(response);
				if($type(onCompletFunc) == 'function') onCompletFunc(req);
				else this[onCompletFunc](req);
			}.bind(this)
		}).send();
	}
	
	
	,_verReqChange: function(reqObj, changObj){
		
		var buildObj, addStr, newTbl={};
		var tblList = {listingdatas: 'ld', listingrows: 'lr', listings: 'l'};
		
		if(reqObj) buildObj = reqObj;
		else buildObj = this._verzReqStr;
		if($defined(changObj['table']) && $type(changObj['table']) == 'string'){
			if(changObj['table'] == '') addStr = '';
			else addStr = '_' + changObj['table'];
			$H(tblList).each(function(items, key){
				newTbl[key + addStr] = items;
			});
			changObj['table'] = newTbl;
		}
		$H(changObj).each(function(items, key){
			reqObj[key] = items;
		});
		
		return reqObj;
	}
	
	/**
	 * _verzFormMulti	Merg des MultiformRequest mit tableName adding
	 * 
	 * sortPath		SortPath Falls das Object nach dem Merg sortiert werden soll (siehe _verzFormSort)
	 * order		Order des Sorting
	 */
	,_verzFormMulti: function(req, sortPath, order){
		
		var newReqArr = [];
		var reqOut = [];
		var count = 0;
		
		if(!$defined(req.result[0][0])) req.result = [req.result];
		req.result.each(function(items, key){
			var tblName = req.tblName[key];
			items.each(function(subitems, subkey){
				if($defined(subitems.lr)) subitems.lr['tableName'] = tblName;
				if($defined(subitems.ld)) subitems.ld['tableName'] = tblName;
				newReqArr.push($H(subitems));
			});
			count++;
		}, this);
				
		if(sortPath) newReqArr = this._verzFormSort(newReqArr, sortPath, order);
		
		reqOut['count'] = newReqArr.length;
		reqOut['result'] = newReqArr;
		
		return reqOut;
	}
	
	/**
	 * _verzFormSort	Umsortierung eines Hash (Achtung Object muss zu Hash formatiert werden)
	 * 
	 * array		Zu sortierenden Hash
	 * path			Sortierpfad (ld.datum)
	 * order		desc / asc
	 */
	,_verzFormSort: function(array, path, order){
		
		for (var i = 0; i < array.length; i++) {
			
			var currVal = array[i].getFromPath(path);
			var currElem = array[i];
			
			var j = i - 1;
			while ((j >= 0) && (array[j].getFromPath(path) > currVal)) {
				array[j + 1] = array[j];
				j--;
			}
			array[j + 1] = currElem;
		}
		
		if(order == 'desc') array.reverse();
		
		return array;
	}
	
	
	
	/**
	 * Site Request
	 */
	,_siteReq: function(id, fields, onCompletFunc){
		new Request.JSON({
			url: 'index.php',
			method: 'post',
			data: 'mode=ajax&id=' + id + '&reqCol=' + fields,
			onComplete: function(response){
				if($type(onCompletFunc) == 'function') onCompletFunc(response);
				else this[onCompletFunc](response);
			}.bind(this)
		}).send();
	}
	
	/**
	 * Desk-Helpers
	 */
	,_jsPreload: function(options){
		
		// http://mootools.net/forge/p/preloaderqueue alternative
		
		this.options.loadstatus = [];
		this._loadStatus('preload', {status: 'start'});
		
		if($defined(options)){
			$each(options, function(val, key){
				if(val){
					// statusset
					this.options.loadstatus.include(key);
					
					this._loadStatus('preload', {
						element: key,
						status: 'request'
					});
					var myScript = new Asset.javascript(eval('this.options.plugins.' + key), {
						onload: function(){
							
							this._loadStatus('preload', {
								element: key,
								status: 'loaded'
							});
							this.options.loadstatus.erase(key);
							
							if (this.options.loadstatus.length == 0) {
								
								// Templating
								if (key = 'templating') {
									EJS.config({
										ext: '.html'
									});
								}
								
								this._loadStatus('preload', {
									status: 'end'
								});
								this._afterRendering();
							}
						}.bind(this)
					});
				}
			}, this)
		}
	}
			
	,deskError: function(title, text, code){
		
		new Element('div', {
			'html': '<b style="background-color: #67726A; color: #ffffff; line-height:20px;">&nbsp;DESK-JS Fehler:&nbsp;</b> <b>' + title + '</b><br />' + text + '<br /><div style="background-color: #ffffff; margin: 8px; padding: 5px; width: 40%;">' + code + '</div>'
			,'class': 'text'
			,'styles': {
				'position': 'absolute'
				,'width': '100%'
				,'left': 0
				,'top': 0
				,'color': '#67726A'
				,'background-color': '#DFDEDA'
				,'border-bottom': '1px solid #67726A'
				,'padding': '8px'
				,'z-index': 9999
			}
		}).inject(document.body, 'top');
	}
});

/**
 * DESK -> EJS Port
 *  - mit slideraddon
 *  - port zu Loader mittels element und timeout oder deskJS._loadStatus()
 *  
 *  Parameters:
 *    tpl: template objekt/filepath
 *    data: datastore (extend: auch req querys?)
 *    addData: fÃ¼gt ein bestimmtes Objekt oder Array an der Templateumgebung hinzu
 *    reqData: datastore nach dem aktuellen Request / automatisch
 *    nodata: Text sofern keine Daten vorhanden sind html/text/array('de'=, 'en'=)
 *    target: replaceobjekt $()
 *    fxInOptions: Animations-Parameter In
 *    fxOutOptions: Animations-Parameter Out
 *    loader: loaderfunktion $() target mit Timeout
 *    afterRendering: Aufruf nach Rendering
 *  
 *  Methods:
 *    load: laden des datastore/request
 *    loadDone: ladestatus abgeschlossen Ã¼bergabe an _loadStatus und aufruf von build()
 *    build: Einbindung des Template und Slidaktivierung fals gesetzt
 *    loadSeq: Anzeigestart des Template / Ausblenden des Loader
 *    showActivate: Aktivierungsaufruf mit Loadertimeout
 *    fxIn: Anzeigeanimation (template/loader)
 *    fxOut: Ausblendeanimation (template/loader)
 *    getStore: Ausgabe des Aktuellen Requeststore (path: 'result', 'count', 'tblName')
 */
var deskJS_template = new Class({
	
	// implements
	Implements: [Options, Events]
	
	// options
	,options: {
		autoLoad: false
		,tpl: false
		,data: false
		,reqData: {}
		,nodata: 'Leider keine EintrÃ¤ge vorhanden'
		,target: false
		,fxInOptions: {
			duration: 500
			// ,transition: 'bounce:in'
		}
		,fxOutOptions: {
			duration: 500
			// ,transition: 'bounce:out'
		}
		,loader: {
			target: ''
			,timeout: 0
		}
		,afterRendering: false
	}
	
	// initialize
	,initialize: function(options){
		
		this.setOptions(options);
		
		if(!this.options.autoLoad) return; 
		else this.load();
	}
	
	,load: function(){
		
		this.options.target.set('morph', {
			duration: 1
		}).morph({
			opacity: 0
		});
		
		var tl = this.options.loader.target;
		if(tl) this.fxIn(tl, {
			duration:100
		});
		
		deskJS._loadStatus('template', {
			element: this.options.tpl
			,status: 'request'
		});
		
		this.loadStart = $time();
		
		// array = norequest -> lokale Daten
		if(this.options.data.type == 'tree' || this.options.data.type == 'all'){
			deskJS._verzReqStr = this.options.data;
			deskJS._verzReq((function(req){
				if(!$defined(req)) req = {};
				if(this.options.addData) req.addData = this.options.addData;
				this.loadDone(req);
			}).bind(this));
		}else{
			this.options.reqData.result = this.options.data;
			this.options.reqData.addData = this.options.addData;
			this.loadDone();
		}
	}
	
	,loadDone: function(req) {
		
		if(req) this.options.reqData = req;
		
		deskJS._loadStatus('template', {
			element: this.options.tpl
			,status: 'loaded'
		});
		
		this.build();
	}
	
	,build: function(){
		
		var ejsObj = {/*cache: 0*/};
		if($type(this.options.tpl) == 'string') ejsObj.text = this.options.tpl;
		// else if(...) ejsObj.url = this.options.tpl; tpl file
		else ejsObj.text = this.options.tpl.get('html');
		
		if(this.options.reqData) req = this.options.reqData;
		else req = this.options.data;
		
		var htmlOut = new EJS(ejsObj).render(req);
		var nodeM = htmlOut.toDOM();
		
		if (nodeM.length > 1) {
			htmlOut = '<div>' + htmlOut + '</div>';
			var nodeM = htmlOut.toDOM();
		}
		
		// if(!$definde(nodeM[0])) nodeM = this.options.nodata.toDOM();
		
		this.options.target.empty();
		nodeM.inject(this.options.target);
		
		if(this.options.afterRendering) this.options.afterRendering();
		
		this.showActivate();
	}
	
	,showActivate: function(){
		
		var tl = this.options.loader.target;
		
		this.loadEnd = $time();
		
		if ((this.loadEnd - this.loadStart) > this.options.loader.timeout) {
			if (tl) {
				this.fxOut(tl, {
					duration: 100
				});
			}
			this.fxIn(this.options.target);
		} else {
			var newDelay = this.options.loader.timeout - (this.loadEnd - this.loadStart);
			(function(){
				if (tl) {
					this.fxOut(tl, {
						duration: 100
					});
				}
				this.fxIn(this.options.target);
			}.bind(this, tl)).delay(newDelay);
		}
	}
	
	,fxIn: function(el, opt){
		if(!opt) opt = {};
		el.set('morph', $merge(this.options.fxInOptions, opt)).morph({
			opacity: 1
		});
	}
	
	,fxOut: function(el, opt){
		if(!opt) opt = {};
		el.set('morph', $merge(this.options.fxOutOptions, opt)).morph({
			opacity: 0
		});
	}
	
	,getStore: function(path){
		return path == undefined ? this.options.reqData : eval('this.options.reqData.' + path);
	}
});

/**
* DOM - Prerenderer
*  http://mootools.net/forge/p/string_todom
*/
String.implement({
	
	// string to DOM
	toDOM: function(){
		var wrapper =	this.test('^<the|^<tf|^<tb|^<colg|^<ca') && ['<table>', '</table>', 1] ||
				this.test('^<col') && ['<table><colgroup>', '</colgroup><tbody></tbody></table>',2] ||
				this.test('^<tr') && ['<table><tbody>', '</tbody></table>', 2] ||
				this.test('^<th|^<td') && ['<table><tbody><tr>', '</tr></tbody></table>', 3] ||
				this.test('^<li') && ['<ul>', '</ul>', 1] ||
				this.test('^<dt|^<dd') && ['<dl>', '</dl>', 1] ||
				this.test('^<le') && ['<fieldset>', '</fieldset>', 1] ||
				this.test('^<opt') && ['<select multiple="multiple">', '</select>', 1] ||
				['', '', 0];
		var el = new Element('div', {
			html: wrapper[0] + this + wrapper[1]
		}).getChildren();
		while(wrapper[2]--){
			el = el[0].getChildren();
		}
		return el;
	}
	
	// Subsititude von Hash-Obj
	,xtemplate: function(object, regexp){
		tplFunc = function(match, name){
			if (match.charAt(0) == '\\') return match.slice(1);
			var parts = name.split('.');
			var val = object;
			for(var i=0; i < parts.length && ($type(val) == 'object' || $type(val) == 'hash' || $type(val) == 'array'); i++){
				val = val[parts[i]];
			}
			return val == undefined ? '' : $type(val) == 'string' ? val.substitute(object, regexp) : val;
		};
		tplOut = this.replace(regexp || (/\\?\{([^{}]+)\}/g /*cor*/), tplFunc);
		return tplOut;
	}
});

/* Faux Console by Chris Heilmann http://wait-till-i.com */
function c(a){console.log(a);};
if(!window.console) {var console={init:function(){console.d=document.createElement('div');document.body.appendChild(console.d);var a=document.createElement('a');a.href='javascript:console.hide()';a.innerHTML='close';console.d.appendChild(a);var a=document.createElement('a');a.href='javascript:console.clear();';a.innerHTML='clear';console.d.appendChild(a);var id='fauxconsole';if(!document.getElementById(id)){console.d.id=id;}console.hide();},hide:function(){console.d.style.display='none';},show:function(){console.d.style.display='block';},log:function(o){console.d.innerHTML+='<br/>'+o;console.show();},clear:function(){console.d.parentNode.removeChild(console.d);console.init();console.show();},/*Simon Willison rules*/addLoadEvent:function(func){var oldonload=window.onload;if(typeof window.onload!='function'){window.onload=func;}else{window.onload=function(){if(oldonload){oldonload();}func();}};}};console.addLoadEvent(console.init);}

