Ask = function(obj, opt){
	Ask.fireEvent('start', obj);
	opt = opt||{};
	obj.rTicket = rTicket;
	opt.url = opt.url || location.href;
	var myfn = opt.onComplete;
	opt.onComplete = function(res){
		typeof myfn === 'function' && myfn(res);
		Ask.fireEvent('complete', res);
		Ask.listeners.each(function(fn){
			fn(res);
		})
		res && res.script && eval(res.script);
		if(res && res.head){
			var tmp=new Element('div');
			tmp.set('html',res.head);
			document.getElement('head').adopt(tmp.childNodes);
		};
	}
	return new Request.JSON(opt).post( {askJSON:JSON.encode(obj)} );
};
$extend(Ask, Events.prototype);

Ask.listeners = [];
Ask.addListener = function(fn){
	Ask.listeners.push(fn);
}

Ask.addListener(function(res){
	if(res && res.updateElements){
		$each(res.updateElements, function(html, selector){
			var script = '';
			$$(selector).each(function(el){
				el.set('html', (''+html).stripScripts(function(s){script = s}) );
			})
			$exec(script)
		})
	}
})

$fn = function(fn){
	return function(){
		var vs = { fn:fn, args:$A(arguments), callb:$empty }
		$fn.stack.push(vs);
		$fn.runCollected();
		return {
			run : function(callb){
				callb && (vs.callb = callb);
				$fn.run();
			},
			then : function(callb){
				vs.callb = callb;
			}
		}
	}
}
$fn.runCollected = function(){
	$fn.run();
}.wait(120);
$fn.stack = [];
$fn.run = function(){
	var fns = $fn.stack;
	if(!fns.length){ return; }
	Ask({
		serverInterface:fns
	},{
		onComplete:function(res){
			res && res.serverInterface.each( function(v){
				fns.shift().callb(v);
			})
		},
		evalScripts:true,
		evalResponse:true
	})
	$fn.stack = [];
}


function $fnCompleter(el, fn, arg, opt){
	el = $(el);
	var box = new _initCombobox(el,opt||{});
	box.searchOption = function(){
		var complete = function(res){
			box.datalist.empty();
			$each(res, function(entry){
				var option = new Element('div');
				option.inject(box.datalist, 'bottom').set('html',entry.html);
				option.value = entry.value;
				option.setAttribute('value', entry.value);
				option.setAttribute('text', entry.text);
			})
			box.init();
		}
		$fn(fn)(el.value, arg).run(complete);
	}.wait(200)	
	return box;
}

$Set = function(what){
	Ask({qgSetting:what});
}

