var _Class  = function (proto)
{
    var obj = function()
    {
        this.init.apply(this, arguments)
    };

    obj.prototype               = proto;
    obj.prototype.constructor   = obj;

    return obj;
};


//initialize output content
function init_content(root){

	var tags;

	if(tags=_(root, "~@script")){
		for(var i=0, l=tags.length; i<l; i++){
			//if((tags[i].type=="ajax/javascript")){
			if(root!=document){
				var func=(new Function(tags[i]?tags[i].innerHTML:""));
				if(!tags[i].src) func.apply(tags[i]); //normal script execution
				else try{func.apply(tags[i])}catch(e){Script.preload(tags[i])}; //modular script execution
			}
		}
	}

	if(tags=_(root, "~@form")){
		for(var i=0, l=tags.length; i<l; i++){
			var tag=tags[i];

			//attach ajax GET handler
			if(_ATTR(tag, "lang")=="ajax") tag.aref=_ATTR(tag, "action");
			if(tag.aref && tag.aref.indexOf("?")!=-1){
				var func_submit=tag.onsubmit?_EV(tag, "onsubmit"):false;
				tag.onsubmit=function(event){if(!func_submit || (func_submit && func_submit())) GET(this, event); return false};
				if(_ATTR(tag, "autoload")!=undefined) tag.onsubmit();
			}
		}
	}

	if(tags=_(root, "~@a")){
		for(var i=0, l=tags.length; i<l ;i++){
			var tag=tags[i];

			//attach ajax GET handler
			if(_ATTR(tag, "aref")) tag.aref=_ATTR(tag, "aref");
			if(tag.aref && tag.aref.indexOf("?")!=-1 && !tag.onclick){
				if(!tag.href) tag.href="#"; //set empty href value <a href="#"> (for non IE)
				tag.onclick=function(event){ return GET(this, event)};
				if(_ATTR(tag, "autoload")!=undefined) tag.onclick();
			}


			if(_ATTR(tag, "type")=="submit"){ //tag as submit button
				var inp=document.createElement("input");
				inp.type="submit";
				CSS(inp).set({visibility:"hidden", position:"absolute"});
				tag.appendChild(inp);
				tag.onclick=function(){_(this, "/form").onsubmit()};
			}
		}
	}


	if(tags=_(root, "~@select")){
		for(var i=0, l=tags.length; i<l ;i++){
			new Forms.select(tags[i]);
		}
	}


};


Forms={};

//input functions
Forms.input=function(obj){
	var _this=this;

	this.init=function(){
		obj.onfocus=null;
		if(obj.getAttribute("mask")){
			addEvent(obj, "keyup", function(event){_this.mask(this)});
			addEvent(obj, "blur", function(event){_this.mask(this)});
		}
		if(obj.getAttribute("onenterkey")){
			addEvent(obj, "keyup", function(event){if(_this.isEnter(event)) _EV(this,'onenterkey')()});
		}
		if(obj.getAttribute("default")!=undefined){
			this.setDefault(obj);
		}

		return this;
	};

	//apply RegExp mask onkey up
	this.mask=function(obj){
		var re=new RegExp("[^"+obj.getAttribute("mask")+"]","gi");
		obj.value=obj.value.replace(re,"");
	};

	//check enter key
	this.isEnter=function(event){
		return (window.event?window.event.keyCode:event.which)==13;
	};

	//init default input value & input styles
	this.setDefault=function(obj){
		function setOpt(obj){
			if(obj.def_opt) CSS(obj).set(obj.def_value==obj.value?obj.def_style:obj.def_opt);
		};
		//init
		if(!obj.def_value){
			var opt=_ATTR(obj,"default");
			if(opt && /^{[^}]*}$/.test(opt)){
				obj.def_opt=(new Function("return "+opt))();
				obj.def_value=obj.value=obj.getAttribute("value") || obj.value;
				obj.def_style=CSS(obj).get(obj.def_opt);
			}
			else if(opt) obj.def_value=obj.def_text=opt;
			addEvent(obj, "focus", function(){_this.setDefault(this)});
			addEvent(obj, "blur", function(){if(!this.value) this.value=this.def_value; setOpt(this)});
		}
		//execute
		//alert(obj.name+": "+obj.def_value+" -- "+obj.value);
		if(obj.def_value==obj.value) obj.value=obj.def_text?obj.def_text:"";
		setOpt(obj);

	};
	return this.init();
};



