/**
* web-T::CMS Portal javascript object
* need oStorage
*
* @version 1.1
* @author goshi
* @package javascript::share
*
*	ChangeLog:
*		1.1		12.06.10/goshi	move session object to portal
*		1.0		21.05.10/goshi	add hash method hash.set
*		0.99	14.05.10/goshi	add in ajax response checking for redirect property
*		0.98	05.05.10/goshi	add print method 
*		0.97	20.03.10/goshi	add clearing hash 
*		0.96	10.03.10/goshi	update portal.dom.getAbsPos method - now it return all dimensions of the object 
*		0.95	01.03.10/goshi	update portal.dom.swap method - now it can swap not only inner HTML 
*		0.94	21.02.10/goshi	add dom.getInPos
*		0.93	03.01.10/goshi	add css object, upgrade debug.dump function, add addBlock and has Block methods to the portal.events object
*		0.92	03.01.10/goshi	add dom object (with tools), add to events object new methods
*		0.91	16.07.09/goshi	fix bug with IE, event deattach and callback function
*		0.9	04.05.09/goshi	add debug object into core
*		0.8	03.05.09/goshi	improve event listeners 
*		0.71	02.05.09/goshi	fixes some init bug 
*		0.7	30.04.09/goshi	added events.attach and events.remove methods 
*		0.6	20.04.09/goshi	added vars.langs property 
*		0.5	17.03.09/goshi	added .ready method
*		0.4	13.02.09/goshi	remove bug with page reload and reffer changer
*		0.3	11.02.09/goshi	added portal.storage instance
*/


/* prepare portal object */
function oPortal(){

	this._init();
	
};

