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);
	}
	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:function(){} }
		$fn.stack.push(vs)
		return {
			run : function(callb){
				callb && (vs.callb = callb);
				$fn.run();
			},
			then : function(callb){
				vs.callb = callb;
			}
		}
	}
}
$fn.stack = [];
$fn.run = function(){
	var fns = $fn.stack;
	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});
}

/*
$new = function(className){
	var constr = function(){
		var constrArgs = $A(arguments);
		var meth = function(method){
				return function(){
					var methodArguments = $A(arguments);
					return { exec : 
						function(onComplete){
							Ask({
								classInterface:className,
								constrArgs:constrArgs,
								method:method,
								args:methodArguments
							},{
								onComplete:onComplete,
								evalScripts:true,
								evalResponse:true
							})
							return meth;
						}
					}
			}
		}
		return meth;
	}
	return constr;
}
*/