//Custom select control
//--------------------------------
//> INITIALIZE
//  new Select(select_obj)

Forms.select=function(obj){
	var _this=this,
		cur_act,
		inInit=true,
		isOver=false,
		isOpen=false;

	obj.style.display="none";


	var inherit_width=CSS(obj).get("width");

	var block=document.createElement("span");
	block.className="select "+obj.className;
	block.onmouseover=function(){isOver=1};
	block.onmouseout=function(){isOver=0};

	//create hidden input element for submit
	var element=document.createElement("input");
	element.type="hidden";
	element.value=obj.value;
	element.name=obj.name;
	element.id=obj.id;
	element.disabled=obj.disabled;
	element.aref=_ATTR(obj, "aref");
	element.target=_ATTR(obj, "target");
	element.onchange=obj.onchange;
	element.onblur=obj.onblur;
	element.autoload=(_ATTR(obj,"autoload")!=undefined);
	element.className="";
	element.update=function(){update(element)};
	element.reset=function(){set(element.defaultElement)};
	element.disable=function(b){disable(b)};
	block.input=element;
	block.appendChild(element);


	var field=document.createElement("span");
	field.className="field";
	var arrow=document.createElement("span");
	arrow.className="arrow";
	field.appendChild(arrow);
	var content=document.createElement("span");
	content.innerHTML="&nbsp;";
	field.appendChild(content);
	block.appendChild(field);
	field.onclick=function(){return showhide()};

	var dropdown=document.createElement("span");
	dropdown.className="dropdown";

	element.root=block;
	element.field=field;
	element.options=[];
	if(obj.options.length)
		for(var i=0; i<obj.options.length; i++) {
			var a=document.createElement("a");
			a.innerHTML=obj.options[i].innerHTML?obj.options[i].innerHTML:"&nbsp;";
			a.className="item "+obj.options[i].className;
			a.value=obj.options[i].value;
			a.onclick=function(){return set(this);};
			CSS(a).set({display:"block", whiteSpace:"nowrap", textDecoration:"none"});
			//CSS(a).copy("color", obj.options[i]);
			element.options.push(a);
			if(obj.options[i].selected || obj.value==a.value) element.selected=element.defaultElement=a;
			if(_ATTR(obj.options[i],"image")){
				var img=document.createElement("img");
				img.src=_ATTR(obj.options[i],"image");
				a.insertBefore(img, a.firstChild);
			}
			dropdown.appendChild(a);
		}
	block.appendChild(dropdown);
	setTimeout(function(){create()},12); //replace select to custom select after initializing


	var create=function(){
		if(!obj || !obj.parentNode) return false;

		obj.parentNode.replaceChild(block, obj);

		if(!_this.constructor.array) _this.constructor.array=[];
		_this.constructor.array.push(block); //add to constructor array (Forms.select.array)

		//overwrite styles

		CSS(block).set({position:"relative", textDecoration:"none"});
		if(BROWSER.ie){
			//fix z-index for IE
			var zIndex=100-_this.constructor.array.length;
			CSS(block).set({zIndex:zIndex});
			CSS(block.parentNode).set({zIndex:zIndex});
		}
		CSS(field).set({whiteSpace:"nowrap", cursor:"default"});
		CSS(content).set({cursor:"default"});
		CSS(dropdown).set({position:"absolute", visibility:"hidden", overflow:"auto", left:"-"+CSS(block).get("borderLeftWidth"), zIndex:2});
		CSS(arrow).set({position:"absolute", display:"block", top:0, right:0, cursor:"pointer", height:block.clientHeight+"px", zIndex:1});

		if(inherit_width!="auto" && block.clientWidth<10){
			block.style.width=inherit_width;
		}

		//CSS(dropdown).set({top:block.clientHeight+"px"});

		if(element.disabled) disable(1);

		if(obj.options.length){
			element.selected ? set(element.selected) : set(element.options[0]); //set default or act
			addEvent(document,"mouseup", function(){if(isOpen && !isOver) setTimeout(function(){showhide(0)},40)}); //define exernal click event
		}

		CSS(dropdown).set({width:block.clientWidth+"px"});
		autoInlineWidth();

		inInit=false;
	};


	var autoInlineWidth=function(){
		if(CSS(block).check({display:"block"})) return false; //control is block
		field.style["paddingRight"]=0;
		var offset=dropdown.scrollWidth-field.offsetWidth-parseInt(CSS(field).get("marginRight"))-parseInt(CSS(field).get("marginLeft"));
		if(offset>0) field.style["paddingRight"]=offset+"px";
	};



	var showhide=function(d){
		if(element.disabled) return false;
		if(parseInt(CSS(dropdown).get("height"))>=dropdown.scrollHeight) CSS(dropdown).set({height:"auto"}); //if scroll bar = auto height
		if(d==undefined) d=dropdown.style.visibility!="visible";
		dropdown.style.visibility=d?"visible":"hidden";

		_this.isOpen=isOpen=d;
		return false;
	};


	var set=function(obj){
		element.prevValue=element.value;
		element.value=obj.value;
		element.selected=obj;
		content.innerHTML=obj.innerHTML;

		autoInlineWidth();
		showhide(0);

		if((!inInit && element.prevValue!=element.value) || element.autoload){
			if(element.onchange) element.onchange(); //call onchange event
			if(element.onblur) element.onblur(); //call onchange event
			if(element.aref) GET(element); //call onchange event
		}

		//act element in dropdown
		if(cur_act) Style(cur_act).remove("act");
		Style(obj).add("act");
		cur_act=obj;

		return false;
	};

	var update=function(element){
		//Style(element.field)[element.disabled?"add":"remove"]("disabled");
		for(var i=0; i<element.options.length; i++) {
			if(element.options[i].value==element.value){
				set(element.options[i]);
				break;
			}
		}
	};

	var disable=function(b){
		element.disabled=b;
		CSS(block).set({opacity:b?0.5:1});
	};



	return this;
};