/* declare portal prorotype */
oPortal.prototype = {
	
	mess: {},
	vars: {},
	storage: {},
	event : {},	// events object
	lang_id: null,
	lang_nick: null,
	
	_hash : {}, // storage for parsed hash
		
	_init: function(){
	
		// loading language variable
		// if it is not set - try get them throw Ajax
		if (window.mess) this.mess = mess;
		if (window.pphplangs) this.vars.langs = pphplangs;
		// determine friendly URL
		if (window.JsFriendly){ 
			this.vars.friendlyURL = window.JsFriendly;
		} else {
			if (/\w+\.php/i.test(document.location.href))
				this.vars.friendlyURL = false;
			else
				this.vars.friendlyURL = true;
		}
		// gettin lang nick
		if (window.lang_nick){ 
			this.lang_nick = lang_nick;
		} else {
			if (this.vars.friendlyURL){
				this.lang_nick = document.location.href.match(/\/lang\/(\w+)/i);
				
			} else {
				this.lang_nick = document.location.href.match(/\lang=(\w+)/i);
			}
			if (this.lang_nick){
				this.lang_nick = this.lang_nick[1];
			}
		}
		
		// determine current laqnguage
		if (window.lang_id){ 
			this.lang_id = window.lang_id;
		} else if (this.vars.langs){
			// trying to determine current language
			
			// setting active language
			if (this.lang_nick){
				var f_lang = 0;
				for (var i in this.vars.langs){
					if (!f_lang) f_lang = i;
					if (this.vars.langs[i]['title'] == this.lang_nick){
						this.lang_id = i; break;
					}
				}
			}
			
			if (!this.lang_id)
				this.lang_id = f_lang;
		}
		
		this.storage = new oStorage();
		
		this.regulars = regulars;
		
		// check - if URL is the same (anf checking inititalization for storage - IE5-IE7 bug)
		if (this.storage.initialized){
			if (this.storage.get('refferer') && this.storage.get('refferer').toLowerCase() != document.URL.toLowerCase()){
				this.storage.set('old_refferer', this.storage.get('refferer'));
			}
			this.storage.set('refferer', document.URL);
					
		} else {
			var aportal = this;
			syncEvent(function() {
							/*var list = [];
							var attrs = aportal.storage.XMLDocument.documentElement.attributes;
 							
							for(var i=0; i < attrs.length; i++) {
							    alert(attrs[i].name+':'+attrs[i].value);
							}*/
							if (aportal.storage.get('refferer') && aportal.storage.get('refferer') != document.URL){
								aportal.storage.set('old_refferer', aportal.storage.get('refferer'));
							}
							aportal.storage.set('refferer', document.URL);
					},
				'portal.storage.initialized'
			);
		
		}

			
	},
	
	/* execute on DOM ready (after load all images, etc.) */
	ready : function(func){
		domReady(func);
	},
	
	/* events model */
	events : {
	
		attach : function(object, event, handler, useCapture) {
			//alert('attach');
			object['_ev_'+event] = handler;
			if (object.addEventListener) {
				object.addEventListener(event, object['_ev_'+event], useCapture ? useCapture : false);
			} else if (object.attachEvent) {
				object.attachEvent('on' + event, object['_ev_'+event]);
			} else {
				object['on'+event] = object['_ev_'+event];
			}
		},
		
		remove : function (object, event, handler){
		
			if(object.removeEventListener){
				//alert('detah : '+object['_ev_'+event]);
				object.removeEventListener(event, handler ? handler : object['_ev_'+event], false);
			} else if(object.detachEvent) { 
				if (typeof handler != "undefined")
					object.detachEvent('on'+event, handler);
				else
					object.detachEvent('on'+event, object['_ev_'+event]);					
			} else object['on'+event] = false;
	
		},
		
		stop: function (event){
			if (event.preventDefault) {
				event.preventDefault();
				event.stopPropagation();
			} else {
				event.returnValue = false;
				event.cancelBubble = true;
			}
			return false;
		},
				
		defPosition : function(event) { 
			var x = 0, y = 0; 
			if (document.attachEvent != null) {
				x = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft; 
				y = event.clientY + document.documentElement.scrollTop + document.body.scrollTop; 
			} 
			if (!document.attachEvent && document.addEventListener) { // Gecko 
				x = event.clientX + window.scrollX; 
				y = event.clientY + window.scrollY; 
			} 
			return {x:x, y:y}; 
		},
		
		addBlock : function(){
			window['bubble_block'] = true;
		},
		
		hasBlock : function(){
			// when found blocking - then release it and send to checker, that we can't move to the next step
			if (window['bubble_block']){
				window['bubble_block'] = false;
				return false;
			} else return true;
		}
	},
	
	debug : {
		
		_level_del : "\t",
		
		_var_dump : function(data, level){
			
			// add protection for level recursion
			if (parseInt(level.length/portal.debug._level_del.length) > 4) return '...';
			
			var out = level+"";
			try {
				if (typeof data == "string"){
					out += data+"\r\n";
				} else if (typeof data == "object"){
					out += "{\r\n";
					for (var i in data){
						if (typeof data[i] == "object" || typeof data[i] == "array")
							out += i+" : "+portal.debug._var_dump(data[i], level+portal.debug._level_del);
						else
							out += i+"="+data[i]+"\r\n";
					}
					out += " }\r\n";
				} else if (typeof data == "array"){
					out += "[\r\n";
					for (var i=0,cnt=data.length ; i< cnt; i++){
						if (typeof data[i] != "string")
							out += i+" : "+portal.debug._var_dump(data[i], level+portal.debug._level_del);
						else
							out += data[i]+"\r\n";
					}
					out += " ]\r\n";
				}
			} catch (e) {
				// do nothing
			} finally {
				return out;
			}	
			
		},
	
		dump : function (data, inline){
			var out = portal.debug._var_dump(data, "");
			if (typeof inline != 'undefined' && inline){
				var ele = elem('pre', false, false, false);
				if (ele){
					ele.innerHTML = out;
					document.body.appendChild(ele);
				}
			} else 
				alert(out);
		}
	},
	
	/* DOM tools */
	dom : {
		// append element after selected obj
		appendAfter : function(obj,node){
			if(typeof obj=="string"){obj=$_(obj);}; 
			if (obj.nextSibling)
				obj.parentNode.insertBefore(node,obj.nextSibling);
			else
				obj.parentNode.appendChild(node);
		},
		
		getAbsPosition : function(obj){
			if(typeof obj=="string"){obj=$_(obj);}; 
			if (!obj) return {};
			
			var x = 0,y = 0, h = 0, w = 0;
			var source = obj;
			w = obj.offsetWidth;
			h = obj.offsetHeight;
			//document.body.appendChild(elem('div', {'id': 'test'}));
			
			while(obj) {
				x += obj.offsetLeft; 
				y += obj.offsetTop;
				//alert(getStyle(obj, 'position'));
				//$_('test').innerHTML += obj.nodeName + '----' + obj.id+'<br>';
				if ((getStyle(obj, 'position') == 'absolute' || getStyle(obj, 'position') == 'relative')){
				//	$_('test').innerHTML += 'POSITION!<br>';
					//alert(obj.offsetLeft + '---' + obj.offsetTop);
					obj = obj.offsetParent;
				} else
					obj = obj.offsetParent; 
			}
			//$_('test').innerHTML += 'final: '+y+'<br>';
			var sY = self.pageYOffset || (document.documentElement && document.documentElement.scrollTop) || (document.body && document.body.scrollTop);
			var sX = self.pageXOffset || (document.documentElement && document.documentElement.scrollLeft) || (document.body && document.body.scrollLeft);
			
			while (source){
				if (typeof source.scrollLeft != 'undefined'){ 
					sX += source.scrollLeft; 
					sY += source.scrollTop;
				}
				source = source.parentNode; 
			}
			
			return  {'x' : x, 'scrollX' : sX, 'y' : y, 'scrollY' : sY, 'h' : h, 'w' : w};
		},
		
		/* getting in window position of the element */
		getInPos : function(obj, eX, eY, cPadding){
		
			if(typeof obj=="string"){obj=$_(obj);}; 
		
			var cW = getClientWidth();
			var cH = getClientHeight();
			var oW = obj.offsetWidth;
			var oH = obj.offsetHeight;
			
			if (typeof cPadding == "undefined")
				cPadding = 5;
				
			var res = {'x' : 0, 'y' : 0}
			
			if (eX + oW + cPadding > cW && eX - oW - cPadding > 0){
				res.x = eX - oW - cPadding;
			} else if (eX + oW + cPadding <= cW) {
				res.x = eX + cPadding;	
			} else {
				res.x = cW - oW - cPadding;	
			}
			
			if (eY + oH + cPadding > cH && eY - oH - cPadding > 0){
				res.y = eY - oH - cPadding;
			} else if (eY + oH + cPadding <= cH) {
				res.y = eY + cPadding;
			} else {
				res.y = cH - oH - cPadding;
			}
			
			return res;
		},
				
		clone : function(source, target, clonePosition){
		
			if(typeof source=="string"){source=$_(source);};
			if(typeof target=="string"){target=$_(target);};
			if(!source || !target){return null;};
			
			for (var i=0, max=source.childNodes.length; i < max; i++){
				var clone1=source.childNodes[i].cloneNode(true);
				target.appendChild(clone1);
			}
			
			// make clone position of the cloned element
			if (typeof clonePosition != 'undefined' && clonePosition){
				target.style.position = 'absolute';
				var offsets = portal.dom.getAbsPosition(source);
				
				//alert(offsets['y'] + '---' + offsets['scrollY']);
				target.style.top    = (offsets['y']) + 'px';
				target.style.left   = (offsets['x']) + 'px';
				target.style.width  = source.offsetWidth + 'px';
				target.style.height = source.offsetHeight + 'px'; 
			}
		},
		
		/* flag moveall helps to move always each element */
		swap : function(element1, element2, moveall){
		
			if(typeof element1=="string"){element1=$_(element1);};
			if(typeof element2=="string"){element2=$_(element2);};
			if(!element1 || !element2){return null;};
			
			// check - if we have swapping all objects - then simply swap places of it
			if (typeof moveall != 'undefined' && typeof moveall != 'null' && moveall){
				var nextSibling = element1.nextSibling;
				var parentNode = element1.parentNode;
				element2.parentNode.replaceChild(element1, element2);
				parentNode.insertBefore(element2, nextSibling);
			} else {
				for (var i=0, max=element1.childNodes.length; i < max; i++){
					var clone1=element1.childNodes[i].cloneNode(true);
					var clone2=element2.childNodes[i].cloneNode(true);
					var replaced1=element1.replaceChild(clone2, element1.childNodes[i]);
					var replaced2=element2.replaceChild(clone1, element2.childNodes[i]);
				}
			}
		}
	},
	
	hash : {
	
		set : function(hash){
			document.location.hash = hash;
		},

	
		parse : function(){
			var result = {};
			var url = document.location.hash;
	 		var parameters = url.slice(url.indexOf('#') + 1).split('&');
	 		
	 		if (parameters.length > 0){
		 		for(var i = 0;  i < parameters.length; i++) {
		 			var parameter = parameters[i].split('=');
		 			result[parameter[0]] = parameter[1];
		 		}
		 		
		 		// saving in protected property for future use
	 			this._hash = result;
	 		}
	 		
	 		return result;
		},
		
		clear : function (){
		
			if (document.location.hash)
				document.location.hash = 'none'; //window.location = window.location.href.replace( /#.*/, "");
		
		}
	},
	
	
	ajax : {
		/**
		* load pages with parameters
		* you can set either id,lang_id or url params
		* @param object $e event object
		* @param int $params.id[option] id of the page for page
		* @param int $params.lang_id[option] language identifier of page
		* @param string $params.url[option] url of the page (it is preferedto user it) 
		* @param function $callback[option] function for callback 
		* @param bool $nohashadd[option] flag for adding hash to the URL 
		*/
		'load' : function(e, params, callback, nohashadd){
			var req = new JsHttpRequest();
			
			req.onreadystatechange = function (){
					
				if (req.readyState == 4){
		
					if (req.responseJS.status == 200){
					
						// checking for redirect
						if (typeof req.responseJS.redirect != 'undefined'){
							document.location.href = req.responseJS.redirect;
							return;
						}
					
						// calling callback function with closures
						if (typeof callback == 'function')
							callback(e, req.responseJS.response, params);
					}
						
				}
		
			}
			
			var hash = [];
			(params['pid'] ? hash[hash.length] = 'id='+params['id'] : '');
			(params['url'] ? hash[hash.length] = 'url='+params['url'] : '');
			
			if (!(typeof nohashadd != 'undefined' && nohashadd))
				document.location.hash = hash.join('&');
			
			req.open(typeof params['method'] != 'undefined' && params['method'] == 'post' ? 'POST' : 'GET', '/ajax.php', true);
			req.send({'resource' : 'content', 'params' : params});
		}
	
	},
	
	css : {
	
		// class manipulation functions
		hasClass : function(ele,cls) {
			if (!ele || ele == null) return false;
			if(typeof ele=="string"){ele=$_(ele);};
			return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
		},
		
		addClass : function(ele,cls) {
			if (!ele || ele == null) return false;
			if(typeof ele=="string"){ele=$_(ele);};
			if (!portal.css.hasClass(ele,cls)) ele.className += " "+cls;
		},
		
		removeClass : function(ele,cls) {
			if (!ele || ele == null) return false;
			if(typeof ele=="string"){ele=$_(ele);};
			if (portal.css.hasClass(ele,cls)) {
				var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
				ele.className=ele.className.replace(reg,' ');
			}
		}
	
	},
	/** 
	* print page
	*/
	print : function (){
		
		var dochead = getLikeElements('head');
		if (dochead && dochead.length > 0){
			// append #print symbol to the hash for copying link and parsing it
			document.location.hash = 'print';
			dochead[0].appendChild(elem('link', {'rel' : 'StyleSheet', 'href' : '/css/project/print-src.css', 'type' : 'text/css'}));
			// now - print document
			if (window.print)
				window.print();
		}
			
	},
	
	session : {
		
		/** 
		* Session cookie prototype 
		* @version 0.2
		*
		* Changelog:
		*	0.2	10.11.08/goshi	remove bug with initial setting for session cookie
		*	0.1	10.11.08/goshi
		*/

		// because session data is dynamic - we must not set _values for long time - only for temporary cache for updating
		_session_name : 'webT',
		
		_values: false,
		
		_init: function(){
			this._values = portal.storage.get(this._session_name, 'object');
			
			if (typeof this._values == 'undefined' || this._values == false){				
				this._values = new Object();
				portal.storage.set(this._session_name, this._values, 'object');						
			}
			
			// setting up switchers			
			if (typeof this._values['switchers'] == 'undefined'){
			
				this._values['switchers'] = new Object();
				this.set('switchers', this._values['switchers']);
				
			}
		},
		
		get: function(valueName){
		
			if (this._values == false) this._init();
		
			this._values = portal.storage.get(this._session_name, 'object');
			if (typeof this._values[valueName] != 'undefined' && this._values[valueName] != ''){
				return this._values[valueName];
			}
		},
		
		set: function(valueName, value){
		
			if (this._values == false) this._init();

			this._values = portal.storage.get(this._session_name, 'object');
			this._values[valueName] = value;
			portal.storage.set(this._session_name, this._values, 'object');
		}
	
	}


};

var portal = new oPortal();
