/*
@name: /htdocs/js/lib/oggetti/gridwindow.js
@desc: Componente javascript gridwindow
@authors: Marco Biondi
@lastauthor: Marco Biondi
@require: Prototype 1.4.0, moo 1.2.2
*/
var GridWindow = Class.create();
GridWindow.prototype = {
	initialize: function(divID, options) {
		this._container = $(divID);
		this._footer = null;
		this._header = null;
		this.options = {
				gridStyle:						'',
				gridWidth:						'150px',
				titleStyle:						'',
				titleContent:					'gridWindow Title',
				headerMeta:					    '',
				cellStyle:						'',
				cellWidth:						'50px',
				cellHeight:						'50px',
				numRows:							3,
				numCols:							3,
				footerStyle:					'',
				footerContent:				'gridWindow footer',
				footerMeta:						'',
				lockBoundaries:				true,
				updateType:						'__def__',
				updateDelay:					0,
				renderingFunction:		this._defCellRenderer.bind(this)
				};
		Object.extend(this.options, options || {});

		if(typeof(this.options.renderingFunction) == "string")
		{
			this.options.renderingFunction = eval(this.options.renderingFunction);
		}

		this._firstRecord = 0;
		this._totCells = this.options.numRows*this.options.numCols;
		this._cells = new Array();

		this._container.innerHTML = "";
		this.dataSource = null;
		this._pageSize = this._totCells;

		EventBroadcaster.initialize(this);

		Binder.initialize(this);
		this.defineBind('next', 'click', this.nextPage, false);
		this.defineBind('prev', 'click', this.prevPage, false);
	},

	destroy: function()
	{
		this.releaseDataSource();
		this.unbindAll();
	},

	releaseDataSource: function() {
		if(this.dataSource)
			this.dataSource.delListener("onDataChange", this);

		this.dataSource = null;
	},

	bindDataSource: function(ds) {
		if(this.dataSource)
			this.dataSource.delListener("onDataChange", this);

		this.dataSource = ds;
		this._firstRecord = 0;
		this.dataSource.addListener("onDataChange", this);
	},

	getOffset: function() {
		return(this._firstRecord);
	},

	setOffset: function(ofs, force) {
		if(this.dataSource)
		{
			if(force)
				this._firstRecord = ofs;
			else
				this._firstRecord = Math.min(this.dataSource.getLength()-this._totCells,Math.max(0,parseInt(ofs)));
		}
		else
			this._firstRecord = 0;

		this.updateControlsState();
		return(this._firstRecord);
	},

	setPagesize: function(size) {
		size = parseInt(size);
		if(!isNaN(size))
			size = this._totCells;

		this._pageSize = Math.min(this._totCells, Math.max(1,size));
	},

	onDataChange: function(objEvt) {
		switch(objEvt.dEvType)
		{
			case "update":
				if(objEvt.from >= this._firstRecord && objEvt.from < (this._firstRecord+this._totCells))
				{
					var dset = this.dataSource.getItemAt(objEvt.from);
					var rIndex = objEvt.from-this._firstRecord;
					var res = this.options.renderingFunction(dset, this._cells[rIndex], objEvt.from);
					if(typeof(res) != 'undefined')
					{
						res = String(res);
						this._cells[rIndex].innerHTML = res;
					}
				}
				break;

			case "updateAll":
				this._firstRecord = 0;
			default:
				this.draw();
				break;
		}
		this.updateControlsState();
	},

	updateControlsState: function() {
		try
		{
			if(!this.dataSource || this.dataSource.getLength() < this._totCells)
			{
					Element.hide(this.getBindObject('next'));
					Element.hide(this.getBindObject('prev'));
			}
			else
			{
				if(this._firstRecord == 0)
					Element.hide(this.getBindObject('prev'));
				else
					Element.show(this.getBindObject('prev'));

				if(this.dataSource.getLength() - this._firstRecord <= this._totCells)
					Element.hide(this.getBindObject('next'));
				else
					Element.show(this.getBindObject('next'));
				
			}
		} catch(err) {};
	},

	create: function() {
		var foo, bar, main, cRow, cell, i, j, spacer;

		var baseULstyle = 'display: block; margin: 0px; padding: 0px; list-style-type: none;';
		var innerULstyle = baseULstyle +' height: '+this.options.cellHeight+'; clear:left;';
		var rowLIstyle = 'clear: left; margin: 0px; padding: 0px; display: inline;';
		var cellLIstyle = 'display: block; float: left; width: '+this.options.cellWidth+'; height: '+this.options.cellHeight+'; overflow: hidden;';

		this._container.className = this.options.gridStyle;
		this._container.style.width = this.options.gridWidth;

		//Creo il titolo
		this._header = foo = document.createElement('div');
		foo.className = this.options.titleStyle;
		if(typeof(this.options.titleContent) == 'string')
			foo.innerHTML = this.options.titleContent;
		else
			foo.appendChild(this.options.titleContent);
		this._container.appendChild(foo);

		this.doBindings(foo);	//Cerco eventuali bindings

		//Creo il contenitore delle celle
		main = document.createElement('ul');
//		main.className = 'ulBase';
		main.style.cssText = baseULstyle; // + ' background-color: #00FF00';

		for(i=0; i<this.options.numRows; i++)
		{
			//Creo la riga
			cRow = document.createElement('li');
//			cRow.className = 'liBase';
			cRow.style.cssText = rowLIstyle;
			foo = document.createElement('ul');
//			foo.className = 'ulBase';
			foo.style.cssText = innerULstyle;

			for(j=0; j<this.options.numCols; j++)
			{
				//Creo le celle
				bar = document.createElement('li');
//				bar.className = 'liCella';
				bar.style.cssText = cellLIstyle;
				cell = document.createElement('div');
				cell.className = this.options.cellStyle;

				this._cells.push(cell);

				bar.appendChild(cell);

				foo.appendChild(bar);
			}
			cRow.appendChild(foo);

			main.appendChild(cRow);
		}

		this._container.appendChild(main);

		//Creo il footer
		this._footer = foo = document.createElement('div');
		foo.className = this.options.footerStyle;
		foo.style.cssText = 'clear: left;';
		if(typeof(this.options.footerContent) == 'string')
			foo.innerHTML = this.options.footerContent;
		else
			foo.appendChild(this.options.footerContent);
		this._container.appendChild(foo);

		this.doBindings(foo);	//Cerco eventuali bindings

		this.updateControlsState();
	},

	draw: function() {
		var i, meta;

		switch(this.options.updateType)
		{
			case '__rnd__':
				var order = new Array(this._totCells);
				for(i=0; i<this._totCells; i++)
					order[i] = i;

				while(order.length)
				{
					i = Math.floor(Math.random()*order.length);
					this._processCell(order[i]);
					order.splice(i,1);
				}
				break;
			
			case '__def__':
			default:
				for(i=0; i<this._totCells; i++)
					this._processCell(i);
				break;
		}

		meta=this.dataSource.getMetaData();

		if (this.options.headerMeta != '')
		{
			if (typeof(meta[this.options.headerMeta]) == 'string')
			{
				this._header.innerHTML = meta[this.options.headerMeta];
				this.doBindings(this._header);
			}
		}
		if (this.options.footerMeta != '')
		{
			if (typeof(meta[this.options.footerMeta]) == 'string')
			{
				this._footer.innerHTML = meta[this.options.footerMeta];
				this.doBindings(this._footer);
			}
		}

		this.dispatchEvent({'type': "onFinishDraw"});
	},

	_processCell: function(i) {
		var res, dset;

		dset = this.dataSource.getItemAt(i+this._firstRecord);
		res = this.options.renderingFunction(dset, this._cells[i], i+this._firstRecord);
		if(typeof(res) != 'undefined')
		{
			res = String(res);
			this._cells[i].innerHTML = res;
		}
	},

	_defCellRenderer: function(dati, cell, recordIndex) {
		var res = '['+recordIndex+']';
		var i;

		if(dati)
		{
			res += "<br />";
			for(i in dati)
				res += i+": "+String(dati[i]).escapeHTML()+"<br />";
		}

		return res;
	},

	nextPage: function() {
		this.setOffset(this._firstRecord + this._pageSize, !this.options.lockBoundaries);
		this.updateControlsState();
		this.draw();
	},

	prevPage: function() {
		this.setOffset(this._firstRecord - this._pageSize);
		this.updateControlsState();
		this.draw();
	}
}
