/*
 * XHR列表请求
 * param element: Element 列表容器
 * param url: String 请求地址
 * param query: Fangbole.Query 查询对象
 * param template: Template 列表模板
 */
Fangbole.PageRequest = Class.create({
	initialize: function(element, url, query, template, options){
		this.element = $(element);
		this.url = url;
		//this.query = Object.isArray(query) ? query : [query];
		this.query = query;
		this.queryQueue = [];
		this.queryCount = 0;
		this.dumpQuery = [];
		this.template = template;
		this.loading = null;
		this.loadIndicate = $('loading_indicate') || null;
		
		this.options = Object.extend({
			onSuccess: Prototype.emptyFunction,
			adapter: Prototype.emptyFunction,
			delay: 0,
			onUpdateProgress: Prototype.emptyFunction,
			breathe: false
		}, options || {})
	},
	onFilterChange: function(filter){
		//special filter logic here
		
		//if(!(filter instanceof Fangbole.Paginator))	
			
		//filter.memo.page;
		if(filter&&filter.memo.page)
			this.query.query.get('pageNo').page=filter.memo.page;
		var queryObject = this.query.toQueryParam();
		
		this.addQuery(queryObject);
		this.request(this.queryQueue.shift());
	},
	/*
	findQueryByFilter: function(filter){
		return this.query.find(function(query){
			var result = false;
			for(var f in query.query){
				if(query.query[f] == filter){
					result = true;
					break;
				}
			}
			return result;
		})
	},
	*/
	addQuery: function(queryObject){
		var id = ++ this.queryCount;
		var requestObject = {
			id: id,
			parameters: queryObject,
			onCreate: this.onloading,
			onSuccess: this.onloadSuccess.curry(id),
			onFailure: this.onloadFailure.curry(id),
			onComplete: this.onloadComplete.curry(id),
			onException: this.onException.curry(id)
		}
		this.queryQueue.push(requestObject);
	},
	clearQuery: function(){
		
	},
	dumpResponse: function(id){
		this.dumpQuery.push(id);
	},
	onloading: function(){
		if(this.loadIndicate){
			//this.loadIndicate.up().addClassName('loading');
			this.loadIndicate.show();
		}
		//this.element.addClassName('gray');
		this.isloading = true;		
	},
	onloadSuccess: function(id, transport){
		if(this.dumpQuery.indexOf(id) > -1)return;	
		var result = transport.responseText.evalJSON();
		if(this.options.adapter != Prototype.emptyFunction)
			result = this.options.adapter(result);
		
		this.data = result.data;
		var body = [];
		if(!this.options.breathe){
			body = result.data.collect(function(d){
				return this.template.evaluate(d);
			}, this).join('');
			this.element.update(body);
			this.options.onSuccess(result);
		}else{
			//a big loop will cause browser down
			//so have a break between every evaluate
			var _i = 0;
			var _t = this.template;
			//var _updateProgress = this.options.onUpdateProgress;
			var _total = result.data.length;
			function buildRow(data){
				this.options.onUpdateProgress(_i + 1, _total);
				body.push(this.template.evaluate(data));
				_i ++;
				if(_i == _total){
					this.element.update(body.join(''));
					this.options.onSuccess(result);
					return;
				}
				setTimeout(buildRow.bind(this, result.data[_i]), 1);
			}			
			buildRow.call(this, result.data[0]);
		}
	},
	onloadFailure: function(id){
		if(this.dumpQuery.indexOf(id) > -1)return;
	},
	onloadComplete: function(id){
		if(this.dumpQuery.indexOf(id) > -1)return;
		if(this.loadIndicate){
			this.loadIndicate.hide();
			//this.loadIndicate.up().removeClassName('loading');
		}
		//this.element.removeClassName('gray');
		this.isloading = false;
	},
	onException: function(id, request, e){
		if(this.dumpQuery.indexOf(id) > -1)return;
		throw e;
	},
	request: function(request){
		if(this.loading)
			this.dumpResponse(this.loading.id);
		this.loading = request;
		new Ajax.Request(this.url, {
			method: 'GET',
			parameters: request.parameters,
			onCreate: request.onCreate.bind(this),
			onSuccess: request.onSuccess.bind(this),
			onComplete: request.onComplete.bind(this),
			onFailure: request.onFailure.bind(this),
			onException: request.onException.bind(this)
		})
	},
	refresh: function(){
		this.onFilterChange();
	},
	//实时监听一个filter，对filter组件的改变会立刻产生一个请求，例如paginator
	listen: function(key){
		var filter = this.query.getParam(key);
		if(filter)
			filter.observe(this.onFilterChange.bind(this));
			//filter.observe(this.onFilterChange.bind(this, filter));
	}
})

Object.extend(Fangbole.PageRequest, {
	
})