//© <stipuha /> development (2008)
//--------------------------------
//CLIENT CONFIGURATION
//--------------------
// define aref="?key1=value&key2=(this.value)&key3=(func())" (get query)
// define target="uid123" (unique tag id for ajax content)
// define autoload (automatic send get query on load content)
// define onstarting="func()" (event calling before ajax sending)
// define oncomplete="func()" (event calling when content already loaded)

//SERVER CONFIGURATION
//--------------------
// define $RESPONSE["complete"]=1 (condition for execute oncomplete function after POST query)
// define $RESPONSE["alert"]="message message message" (condition for open system information popup)



//> HTMLAJAX functionality
//----------------------------------
var HTMLAJAX=function(obj, event){
	var _this=this;

	this.init=function(){
		this.obj=obj;
		//init vars
		this.target=_(_ATTR(obj,"target"));
		this.indicatorShow=eval(_ATTR(obj,"indicator"));
		this.onstarting=_EV(obj,'onstarting','event, request');
		this.oncomplete=_EV(obj,'oncomplete','response');
		this.onfailure=_EV(obj,'onfailure','response');
		//init ajax
		(this.req=new AJAX()).onready=function(response){_this.onready(response)};
		this.cache_time=_ATTR(obj,"cache")||_ATTR(obj.cache_obj,"cache");

		return this;
	};

	this.exec=function(){
		if(this.target) this.target.call_func=this.constructor.lastCall; //attach call ajax on target

		//execute sender callback function
		if(this.onstarting(event, this.req.hash)==false) return false; //break if onstarting event return false

		//execute predefined basic operations
		if(this.constructor.onrequest(this.req.hash, this)==false) return false; //break if onbeforesend function  return false

		//try to set cache
		if(this.cache_time) this.constructor.cache.set(this.cache_time, this.req, this.obj||this.obj.cache_obj);

		this.indicator(1);

		if(this.obj.in_process) return false;
		this.obj.in_process=true;

		this.req.send();
		return false;
	};

	this.onready=function(response){
		if(window.DEBUGGER_ENABLED)
			this.constructor.debug.add(response?"(target="+this.obj.target+")\n"+"["+this.req.query+"]\n"+"\n----------\n"+response.obj+"\n----------\n"+response.text:"\nNO RESPONSE!\n");

		this.command_failure=!response || (response.obj.complete!=undefined && !Number(response.obj.complete)) || response.obj.failure;

		if(this.target && !this.command_failure){
			this.target.innerHTML=response.text; //if echo -- write innerHTML
			if(response.obj) this.targetProp(this.target, response.obj.target); //if target properties in response exist set properties to target
			if(window.init_content) init_content(this.target);
		}

		this.indicator(0);
		this.obj.in_process=false;

		this.act();

		//execute predefined basic operations
		this.constructor.onresponse(response, this);

		//execute sender callback function
		if(!this.command_failure) this.oncomplete(response);
		else this.onfailure(response);

	};

	this.targetProp=function(target, props){
		if(props)
			for(var i in props)
				target[i]=props[i];
	};

	//show global ajax loading icon
	this.indicator=function(b){
		if(this.constructor.loader) this.constructor.loader.style.display=b?"block":"none";
		if(this.target){
			CSS(this.target).set({opacity:b?0.5:1});
			if(this.indicatorShow){
				if(b) this.target.defaultHeight=this.target.style.height || "auto";
				this.target.style.height=b?this.target.clientHeight+"px":this.target.defaultHeight;
				if(b) this.target.innerHTML=this.constructor.loader?this.constructor.loader.alt:"...";
			}
		}
		return false;
	};

	//parse ajax referer link (ARL=aref)
	this.url2query=function(url){
		if(!url) return "";
		var file=url.replace(/([^?]*\/)*([^?]*)\??.*/,"$2"); //get file name
		if(file) this.req.file=file; //overwrite ajax handler file name
		url=url.replace(/[^?]*\??/,""); //get query [a=1&b=2&c=3]
		if(!url) return "";
		url=this.func2query(url); //check & try to execute function in query
		return url;
	};

	//parse form fields & create hash params
	this.form2query=function(form){
		if(!form.elements) return {};
		var hash={};
		for(var i=0;i<form.elements.length;i++){
			if(!form.elements[i]) continue;
			if(form.elements[i].tagName=="FIELDSET" || form.elements[i].tagName=="OBJECT") continue;
			if(form.elements[i].type=="checkbox") hash[form.elements[i].name]=(form.elements[i].checked?1:0);
			else if(form.elements[i].type=="radio"){ if(form.elements[i].checked) hash[form.elements[i].name]=form.elements[i].value;}
			else if(form.elements[i].type=="file") hash[form.elements[i].name]=form.elements[i];
			else hash[form.elements[i].name]=form.elements[i].value;
		}
		return hash;
	};

	//for function in query (dynamic executeble query)
	this.func2query=function(url){
		var dyn=url.match(/&?[a-z0-9_]+=\(%?[^&]+\)/gi);
		if(dyn && dyn.length){
			for(var i=0,a,l=dyn.length;i<l;i++){
				a=dyn[i].split(/=/);
				var ue=false;
				if(ue=/^\(%/.test(a[1]))a[1]=a[1].replace(/^\(%/, "("); //unescape definition
				var hash={};
				var key=a[0].replace(/&/,"");
				var value=(new Function('return '+a[1])).apply(obj);
				hash[key]=value;
				var res="";
				res=this.req.json2query(hash);
				if(ue && typeof res=="string") res=unescape(res);
				url=url.replace(/&?[a-z0-9_]+=\(%?[^&]+\)/i, res); //add value to query
			}
		}
		return url;
	};


	// activate item on click (set className="act")
	this.act=function(){
		var obj=this.obj;
		if(!obj || !obj.tagName || !obj.parentNode) return false;
		if(_ATTR(obj, "noact")!=undefined) return false;
		var par=(obj.parentNode.tagName=="LI" ? obj.parentNode.parentNode : obj.parentNode);
		if(!par.set) par.set=function(i){return _(par, '~@a')[i].onclick();}; //init funtion [set]
		if(!par.act) par.act=function(i){return _act(_(par, '~@a')[i]);}; //init funtion [set]
		if(!par.unset) par.unset=function(){Style(par.cur).remove("act"); par.cur=null; return false;}; //init funtion [set]
		if(par.cur==obj) return false;
		if(!par.cur) par.cur=_(par, "a.act"); // if no [cur] try to find it
		if(par.cur) Style(par.cur).remove("act");
		Style(obj).add("act");
		par.cur=obj;
		(_ATTR(obj, "onact") || function(){})(); //call [onact] event
		return false;
	};

	return this.init();
};

HTMLAJAX.loader=null; //ajax loader icon
HTMLAJAX.lastCall=null; //last request which call ajax
HTMLAJAX.onrequest=function(request, htmlajax){}; //function is called before request sended
HTMLAJAX.onresponse=function(response, htmlajax){}; //function is called when response complete

//HTMLAJAX CACHE control functionality
HTMLAJAX.cache={
	MULTIPLIER:60*1000, // set cache in [minutes]
	from:(new Date()).getTime(),
	init:function(cache_time){
		var cache_param={};
		var ts=(new Date()).getTime();
		cache_param.period=Number(cache_time=="*"?CACHE_DEFAULT:cache_time);
		cache_param.start=ts;
		cache_param.end=ts+cache_param.period*this.MULTIPLIER;
		return cache_param;
	},
	expire:function(cache_param){ //check cache time out
		var ts=(new Date()).getTime();
		if(cache_param.end<ts || cache_param.start<this.from){ //if cache time out replace cache params (start & end)
			cache_param.start=ts;
			cache_param.end=this.init(cache_param.period).end;
			return true;
		}
		return false;
	},
	set:function(cache_time, ajax, cache_obj){
		// from tag:  cache="5" (5 minutes cache) || cache="*" (default cache)
		if(cache_time && cache_obj){
			if(!cache_obj.cache_param) cache_obj.cache_param=this.init(cache_time);
			if(!this.expire(cache_obj.cache_param) && !cache_obj.nocaching) ajax.caching=true;
		}
	},
	reset:function(){this.from=(new Date()).getTime()}
};



//>-------------------------------
//> AJAX debugger console
//> Calling: ctrl+shift+q
HTMLAJAX.debug={
	win:null,
	data:'',
	init:function(){
		var _this=this;
		//attach debugger window call on key combination
		addEvent(document, "keyup", function(e){
			var ev=e?e:window.event;
			var key=ev.keyCode?ev.keyCode:ev.which;
			//alert(ev.ctrlKey+","+ev.shiftKey+","+ev.altKey+","+key);	//ctrl+shift+q
			if(ev.ctrlKey  && ev.shiftKey  && (key==113 || key==81 || key==17) ) _this.winopen();
		});
		this.inited=1;
	},
	winopen:function(){
		this.win=window.open('', 'debug', 'scrollbars=no,status=yes,resizable=yes,width=780,height=560');
		this.load();
	},

	load:function(){
		this.win.document.open();
		this.win.document.write("<title>AJAX debugger</title><input type='button' value='refresh' onclick='window.opener.HTMLAJAX.debug.load()' /><div style='width:100%;height:95%;overflow-y:auto; border:1px solid #555; font:12px \"Courier New\"'>"+this.data+"</div>");
		this.win.document.close();
	},

	add:function(txt){
		if(!this.inited) this.init();
		txt=txt.replace(/={20,}/g,"");
		txt=txt.replace(/</g,"&lt;");
		txt=txt.replace(/>/g,"&gt;");
		txt=txt.replace(/\t/g,"&nbsp; ");
		var now=new Date();
		this.data+="["+this._0(now.getHours())+":"+this._0(now.getMinutes())+":"+this._0(now.getSeconds())+"]\n";
		this.data+="====================\n";
		this.data+=o2s(txt)+"\n\n\n";

		this.data=this.data.replace(/\n/g,"<br />");
	},

	_0:function(num){return (num<10?"0"+num:num)}
};



// main handler
function GET(obj, event){
	if(!window.AJAX_HANDLER) return false;
	//HTMLAJAX.lastCall=function(e){window["GET"](obj,e)};

	var htmlajax=new HTMLAJAX(obj, event); /*init parent class*/
	htmlajax.req.file=AJAX_HANDLER;
	htmlajax.req.query=htmlajax.url2query(obj.ref||obj.aref||_ATTR(obj,"aref")||_ATTR(obj,"href")||_ATTR(obj,"action")); //set query params
	if(obj.tagName=="FORM") htmlajax.req.hash=htmlajax.form2query(obj);
	if(obj.nodeType!=1 && obj.hash) htmlajax.req.hash=obj.hash;
	if(!htmlajax.req.query && !obj.hash) return false; //exit if no parameters
	return htmlajax.exec();
};


HTMLAJAX.loader=null; //ajax loader icon
HTMLAJAX.lastCall=null; //last request which call ajax
HTMLAJAX.onrequest=function(request, htmlajax){}; //function is called before request sended
HTMLAJAX.onresponse=function(response, htmlajax){}; //function is called when response complete

//HTMLAJAX CACHE control functionality
HTMLAJAX.cache={
	MULTIPLIER:60*1000, // set cache in [minutes]
	from:(new Date()).getTime(),
	init:function(cache_time){
		var cache_param={};
		var ts=(new Date()).getTime();
		cache_param.period=Number(cache_time=="*"?CACHE_DEFAULT:cache_time);
		cache_param.start=ts;
		cache_param.end=ts+cache_param.period*this.MULTIPLIER;
		return cache_param;
	},
	expire:function(cache_param){ //check cache time out
		var ts=(new Date()).getTime();
		if(cache_param.end<ts || cache_param.start<this.from){ //if cache time out replace cache params (start & end)
			cache_param.start=ts;
			cache_param.end=this.init(cache_param.period).end;
			return true;
		}
		return false;
	},
	set:function(cache_time, ajax, cache_obj){
		// from tag:  cache="5" (5 minutes cache) || cache="*" (default cache)
		if(cache_time && cache_obj){
			if(!cache_obj.cache_param) cache_obj.cache_param=this.init(cache_time);
			if(!this.expire(cache_obj.cache_param) && !cache_obj.nocaching) ajax.caching=true;
		}
	},
	reset:function(){this.from=(new Date()).getTime()}
};


//>-------------------------------
//> AJAX debugger console
//> Calling: ctrl+shift+q
HTMLAJAX.debug={
	win:null,
	data:'',
	init:function(){
		var _this=this;
		//attach debugger window call on key combination
		addEvent(document, "keyup", function(e){
			var ev=e?e:window.event;
			var key=ev.keyCode?ev.keyCode:ev.which;
			//alert(ev.ctrlKey+","+ev.shiftKey+","+ev.altKey+","+key);	//ctrl+shift+q
			if(ev.ctrlKey  && ev.shiftKey  && (key==113 || key==81 || key==17) ) _this.winopen();
		});
		this.inited=1;
	},
	winopen:function(){
		this.win=window.open('', 'debug', 'scrollbars=no,status=yes,resizable=yes,width=780,height=560');
		this.load();
	},

	load:function(){
		this.win.document.open();
		this.win.document.write("<title>AJAX debugger</title><input type='button' value='refresh' onclick='window.opener.HTMLAJAX.debug.load()' /><div style='width:100%;height:95%;overflow-y:auto; border:1px solid #555; font:12px \"Courier New\"'>"+this.data+"</div>");
		this.win.document.close();
	},

	add:function(txt){
		if(!this.inited) this.init();
		txt=txt.replace(/={20,}/g,"");
		txt=txt.replace(/</g,"&lt;");
		txt=txt.replace(/>/g,"&gt;");
		txt=txt.replace(/\t/g,"&nbsp; ");
		var now=new Date();
		this.data+="["+this._0(now.getHours())+":"+this._0(now.getMinutes())+":"+this._0(now.getSeconds())+"]\n";
		this.data+="====================\n";
		this.data+=o2s(txt)+"\n\n\n";

		this.data=this.data.replace(/\n/g,"<br />");
	},

	_0:function(num){return (num<10?"0"+num:num)}
};


//© <stipuha /> development (2008)
//> AJAX
//--------------------------------
//  ___example#1___
//  (req=new Ajax()).onready=function(response){ready_func(response)};
//	req.file="index.php";
//	req.query="abc=123&def=456";
//	req.send();
//
//  ___example#2___
//	new Ajax({
//		file:"index.php",
//		query:"abc=123&def=456",
//		onready:function(response){ready_func(response)},
//		send:1
//	});


(AJAX=function(opt){this.init.apply(this, arguments)}).prototype={

	CACHE:{},

	init:function(opt){
		opt=opt || {};
		this.method=opt.method || "http";
		this.file=opt.file || "";
		this.query=opt.query || "";
		this.caching=opt.caching || false;
		this.hash=opt.hash || {};
		this.onready=opt.onready || function(){};
		if(opt.onready) this.send();
	},

	send:function(){
		//add hash to query
		this.query+=this.json2query(this.hash);
		//if cache==true > call data from cache & return
		try{if(this.caching && this.CACHE[this.query]) return this.ondata(this.CACHE[this.query]);}catch(e){};

		var _this=this;
		var request, response;
		var SID=(new Date()).getTime()+Math.round(Math.random()*1000);

		switch(this.method){
			case "http":
				request=window.XMLHttpRequest?new XMLHttpRequest():(new ActiveXObject("Msxml2.XMLHTTP") || null); // ||"Microsoft.XMLHTTP" - ie5x
				if(request){
					request.open('POST', this.file, true);
					request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // $_POST[] || $_REQUEST[]
					request.onreadystatechange=function(){
						if(request.readyState==4){
							if(request.getResponseHeader('Content-Type') && request.getResponseHeader('Content-Type').indexOf("/xml")!=-1) response=_this.xml2json(request); //xml
							else response=(new Function('return '+request.responseText))(); //json
							_this.ondata(response);
						}
					};
					request.send(this.query); //request send
					break;
				}

			case "script":
				request=document.createElement("script");
				if(request){
					request.id=SID;
					var src=this.file+"?"+"_scriptID_="+request.id+"&"+this.query;
					if(BROWSER.ie) request.src=src.substr(0,2048); //MAX msie:2kb
					else{request.src=src; request.src=request.src.substr(0,4096)}; //MAX gesko:4Kb
					request.onreadystatechange=function(response){
						if(response && !response.initEvent){
							_this.ondata(response);
							setTimeout(function(){request.parentNode.removeChild(request)},13);
						}
					};
					document.body.appendChild(request); //request send
					break;
				}

			case "form":
				var request=document.createElement(BROWSER.ie?"<iframe name="+SID+">":"iframe");
				if(request){
					request.name=SID;
					request.style.position="absolute";
					request.style.visibility="hidden";
					this.form.appendChild(request);
					//this.form.encoding="multipart/form-data";
					this.form.method="post";
					this.form.target=request.name;
					this.form.action=this.file+this.form.action.replace(/.*(\?.*)$/,"$1");
					request.onreadystatechange=request.onload=function(response){
						if(!request.readyState || request.readyState=="complete"){
							_this.ondata((new Function('return '+request.contentWindow.document.body.innerHTML))());
							setTimeout(function(){request.parentNode.removeChild(request)},13);
						}
					};
					this.form.submit(); //request send
					break;
				}

			default: return request;
		}
	},

	ondata:function(response){
		if(this.caching || this.CACHE[this.query]) this.CACHE[this.query]=response; //cache response data
		this.response=response;
		this.onready(response);
	},

	json2query:function(hash, pref){
		var query="";
		for(var i in hash){
			if(!i) continue;
			var key=(pref?pref+"["+i+"]":i);
			query+=(typeof hash[i]=="object" ? this.json2query(hash[i],key) : "&"+key+"="+hash[i].toString().replace(/&/g, "%26"));
		}
		return query;
	},

	xml2json:function(request){
		var parseXML=function(node){
			if(node.childNodes.length==1 && (node.firstChild.nodeType==3 || node.firstChild.nodeType==4)) return node.firstChild.data; //if text node
			var hash={};
			for(var i=0, childs=node.childNodes, l=childs.length; i<l; i++)
				if(childs[i].nodeType==1)
					if(hash[childs[i].tagName]){ //if node has array type
						if(typeof hash[childs[i].tagName]=="string" || (typeof hash[childs[i].tagName]=="object" && !hash[childs[i].tagName].length))
							hash[childs[i].tagName]=[hash[childs[i].tagName]]; //reinit node (set array type)
						hash[childs[i].tagName][hash[childs[i].tagName].length]=parseXML(childs[i]);
						}
					else hash[childs[i].tagName]=parseXML(childs[i]);
			return hash;
		};
		var doc=BROWSER.ie?request.responseXML:(new DOMParser()).parseFromString(request.responseText, "text/xml"); //get XML content
		var response={obj:{}, text:''};
		if(doc && doc.documentElement) response.obj=parseXML(doc);
		return response;
	},

	onerror:function(message){alert("Server output error...\n"+message)}
};



var initGeneral = function()
{
    init_content(document);
}

window.addEventListener('load', initGeneral, false);
