var bufferview = {};
(function($){
	$.extend($.fn.datagrid.defaults, {
		rowHeight: 25,
		onBeforeFetch: function(page){},
		onFetch: function(page, rows){}
	});

	bufferview = $.extend({}, $.fn.datagrid.defaults.view, {
		render: function(target, container, frozen){
			var state = $.data(target, 'datagrid');
			var opts = state.options;
			var rows = this.rows || [];
			if (!rows.length) {
				return;
			}
			var fields = $(target).datagrid('getColumnFields', frozen);
			
			if (frozen){
				if (!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))){
					return;
				}
			}
			
			var index = parseInt(opts.finder.getTr(target,'','last',(frozen?1:2)).attr('datagrid-row-index'))+1 || 0;
			var table = ['<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>'];
			for(var i=0; i<rows.length; i++) {
				// get the class and style attributes for this row
				var css = opts.rowStyler ? opts.rowStyler.call(target, index, rows[i]) : '';
				var classValue = '';
				var styleValue = '';
				if (typeof css == 'string'){
					styleValue = css;
				} else if (css){
					classValue = css['class'] || '';
					styleValue = css['style'] || '';
				}
				
				var cls = 'class="datagrid-row ' + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ') + classValue + '"';
				var style = styleValue ? 'style="' + styleValue + '"' : '';
				var rowId = state.rowIdPrefix + '-' + (frozen?1:2) + '-' + index;
				table.push('<tr id="' + rowId + '" datagrid-row-index="' + index + '" ' + cls + ' ' + style + '>');
				table.push(this.renderRow.call(this, target, fields, frozen, index, rows[i]));
				table.push('</tr>');
				index++;
			}
			table.push('</tbody></table>');
			
			$(container).append(table.join(''));
		},
		
		onBeforeRender: function(target){
			var state = $.data(target, 'datagrid');
			var opts = state.options;
			var dc = state.dc;
			var view = this;
			this.renderedCount = 0;
			this.rows = [];
			
			dc.body1.add(dc.body2).empty();
			init();
			
			function init(){
				// erase the onLoadSuccess event, make sure it can't be triggered
				state.onLoadSuccess = opts.onLoadSuccess;
				opts.onLoadSuccess = function(){};
				setTimeout(function(){
					dc.body2.unbind('.datagrid').bind('scroll.datagrid', function(e){
						if (state.onLoadSuccess){
							opts.onLoadSuccess = state.onLoadSuccess;	// restore the onLoadSuccess event
							state.onLoadSuccess = undefined;
						}
						if (view.scrollTimer){
							clearTimeout(view.scrollTimer);
						}
						view.scrollTimer = setTimeout(function(){
							scrolling.call(view);
						}, 50);
					});
					dc.body2.triggerHandler('scroll.datagrid');
				}, 0);
			}
			
			function scrolling(){
				if (getDataHeight() < dc.body2.height() && view.renderedCount < state.data.total){
					this.getRows.call(this, target, function(rows){
						this.rows = rows;
						this.populate.call(this, target);
						dc.body2.triggerHandler('scroll.datagrid');
					});
				} else if (dc.body2.scrollTop() >= getDataHeight() - dc.body2.height()){
					this.getRows.call(this, target, function(rows){
						this.rows = rows;
						this.populate.call(this, target);
					});
				}
			}
			
			function getDataHeight(){
				// var h = 0;
				// dc.body2.children('table.datagrid-btable').each(function(){
				// 	h += $(this).outerHeight();
				// });
				// if (!h){
				// 	h = view.renderedCount * opts.rowHeight;
				// }
				// return h;
				return view.renderedCount * opts.rowHeight;
			}
		},
		
		getRows: function(target, callback){
			var state = $.data(target, 'datagrid');
			var opts = state.options;
			var page = Math.floor(this.renderedCount/opts.pageSize) + 1;
			
			if (this.renderedCount >= state.data.total){return;}
			if (opts.onBeforeFetch.call(target, page) == false){return}
			
	//		var rows = state.data.rows.slice(this.renderedCount, this.renderedCount+opts.pageSize);
			var index = (page-1)*opts.pageSize;
			var rows = state.data.rows.slice(index, index+opts.pageSize);
			if (rows.length){
				opts.onFetch.call(target, page, rows);
				callback.call(this, rows);
			} else {
				var param = $.extend({}, opts.queryParams, {
					page: Math.floor(this.renderedCount/opts.pageSize)+1,
					rows: opts.pageSize
				});
				if (opts.sortName){
					$.extend(param, {
						sort: opts.sortName,
						order: opts.sortOrder
					});
				}
				if (opts.onBeforeLoad.call(target, param) == false){return;}
				
				$(target).datagrid('loading');
				var result = opts.loader.call(target, param, function(data){
					$(target).datagrid('loaded');
					var data = opts.loadFilter.call(target, data);
					opts.onFetch.call(target, page, data.rows);
					if (data.rows && data.rows.length){
						state.data.rows = state.data.rows.concat(data.rows);
						callback.call(opts.view, data.rows);
					} else {
						opts.onLoadSuccess.call(target, data);
					}
				}, function(){
					$(target).datagrid('loaded');
					opts.onLoadError.apply(target, arguments);
				});
				if (result == false){
					$(target).datagrid('loaded');
					if (!state.data.rows.length){
						opts.onFetch.call(target, page, state.data.rows);
						opts.onLoadSuccess.call(target, state.data);
					}
				}
			}
		},
		
		populate: function(target){
			var state = $.data(target, 'datagrid');
			var opts = state.options;
			var dc = state.dc;
			if (this.rows.length){
				this.renderedCount += this.rows.length;
				this.render.call(this, target, dc.body2, false);
				this.render.call(this, target, dc.body1, true);
				opts.onLoadSuccess.call(target, {
					total: state.data.total,
					rows: this.rows
				});
	//			for(var i=this.renderedCount-this.rows.length; i<this.renderedCount; i++){
	//				$(target).datagrid('fixRowHeight', i);
	//			}
			}
		}
	});
}(jQuery);
