/****************
Class:  SJSGrid
*****************
Definisce una griglia (table) che può avere le seguenti caratteristiche:
- Definizione distinte degli stili per i titoli, le righe dispari, le righe pari, le celle - (normal, mouseover, mouseout)
- Definizione degli eventi associati ai titoli, alle righe, alle celle - (click, dblclick, mouseover, mouseout)
- Gestione dell'evento onCalcFields e onCalcTitle
- Gestione dell'ordinamento dei dati 
- Possibilità di definire le proprietà delle singole colonne (visibilità, allineamento, tipo di dato, larghezza, ecc.)
- Possibilità di indicare le colonne come "selector", ovvero le colonne che permettono la selezione dell'intera riga
- Possibilità di impostare la griglia per effettuare la selezione delle righe (selezione singola/multipla)
- Possibilità di impostare la griglia per effettuare la selezione delle celle (selezione singola/multipla)


Sintassi
	var  miaGriglia = new SJSGrid(id, dataset, [opzioni]);

Argomenti
	•	Id - (string, obbligatorio) ID della griglia (sarà l'ID della tabella generata)
	•	dataset - (object array, obbligatorio) Array di oggetti contenente i dati che definiscono la griglia
	•	opzioni - (object, opzionale) vedi sotto

Opzioni
	• checkDataset - (boolean, default:true) Controlla che il dataset contenga campio omogenei in tutti i record (stessi campio per tutte le righe)
	•	columns – (object array) Array di oggetti  contenenti le proprietà delle colonne (l'indice dell'array identifica la colonna)
			o	'fieldname' – nome del campo del dataset associato a cui fa riferimento
				NB impostando 'fieldname':'default_column', è possibile specificare i valori di default per tutte le colonne senza proprietà specifiche
			o	'description' – titolo della colonna (se omesso,  viene riportato il fieldname)
			o	'dataType' – tipo di dato ('number'/'string'/'date', default = 'string' )
			o	'visible' – (boolean) Indica se la colonna deve essere visibile o meno
			o	'alignment' – 'left'/'right'/'center' – Indica l'allineamento delle celle della colonna
			o	'width' – (string) – Indica la larghezza della colonna (% o px).
			o	'rowSelector' - (boolean) - Se è True, selezionando la cella, vengono selezionate tutte le celle della riga
			o 'selectable' - (boolean, default:false) Indica se sulla colonna si può applicare la selezione e l'ordinamento (in funzione anche dei parametri colSelection e colOrder)
	•	lockedTitles - (boolean, default:false) Blocca la riga dei titoli ed effettua lo scroll solo dei dati. 
									Deve essere impostato anche il parametro 'bodyHeight' ed è indispensabile impostare anche le larghezze delle singole colonne;
	•	bodyHeight - (integer - obbligatorio se lockedTitles=true) altezza massima della griglia contenente i dati oltre la quale compare la scrollbar;
	•	selectableRows – (boolean, default:false) Indica se le righe sono selezionabili, in tal caso l'array contenente le righe selezionate viene ritornato dalla proprietà selectedRows (vedi sotto)
											NB se selectableRows = true allora anche multiCellSelection viene forzato a true
	• multiRowSelection - (boolean, default:true) Indica se è abilitata la selezione multipla delle righe (ha senso se selectableRows=true)
	•	selectableCells – (boolean, default:false) Indica se le celle sono selezionabili, in tal caso l'array contenente le celle selezionate viene ritornato dalla proprietà selectedCells (vedi sotto)
											NB è necessario impostare il parametro "rowSelector" per le celle che selezionano la riga
	•	multiCellSelection – (boolean, default:true) Indica se è abilitata la selezione multipla delle celle (ha senso se selectableCells=true)
											NB se selectableRows = true allora anche multiCellSelection viene forzato a true
	•	colSelection – (boolean, default:false) Se è true, cliccando sui titoli verranno selezionate tutte le celle della colonna. Impostando a true questo parametro verrà impostato a true automaticamente anche il parametro selectableCells
	•	colOrder  – (boolean, default:false) Indica se è possibile ordinare i record cliccando sui titoli. Per indicare le colonne da escludere dall'ordinamento vedi la proprietà columns
	•	tableClass – (string) Indica la classe style da applicate alla tabella
	•	tableStyle – (string) Indica lo style da applicate alla tabella
	•	cellClass – (object) Oggetto contenente il riferimento alle classi di stile da applicare alle celle
			o	'normal' – Classe di stile della cella
			o	'over'– Classe di stile della cella sull'evento onMouseOver
			o	'out – Classe di stile della cella sull'evento onMouseOut
			o	'selected' – Classe di stile della cella selezionata
			o	'selectedOver' – Classe di stile della cella selezionata sull'evento onMouseOver
			o	'selectedOut' – Classe di stile della cella selezionata sull'evento onMouseOut
			o	'isNull' – Classe di stile della cella eventualmente inesistente (con dati non omogenei)
			N.B. questo style prevale sugli stili rowClassOdd e rowClassEven
	•	  – (object) Oggetto contenente il riferimento alle classi di stile da applicare alle righe dispari (vedi proprietà cellClass)
	•	rowClassEven – (object) Oggetto contenente il riferimento alle classi di stile da applicare alle righe dispari (vedi proprietà cellClass)
	•	titleClass – (object) Oggetto contenente il riferimento alle classi di stile da applicare alle celle dei titoli (vedi proprietà cellClass)

Eventi
	•	onCalcTitles: (function(fieldname, Stringa_innerHTML)) Evento associato alla generazione delle celle dei titoli
	•	onCalcTD: (function(fieldname, record, indiceRecord)) Evento associato alla generazione del codice TD
	•	onCalcFields: (function(fieldname, Stringa_innerHTML, record, indiceRecord)) Evento associato alla generazione delle celle
	•	onRowTitleClick – (function(row)) Evento onClick della riga del titolo
	•	onRowTitleDblClick – (function(row)) E onDblClick della riga del titolo
	•	onRowTitleOver – (function(row)) Evento onMouseOver della riga del titolo
	•	onRowTitleOut – (function(row)) Evento onMouseOut della riga del titolo
	•	onRowClick – (function(row)) Evento onClick della riga
	•	onRowDblClick – (function(row)) Evento onDblClick della riga
	•	onRowOver – (function(row)) Evento onMouseOver della riga
	•	onRowOut – (function(row)) Evento onMouseOut della riga
	•	onTitleClick – (function(cella, fieldname)) Evento onClick della cella dei titoli
	•	onTitleDblClick – (function(cella, fieldname)) Evento onDblClick della cella dei titoli
	•	onTitleOver – (function(cella, fieldname)) Evento onMouseOver della cella dei titoli
	•	onTitleOut – (function(cella, fieldname)) Evento onMouseOut della cella dei titoli
	•	onCellClick – (function(cella, fieldname, indiceRecord)) Evento onClick della cella
	•	onCellDblClick – (function(cella, fieldname, indiceRecord)) Evento onDblClick della cella
	•	onCellOver – (function(cella, fieldname, indiceRecord)) Evento onMouseOver della cella
	•	onCellOut – (function(cella, fieldname, indiceRecord)) Evento onMouseOut della cella viene

***********************
SJSGrid  Metodo: Show
***********************
	Disegna la griglia

Sintassi
	unaGriglia.Show(container);

Argomenti
	•	Container – (string) ID del TAG contenitore della griglia nel quale effettuare l'innerHTML


***********************
SJSGrid  Metodo: Sort
***********************
	Riordina i record dell griglia. E' necessario che sia già stato richimato il metodo Show

Sintassi
	unaGriglia.Sort(fieldname);

Argomenti
	•	fieldname – (string) nome campo di ordinamento


******************************
SJSGrid  Metodo: recordCount 
******************************
Ritorna il numero di record della griglia

Sintassi
	unaGriglia.recordCount();

*******************************
SJSGrid  Metodo: selectedRows 
*******************************
Ritorna un array con le righe selezionate

Sintassi
	unaGriglia.selectedRows;

********************************
SJSGrid  Metodo: selectedCells 
********************************
Ritorna un array con le celle selezionate

Sintassi
	unaGriglia.selectedCells;

*********************************
SJSGrid  Metodo: selectAllCells
*********************************
Seleziona/Deseleziona tutte le celle

Sintassi
	unaGriglia.selectAllCells(opzione);

Argomenti
	•	opzione – (boolean) Se true, seleziona tutte le celle, altrimenti le deseleziona.




Esempio 1
var  miaGriglia = new SJSGrid(id, mioDS);
miaGriglia.Show('myDiv');

Esempio 2
var  miaGriglia = new SJSGrid(id, mioDS, {
					columns: [{'fieldname' : 'IDDIP' , 'description' : 'id', 'visible' : false, 'alignment' : 'right'},
          					{'fieldname' : 'MATRICOLA' , 'description' : 'Matricola', 'visible' : true, 'alignment' : 'left'}], 
					onCalcFields: function(nomecampo, stringa){ return stringa.toUpperCase()},
					titleClass: {'normal' : 'titoli'},
					cellClass: {'normal':'cella', 'selected':'CellaSelez'},
					onCellClick: function(cella, nomeField, indiceRigaDataset){ codice },
					});
miaGriglia.Show('myDiv');
================================================================================================================== */

var _compareFieldNumber = function(a, b){
	if(versoAZ)
		return a[campoOrdinamento] - b[campoOrdinamento];
	else
		return b[campoOrdinamento] - a[campoOrdinamento];
};

var _compareFieldString = function(a, b){	
	if(versoAZ){
		var campoB = a[campoOrdinamento].toUpperCase();
		var campoA = b[campoOrdinamento].toUpperCase();
	}
	else{
		var campoA = a[campoOrdinamento].toUpperCase();
		var campoB = b[campoOrdinamento].toUpperCase();
	}
	if(campoA > campoB)
		return -1;
	else if(campoA < campoB)
		return 1;
	else 
		return 0;
};

var _compareFieldDate = function(a, b){
	if(versoAZ){
		var campoA = Date.parse(a[campoOrdinamento]);
		var campoB = Date.parse(b[campoOrdinamento]);
	}
	else{
		var campoB = Date.parse(a[campoOrdinamento]);
		var campoA = Date.parse(b[campoOrdinamento]);
	}
	if(campoA > campoB)
		return -1;
	else if(campoA < campoB)
		return 1;
	else 
		return 0;
};

var _detectItem = function(originalArray, itemToDetect) {
	var j = 0;
	while (j < originalArray.length) {
		if (originalArray[j] == itemToDetect)
			return true;
		else
			j++; 
	}
		return false;
}

var _removeItem = function(originalArray, itemToRemove) {
	var j = 0;
	while (j < originalArray.length) {  	
		if (originalArray[j] == itemToRemove)
			originalArray.splice(j, 1);
		else
			j++;
	}
	return originalArray;
}


var _RiordinaRighe = function(unaGriglia, forzaVersoAZ){
	//riodina il dataset in base al campo selezionato e ridisegna la griglia	
	if(unaGriglia.container){
		campoOrdinamento = unaGriglia.fieldnameOrder;	
		dataTypeOrdinamento = unaGriglia.dataTypeOrder;
		if(forzaVersoAZ)
			versoAZ = true;
		switch(dataTypeOrdinamento){
			case 'string': unaGriglia.dataset.sort(_compareFieldString); break;
			case 'date': unaGriglia.dataset.sort(_compareFieldDate); break;
			case 'number': unaGriglia.dataset.sort(_compareFieldNumber); break;
		}
		unaGriglia.container.innerHTML = '';
		versoAZ = !versoAZ;		
	}
};

var _ColonnaSelector = function(objColonne, nomeCampo){
	if(!objColonne)
		return false;
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo){
				return (objColonne[c]["rowSelector"]);
			}
	}
	
	if(nomeCampo!='default_column')
		return _ColonnaSelector(objColonne, 'default_column');
	
	return false;
};

var _ColonnaTipo = function(objColonne, nomeCampo){
	if(!objColonne)
		return 'string';
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo && objColonne[c]["dataType"]!=undefined){
				return (objColonne[c]["dataType"]);
			}
	}
	
	if(nomeCampo!='default_column')
		return _ColonnaTipo(objColonne, 'default_column');

	return 'string';
};

var _ColonnaVisibile = function(objColonne, nomeCampo){
	if(!objColonne)
		return true;
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo){
				//return (objColonne[c]["visible"] == 'yes' || objColonne[c]["visible"] == 1 || objColonne[c]["visible"] == '1' || objColonne[c]["visible"] == undefined)			
				return (objColonne[c]["visible"] || objColonne[c]["visible"] == undefined);
			}
	}

	if(nomeCampo!='default_column')
		return _ColonnaVisibile(objColonne, 'default_column');
				
	return true;
};

var _ColonnaWidth = function(objColonne, nomeCampo){
	if(!objColonne)
		return '';
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo && objColonne[c]["width"]!=undefined){
				return (objColonne[c]["width"]);
			}
	}

	if(nomeCampo!='default_column')
		return _ColonnaWidth(objColonne, 'default_column');

	return '';
};

var _ColonnaNonSelezionabile = function(objColonne, nomeCampo){
	if(!objColonne)
		return false;
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo){			
				//return (objColonne[c]["selectable"] == 'no' || objColonne[c]["selectable"] == 0 || objColonne[c]["selectable"] == '0')
				return (objColonne[c]["selectable"] || !(objColonne[c]["selectable"]==undefined));
			}
	}

	if(nomeCampo!='default_column')
		return _ColonnaNonSelezionabile(objColonne, 'default_column');

	return false;
};

var _DescrizioneColonna = function(objColonne, nomeCampo){
	if(!objColonne)
		return nomeCampo;
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo && objColonne[c]["description"]!=undefined)
				return (objColonne[c]["description"])
	}
	
	return nomeCampo;
};

var _AllineamentoColonna = function(objColonne, nomeCampo){
	if(!objColonne)
		return 'left';
	var nCols = objColonne.length;
	for(var c=0; c<nCols; c++){
		if(objColonne[c]!=undefined)
			if(objColonne[c]["fieldname"] == nomeCampo)
				return (objColonne[c]["alignment"])
	}
	
	if(nomeCampo!='default_column')
		return _AllineamentoColonna(objColonne, 'default_column');
	
	return 'left';
};

var _ClasseCella = function(objGriglia, nomeProp){
	if(!objGriglia.cellClass)
		return '';
	for(var c in objGriglia.cellClass)	
		if(c == nomeProp)
			return objGriglia.cellClass[c];
	
	//gestisco le classi non definite
	if(nomeProp=='over' || nomeProp=='out')
		return _ClasseCella(objGriglia, 'normal');
	else if(nomeProp=='selectedOver' || nomeProp=='selectedOut')
		return _ClasseCella(objGriglia, 'selected');
	
	return '';
};

var _ClasseCellaNulla = function(objGriglia, nomeProp){
	if(!objGriglia.cellClass)
		return '';
	for(var c in objGriglia.cellClass)	
		if(c == nomeProp)
			return objGriglia.cellClass[c];
	
	return '';
};


var _ClasseRigaDispari = function(objGriglia, nomeProp){
	if(!objGriglia.rowClassOdd)
		return '';
	for(var c in objGriglia.rowClassOdd)	
		if(c == nomeProp)	
			return objGriglia.rowClassOdd[c];
			
	//gestisco le classi non definite
	if(nomeProp=='over' || nomeProp=='out')
		return _ClasseRigaDispari(objGriglia, 'normal');
	else if(nomeProp=='selectedOver' || nomeProp=='selectedOut')
		return _ClasseRigaDispari(objGriglia, 'selected');
	
	return '';
};

var _ClasseRigaPari = function(objGriglia, nomeProp){
	if(!objGriglia.rowClassEven)
		return _ClasseRigaDispari(objGriglia, nomeProp);
	
	for(var c in objGriglia.rowClassEven)	
		if(c == nomeProp)	
			return objGriglia.rowClassEven[c];

//gestisco le classi non definite
	if(nomeProp=='over' || nomeProp=='out')
		return _ClasseRigaPari(objGriglia, 'normal');
	else if(nomeProp=='selectedOver' || nomeProp=='selectedOut')
		return _ClasseRigaPari(objGriglia, 'selected');

	return _ClasseRigaDispari(objGriglia, nomeProp);
};

var _ClasseTitolo = function(objGriglia, nomeProp){
	if(!objGriglia.titleClass)
		return '';
	
	for(var c in objGriglia.titleClass)	
		if(c == nomeProp)	
			return objGriglia.titleClass[c];
	return '';
};

var _ClasseTitolo = function(objGriglia, nomeProp){
	if(!objGriglia.titleClass)
		return '';

	for(var c in objGriglia.titleClass)	
		if(c == nomeProp)	
			return objGriglia.titleClass[c];
	return '';
};

var _draw = function(idContenitore){
	this.container = idContenitore;
	this.container.innerHTML = '';	
	disegnaGriglia(this);
};

var _sort = function(fieldName, forzaVersoAZ){
	this.fieldnameOrder = fieldName;
	_RiordinaRighe(this, forzaVersoAZ);
};

var _SelezionaCella = function(unaCella, idxGriglia, selezioneMultipla){	
	var selezionabile = (unaCella.getAttribute('selectable') == 1);
	if(!selezionabile)
		return;
	if(selezioneMultipla){ //se la selezione è multipla viene gestita in modo particolare
		if(selezioneMultipla == 2){ //seleziono se non è già selezionata
			if(!_detectItem(_eg[idxGriglia].selectedCells, unaCella)){
				_eg[idxGriglia].selectedCells.push(unaCella);
				unaCella.className = _ClasseCella(_eg[idxGriglia], 'selected');
			}
		}
		else if(selezioneMultipla == 1){ //se è selezionato deseleziono
			if(_detectItem(_eg[idxGriglia].selectedCells, unaCella)){
				unaCella.className = _ClasseCella(_eg[idxGriglia], 'normal');
				_eg[idxGriglia].selectedCells = _removeItem(_eg[idxGriglia].selectedCells, unaCella);	
			}
		}
	}
	else {
		//verifico se la proprietà è attiva
		if(!_eg[idxGriglia].selectableCells)
			return;
			
		if(_detectItem(_eg[idxGriglia].selectedCells, unaCella)){		
			unaCella.className = _ClasseCella(_eg[idxGriglia], 'normal');
			_eg[idxGriglia].selectedCells = _removeItem(_eg[idxGriglia].selectedCells, unaCella);	
		}
		else {
			_eg[idxGriglia].selectedCells.push(unaCella);
			unaCella.className = _ClasseCella(_eg[idxGriglia], 'selectedOver');
		}
	}
};

var _selectAllCells = function(seleziona){
	if(this.lockedTitles)
		var elencoCelle = document.getElementById(this.id + '_body').getElementsByTagName('TD');
	else
		var elencoCelle = document.getElementById(this.id).getElementsByTagName('TD');
	
	var fine = elencoCelle.length;	
	//carico un array che contiene le celle della tabella
	for(var i=0; i<fine; i++){
		if(seleziona) //seleziono tutte le celle
			_SelezionaCella(elencoCelle[i], this.idx, 2);
		else //deseleziono tutte le celle
			_SelezionaCella(elencoCelle[i], this.idx, 1);
	}
};

var _SelezionaCelleColonna = function(unTitolo, idxGriglia){
	var selezionabile = (unTitolo.getAttribute('selectable') == 1);
	if(!selezionabile)
		return;
	if(_eg[idxGriglia].colSelection){  //selezione colonna
		var numeroColonna = unTitolo.getAttribute('inc');
		
		if(_eg[idxGriglia].lockedTitles)
			var elencoCelle = document.getElementById(_eg[idxGriglia].id + '_body').getElementsByTagName('TD');
		else
			var elencoCelle = document.getElementById(_eg[idxGriglia].id).getElementsByTagName('TD');
		
		var elencoCelleDaSelezionare = new Array();
		var fine = elencoCelle.length;	
		//carico un array che contiene le celle da selezionare	
		for(var i=0; i<fine; i++){		
			if(elencoCelle[i].getAttribute('inc') == numeroColonna && elencoCelle[i].getAttribute('selectable') == 1)
				elencoCelleDaSelezionare.push(elencoCelle[i]);			
		}
		//se non tutte le celle sono selezionate, le seleziono tutte
		var fine = elencoCelleDaSelezionare.length;
		var tutteSelezionate = true;
		for(var i=0; i<fine; i++){
			if(!_detectItem(_eg[idxGriglia].selectedCells, elencoCelleDaSelezionare[i]))
				tutteSelezionate = false;
			break;
		}
		//effettuo la selezione(2)/deselezione(1)
		if(tutteSelezionate)
			for(var i=0; i<fine; i++)
				_SelezionaCella(elencoCelleDaSelezionare[i], idxGriglia, 1);
		else
			for(var i=0; i<fine; i++)
				_SelezionaCella(elencoCelleDaSelezionare[i], idxGriglia, 2);
	}
	else if(_eg[idxGriglia].colOrder){  //ordinamento colonna
		_eg[idxGriglia].fieldnameOrder = unTitolo.getAttribute('fieldname');
		_eg[idxGriglia].dataTypeOrder = unTitolo.getAttribute('dataType');
		_RiordinaRighe(_eg[idxGriglia]);
	}
};

var _SelezionaCelleRiga = function(unSelettore, idxGriglia, fieldname, indiceRecord){
	var numeroRiga = unSelettore.getAttribute('inr');
	//var elencoCelle = $$('TD');
	
	if(_eg[idxGriglia].lockedTitles)
		var elencoCelle = document.getElementById(_eg[idxGriglia].id + '_body').getElementsByTagName('TD');
	else
		var elencoCelle = document.getElementById(_eg[idxGriglia].id).getElementsByTagName('TD');
	
	var elencoCelleDaSelezionare = new Array();
	var fine = elencoCelle.length;	
	//carico un array che contiene le celle da selezionare
	for(var i=0; i<fine; i++){
		if(elencoCelle[i].getAttribute('inr') == numeroRiga && elencoCelle[i].getAttribute('selectable') == 1)
			elencoCelleDaSelezionare.push(elencoCelle[i]);			
	}
	//se non tutte le celle sono selezionate, le seleziono tutte
	var fine = elencoCelleDaSelezionare.length;
	var tutteSelezionate = true;
	for(var i=0; i<fine; i++){
		if(!_detectItem(_eg[idxGriglia].selectedCells, elencoCelleDaSelezionare[i]))
			tutteSelezionate = false;
		break;
	}
	//effettuo la selezione(2)/deselezione(1)
	if(tutteSelezionate)
		for(var i=0; i<fine; i++)
			_SelezionaCella(elencoCelleDaSelezionare[i], idxGriglia, 1);
	else
		for(var i=0; i<fine; i++)
			_SelezionaCella(elencoCelleDaSelezionare[i], idxGriglia, 2);	
	
	if(_eg[idxGriglia].onCellClick)
		_eg[idxGriglia].onCellClick(unSelettore, fieldname, indiceRecord);
};

var _SelezionaRiga = function(unaRiga, idxGriglia){
	//verifico se la proprietà è attiva
	if(!_eg[idxGriglia].selectableRows)
		return;
		
	var eDispari = parseInt(unaRiga.childNodes[0].getAttribute('inr'),10) % 2 == 0;
			
	if(_detectItem(_eg[idxGriglia].selectedRows, unaRiga)){		
		if(eDispari)
			unaRiga.className = _ClasseRigaDispari(_eg[idxGriglia], 'normal');
		else
			unaRiga.className = _ClasseRigaPari(_eg[idxGriglia], 'normal');
		_eg[idxGriglia].selectedRows = _removeItem(_eg[idxGriglia].selectedRows, unaRiga);		
	}
	else {
		_eg[idxGriglia].selectedRows.push(unaRiga);
		if(eDispari)
			unaRiga.className = _ClasseRigaDispari(_eg[idxGriglia], 'selectedOver');
		else
			unaRiga.className = _ClasseRigaPari(_eg[idxGriglia], 'selectedOver');
	}
}

var _GestisciMouseOverRigaTitolo = function(objGriglia, unaRigaTitolo){	
	var classe = _ClasseTitolo(objGriglia, 'over');
	if(classe!='')
		unaRigaTitolo.className = classe;
	if(objGriglia.onRowTitleOver)
		objGriglia.onRowTitleOver(unaRigaTitolo);
};

var _GestisciMouseOutRigaTitolo = function(objGriglia, unaRigaTitolo){	
	var classe = _ClasseTitolo(objGriglia, 'out');
	if(classe!='')
		unaRigaTitolo.className = classe;
	if(objGriglia.onRowTitleOut)
		objGriglia.onRowTitleOut(unaRigaTitolo);
};

var _GestisciMouseOverTitolo = function(objGriglia, unTitolo, fieldname){	
	var classe = _ClasseTitolo(objGriglia, 'over');
	if(classe!='')
		unTitolo.className = classe;
	if(objGriglia.onTitleOver)
		objGriglia.onTitleOver(unTitolo, fieldname);
};

var _GestisciMouseOutTitolo = function(objGriglia, unTitolo, fieldname){	
	var classe = _ClasseTitolo(objGriglia, 'out');
	if(classe!='')
		unTitolo.className = classe;
	if(objGriglia.onTitleOut)
		objGriglia.onTitleOut(unTitolo, fieldname);
};

var _GestisciMouseOverRiga = function(objGriglia, unaRiga, rigaDispari){		
	if(_detectItem(objGriglia.selectedRows, unaRiga)){
		if(rigaDispari)
			var classe = _ClasseRigaDispari(objGriglia, 'selectedOver');
		else
			var classe = _ClasseRigaPari(objGriglia, 'selectedOver');
		if(classe!='')
			unaRiga.className = classe;
	}
	else {				
		if(rigaDispari)
			var classe = _ClasseRigaDispari(objGriglia, 'over');
		else
			var classe = _ClasseRigaPari(objGriglia, 'over');
		if(classe!='')
			unaRiga.className = classe;
	}
	if(objGriglia.onRowOver)
		objGriglia.onRowOver(unaRiga);
};

var _GestisciMouseOutRiga = function(objGriglia, unaRiga, rigaDispari){
	if(_detectItem(objGriglia.selectedRows, unaRiga)){
		if(rigaDispari)
			var classe = _ClasseRigaDispari(objGriglia, 'selectedOut');
		else
			var classe = _ClasseRigaPari(objGriglia, 'selectedOut');
		if(classe!='')
			unaRiga.className = classe;
	}
	else {
		if(rigaDispari)
			var classe = _ClasseRigaDispari(objGriglia, 'out');
		else
			var classe = _ClasseRigaPari(objGriglia, 'out');
		if(classe!='')
			unaRiga.className = classe;
	}
	if(objGriglia.onRowOut)
		objGriglia.onRowOut(unaRiga);
};

var _GestisciMouseOverCella = function(objGriglia, unaCella, fieldname, indiceRecord){	
	var selezionabile = (unaCella.getAttribute('selectable') == 1);
	if(selezionabile){
		if(_detectItem(objGriglia.selectedCells, unaCella)){
			var classe = _ClasseCella(objGriglia, 'selectedOver');
			if(classe!='')
				unaCella.className = classe;
		}
		else {		
			var classe = _ClasseCella(objGriglia, 'over');
			if(classe!='')
				unaCella.className = classe;
		}
	}
	if(objGriglia.onCellOver)
		objGriglia.onCellOver(unaCella, fieldname, indiceRecord);
};

var _GestisciMouseOutCella = function(objGriglia, unaCella, fieldname, indiceRecord){
	var selezionabile = (unaCella.getAttribute('selectable') == 1);
	if(selezionabile){
		if(_detectItem(objGriglia.selectedCells, unaCella)){
			var classe = _ClasseCella(objGriglia, 'selectedOut');
			if(classe!='')
				unaCella.className = classe;
		}
		else {		
			var classe = _ClasseCella(objGriglia, 'out');
			if(classe!='')
				unaCella.className = classe;
		}
	}
	if(objGriglia.onCellOut)
		objGriglia.onCellOut(unaCella, fieldname, indiceRecord);
};

var _clickOnSelectorCell = function(unaCella, idxGriglia, fieldname, indiceRecord){	
	nonEseguireClickTR=true;
	
	if(_eg[idxGriglia].multiRowSelection){
		_SelezionaCelleRiga(unaCella, idxGriglia, fieldname, indiceRecord);
		_SelezionaRiga(unaCella.parentNode, idxGriglia);
		_clickOnTr(unaCella.parentNode, idxGriglia);
	}
	else{
		if(_eg[idxGriglia].selectedRows.length>0){ //prima deselezione precedente
			_SelezionaCelleRiga(lastClickedSelectorCell[idxGriglia], idxGriglia, fieldname, indiceRecord);
			_SelezionaRiga(lastClickedSelectorCell[idxGriglia].parentNode, idxGriglia);		
		}
		if(unaCella!=lastClickedSelectorCell[idxGriglia]){
			_SelezionaCelleRiga(unaCella, idxGriglia, fieldname, indiceRecord);
			_SelezionaRiga(unaCella.parentNode, idxGriglia);
		}
	}
	lastClickedSelectorCell[idxGriglia] = unaCella;
}

var _clickOnNonSelectorCell = function(unaCella, idxGriglia){
	nonEseguireClickTR=true;
	if(_eg[idxGriglia].multiCellSelection){
		_SelezionaCella(unaCella, idxGriglia);
	}
	else{
		if(_eg[idxGriglia].selectedCells.length>0){ //prima deselezione precedente
			_SelezionaCella(lastClickedNonSelectorCell[idxGriglia], idxGriglia);
		}
		if(unaCella!=lastClickedNonSelectorCell[idxGriglia]){
			_SelezionaCella(unaCella, idxGriglia);
		}
	}
	lastClickedNonSelectorCell[idxGriglia] = unaCella;
}

var _clickOnTr = function(unTR, idxGriglia){
	if(!nonEseguireClickTR)
		_SelezionaRiga(unTR, idxGriglia);	
}

var disegnaGriglia = function (objGriglia){	
	//leggo gli stili
	var classeTitolo = _ClasseTitolo(objGriglia, 'normal');
	var classeCella = _ClasseCella(objGriglia, 'normal');
	var classeRigaDispari = _ClasseRigaDispari(objGriglia, 'normal');
	var classeRigaPari = _ClasseRigaPari(objGriglia, 'normal');
	var classeCellaNulla = _ClasseCellaNulla(objGriglia, 'isNull');
	
	if(objGriglia.container != null && document.getElementById(objGriglia.container) != null)
		var targetDiv = document.getElementById(objGriglia.container)
	if(targetDiv)
		targetDiv.innerHTML = '';

	arr_TBL_HEADER = new Array();
	arr_TBL = new Array();
	arr_TBL_BODY  = new Array();
	
	var TBL_std= '<table id="' + objGriglia.id + '" class="' + objGriglia.tableClass +'" style="' + objGriglia.tableStyle + '">';
	var TBL_std2= '<table id="' + objGriglia.id + '_body" class="' + objGriglia.tableClass +'" style="' + objGriglia.tableStyle + '">';
	
	//var TBL = TBL_std;
	var TBL = "";
	arr_TBL.push(TBL_std);
	
	//scrivo i titoli della griglie
	var tiRwCk = '';
	var tiRwDblCk = '';
	if(objGriglia.onRowTitleClick)
		tiRwCk = ' onClick="_eg[' + objGriglia.idx + '].onRowTitleClick(this)" ';
	if(objGriglia.onRowTitleDblClick)
		tiRwDblCk = ' onDblClick="_eg[' + objGriglia.idx + '].onRowTitleDblClick(this)" ';

	var styleTH = '';
	if(objGriglia.titleClass)
		styleTH = '';
	else 
		styleTH = 'style="' + objGriglia.thStyle + '" ';

	arr_TBL_HEADER.push('<thead class="fixedHeader"><tr class="');
	arr_TBL_HEADER.push(classeTitolo);
	arr_TBL_HEADER.push('" style="');
	arr_TBL_HEADER.push(styleTH);
	arr_TBL_HEADER.push('" ');
	arr_TBL_HEADER.push(tiRwCk);
	arr_TBL_HEADER.push(tiRwDblCk);
	arr_TBL_HEADER.push(' onMouseOver="_GestisciMouseOverRigaTitolo(_eg[');
	arr_TBL_HEADER.push(objGriglia.idx);
	arr_TBL_HEADER.push('], this)" ');
	arr_TBL_HEADER.push('	onMouseOut="_GestisciMouseOutRigaTitolo(_eg[');
	arr_TBL_HEADER.push(objGriglia.idx);
	arr_TBL_HEADER.push('], this)" >');	
	
	var colPropSAV = new Object();
	
	var fine = objGriglia.dataset.length;	
	var conta=0;
	if(fine>0){			
		var unRecord = objGriglia.dataset[0];
		for(var f in unRecord){									
			//salvo le proprietà comuni delle celle in modo da non deverle rileggere per ogni cella
			colPropSAV[f] = new Object();
			colPropSAV[f]["ColonnaVisibile"] = _ColonnaVisibile(objGriglia.columns, f);
			colPropSAV[f]["ColonnaNonSelezionabile"] = _ColonnaNonSelezionabile(objGriglia.columns, f);
			colPropSAV[f]["ColonnaWidth"] = _ColonnaWidth(objGriglia.columns, f);
			colPropSAV[f]["ColonnaTipo"] = _ColonnaTipo(objGriglia.columns, f);
			colPropSAV[f]["DescrizioneColonna"] = _DescrizioneColonna(objGriglia.columns, f);
			colPropSAV[f]["ColonnaSelector"] = _ColonnaSelector(objGriglia.columns, f);
			colPropSAV[f]["AllineamentoColonna"] = _AllineamentoColonna(objGriglia.columns, f);
			////////////////////////////////////			
			
			if(typeof(objGriglia.dataset[0][f]) != 'function'){
							
				if(colPropSAV[f] && colPropSAV[f]["ColonnaVisibile"]){
					var tiCk = ' onClick="_SelezionaCelleColonna(this, ' + objGriglia.idx + ')" ';
					var tiDblCk = '';
					if(objGriglia.onTitleClick)
						tiCk = ' onClick="_SelezionaCelleColonna(this, ' + objGriglia.idx + '); _eg[' + objGriglia.idx + '].onTitleClick(this, \'' + f + '\')" ';
					if(objGriglia.onTitleDblClick)
						tiDblCk = ' onDblClick="_eg[' + objGriglia.idx + '].onTitleDblClick(this, \'' + f + '\')" ';

					if(colPropSAV[f] && colPropSAV[f]["ColonnaNonSelezionabile"]){
						titSelezionabile = 0;							
						if(objGriglia.titleClass)
							styleTH = '';
						else 
							styleTH = 'style="' + objGriglia.thStyle + '" ';
					}
					else {
						titSelezionabile = 1;
						if(objGriglia.colSelection || objGriglia.colOrder)							
							if(objGriglia.titleClass)
								styleTH = ' style="cursor:pointer !important;" ';
							else
								styleTH = ' style="cursor:pointer !important; ' + objGriglia.thStyle + '" ';
					}
										
					arr_TBL_HEADER.push('<th inc=');
					arr_TBL_HEADER.push(conta);
					arr_TBL_HEADER.push(' selectable=');
					arr_TBL_HEADER.push(titSelezionabile);
					arr_TBL_HEADER.push(' fieldname="');
					arr_TBL_HEADER.push(f);
					arr_TBL_HEADER.push('" ');
					arr_TBL_HEADER.push(' width="');
					if(colPropSAV[f])
						arr_TBL_HEADER.push(colPropSAV[f]["ColonnaWidth"]);
					arr_TBL_HEADER.push('"');
					arr_TBL_HEADER.push(' datatype="');
					if(colPropSAV[f])
						arr_TBL_HEADER.push(colPropSAV[f]["ColonnaTipo"]);
					arr_TBL_HEADER.push('"');
					arr_TBL_HEADER.push(' class="');
					arr_TBL_HEADER.push(classeTitolo);
					arr_TBL_HEADER.push('" ');
					arr_TBL_HEADER.push(styleTH);
					arr_TBL_HEADER.push(tiCk);
					arr_TBL_HEADER.push(tiDblCk)
					arr_TBL_HEADER.push(' onMouseOver="_GestisciMouseOverTitolo(_eg[');
					arr_TBL_HEADER.push(objGriglia.idx);
					arr_TBL_HEADER.push('], this, \'');
					arr_TBL_HEADER.push(f);
					arr_TBL_HEADER.push('\')" ');
					arr_TBL_HEADER.push('	onMouseOut="_GestisciMouseOutTitolo(_eg[');
					arr_TBL_HEADER.push(objGriglia.idx);
					arr_TBL_HEADER.push('], this, \'');
					arr_TBL_HEADER.push(f);
					arr_TBL_HEADER.push('\')" >');

					var titCol='';
					
					if(objGriglia.onCalcTitles){
						if(colPropSAV[f])
							titCol = colPropSAV[f]["DescrizioneColonna"];
							
						titCol = objGriglia.onCalcTitles(f, titCol);
						//if(titCol==f)
						//	if(colPropSAV[f])
						//		titCol = colPropSAV[f]["DescrizioneColonna"];
					}
					else						
						if(colPropSAV[f])
							titCol = colPropSAV[f]["DescrizioneColonna"];
						
					arr_TBL_HEADER.push(titCol);
															
					arr_TBL_HEADER.push('</th>');
					
					conta++;					
				}
			}
		}
	}
	arr_TBL_HEADER.push('</tr></thead>');
	TBL_HEADER = arr_TBL_HEADER.join('');
	
	arr_TBL.push(TBL_HEADER);
	
	TBL_BODY = '<tbody>';
	
	//scrivo i dati
	var rwCk = ' onClick="_clickOnTr(this, ' + objGriglia.idx + ');" ';
	var rwDblCk = '';
	if(objGriglia.onRowClick)
		rwCk = ' onClick="_clickOnTr(this, ' + objGriglia.idx + '); _eg[' + objGriglia.idx + '].onRowClick(this);" ';
	if(objGriglia.onRowDblClick)
		rwDblCk = ' onDblClick="_eg[' + objGriglia.idx + '].onRowDblClick(this)" ';
		
	for(var r=0; r<fine; r++ ){
		var rigaDispari = ((r+1)/2) == Math.round((r+1)/2);
		var classeRigaCalc = rigaDispari ? classeRigaDispari : classeRigaPari;
		
		arr_TBL_BODY.push('<tr style="');
		arr_TBL_BODY.push(objGriglia.trStyle);
		arr_TBL_BODY.push('" class="');
		arr_TBL_BODY.push(classeRigaCalc);
		arr_TBL_BODY.push('" ');
		arr_TBL_BODY.push(rwCk);
		arr_TBL_BODY.push(rwDblCk);
		arr_TBL_BODY.push(' onMouseOver="_GestisciMouseOverRiga(_eg[');
		arr_TBL_BODY.push(objGriglia.idx);
		arr_TBL_BODY.push('], this, ');
		arr_TBL_BODY.push(rigaDispari);
		arr_TBL_BODY.push(')" ');
		arr_TBL_BODY.push('	onMouseOut="_GestisciMouseOutRiga(_eg[');
		arr_TBL_BODY.push(objGriglia.idx);
		arr_TBL_BODY.push('], this, ');
		arr_TBL_BODY.push(rigaDispari);
		arr_TBL_BODY.push(')" ');
		arr_TBL_BODY.push(' >');
						
		//var unRecord = objGriglia.dataset[r];				
		conta = 0;
		
		for(var f in unRecord){  //faccio sempre riferimento alle celle del primo record
			
			if(typeof(objGriglia.dataset[r][f]) != 'function'){				

				var selezionabile = '1';
				if(colPropSAV[f] && colPropSAV[f]["ColonnaNonSelezionabile"])
					selezionabile = '0';			

				var clCk = ' onClick="_clickOnNonSelectorCell(this, ' + objGriglia.idx + ');"';
				var clDblCk = '';
				if(objGriglia.onCellClick)
					clCk = ' onClick="_clickOnNonSelectorCell(this, ' + objGriglia.idx + '); _eg[' + objGriglia.idx + '].onCellClick(this, \'' + f + '\', ' + r + ');" ';
				if(objGriglia.onCellDblClick)
					clDblCk = ' onDblClick="_eg[' + objGriglia.idx + '].onCellDblClick(this, \'' + f + '\', ' + r + ')" ';

				var strWidth = '';
				if(r==0)
					if(colPropSAV[f])
						strWidth = ' width="' + colPropSAV[f]["ColonnaWidth"] + '" ';					
				
				if(colPropSAV[f] && colPropSAV[f]["ColonnaVisibile"]){
					
					if(objGriglia.dataset[r][f] != undefined){ 

						if(colPropSAV[f] && colPropSAV[f]["ColonnaSelector"] && objGriglia.selectableRows){
							
							arr_TBL_BODY.push('<td inr=');
							arr_TBL_BODY.push(r);
							arr_TBL_BODY.push(' inc=');
							arr_TBL_BODY.push(conta);
							arr_TBL_BODY.push(strWidth);
							arr_TBL_BODY.push(' selectable=');
							arr_TBL_BODY.push(selezionabile);
							arr_TBL_BODY.push(' class="');
							arr_TBL_BODY.push(classeCella);
							arr_TBL_BODY.push('" ');
							arr_TBL_BODY.push(' onMouseOver="_GestisciMouseOverCella(_eg[');
							arr_TBL_BODY.push(objGriglia.idx);
							arr_TBL_BODY.push('], this, \'');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('\', ' + r + ')" ');
							arr_TBL_BODY.push('	onMouseOut="_GestisciMouseOutCella(_eg[');
							arr_TBL_BODY.push(objGriglia.idx);
							arr_TBL_BODY.push('], this, \'');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('\', ' + r + ')" ');
							arr_TBL_BODY.push(' onClick="_clickOnSelectorCell(this, ');
							arr_TBL_BODY.push(objGriglia.idx);
							arr_TBL_BODY.push(', \'');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('\', ' + r + ')" ');
							arr_TBL_BODY.push(clDblCk);
							arr_TBL_BODY.push(' style="cursor:pointer;" ');
							arr_TBL_BODY.push(' align="');
							if(colPropSAV[f])
								arr_TBL_BODY.push(colPropSAV[f]["AllineamentoColonna"]);
							arr_TBL_BODY.push('" ');
							
	
							if(objGriglia.onCalcTD)
								arr_TBL_BODY.push(objGriglia.onCalcTD(f, objGriglia.dataset[r], r));
								
							arr_TBL_BODY.push(' >');
							
						}
						else{
							var cursPointer = '';
							if(selezionabile)
								cursPointer = 'cursor:pointer;';
								
							arr_TBL_BODY.push('<td inr=');
							arr_TBL_BODY.push(r);
							arr_TBL_BODY.push(' inc=');
							arr_TBL_BODY.push(conta);
							arr_TBL_BODY.push(strWidth);
							arr_TBL_BODY.push(' selectable=');
							arr_TBL_BODY.push(selezionabile);
							arr_TBL_BODY.push(' class="');
							arr_TBL_BODY.push(classeCella);
							arr_TBL_BODY.push('" ');
							arr_TBL_BODY.push(' onMouseOver="_GestisciMouseOverCella(_eg[');
							arr_TBL_BODY.push(objGriglia.idx);
							arr_TBL_BODY.push('], this, \'');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('\')" ');
							arr_TBL_BODY.push('	onMouseOut="_GestisciMouseOutCella(_eg[');
							arr_TBL_BODY.push(objGriglia.idx);
							arr_TBL_BODY.push('], this, \'');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('\')" ');
							arr_TBL_BODY.push(' fieldname="');
							arr_TBL_BODY.push(f);
							arr_TBL_BODY.push('" style="');
							arr_TBL_BODY.push(cursPointer);
							arr_TBL_BODY.push('" align="');
							if(colPropSAV[f])
								arr_TBL_BODY.push(colPropSAV[f]["AllineamentoColonna"]);
							arr_TBL_BODY.push('"');
							arr_TBL_BODY.push(clCk);
							arr_TBL_BODY.push(clDblCk);
							arr_TBL_BODY.push(" ");
							
							if(objGriglia.onCalcTD)
								arr_TBL_BODY.push(objGriglia.onCalcTD(f, objGriglia.dataset[r], r));
								
							arr_TBL_BODY.push(' >');
							
						}
						if(objGriglia.onCalcFields)
							var strDato = objGriglia.onCalcFields(f, objGriglia.dataset[r][f], objGriglia.dataset[r], r);
						else
							var strDato = objGriglia.dataset[r][f];					
						arr_TBL_BODY.push(strDato);
						
						arr_TBL_BODY.push('</td>');
					}
					
					
					else {
						//se la cella in questo record non esiste creo una cella dummy
						arr_TBL_BODY.push('<td inr=');
						arr_TBL_BODY.push(r);
						arr_TBL_BODY.push(' inc=');
						arr_TBL_BODY.push(conta);
						arr_TBL_BODY.push(strWidth);
						arr_TBL_BODY.push(' selectable=0');
						arr_TBL_BODY.push(' class="');
						arr_TBL_BODY.push(classeCellaNulla);
						arr_TBL_BODY.push('" fieldname="');
						arr_TBL_BODY.push(f);
						arr_TBL_BODY.push('" >&nbsp;</td>');
						
					}	
					
					conta++;
					
				}
			}
			
		}
		arr_TBL_BODY.push('</tr>');
	}
	
	arr_TBL_BODY.push('</tbody>');
	TBL_BODY = arr_TBL_BODY.join('');
	
	arr_TBL.push(TBL_BODY);
	arr_TBL.push('</table>');
	TBL = arr_TBL.join('');
	
	if(objGriglia.lockedTitles){ //creo una tabella "copia" splittando header e body e aggiungento un div con la scrollbar
		var arr_TBL_B = new Array();
		
		arr_TBL_B.push('<table cellpadding=0 cellspacing=0 width="100%"><tr><td>');
		arr_TBL_B.push(TBL_std);
		arr_TBL_B.push(TBL_HEADER);
		arr_TBL_B.push('</table></td><td id="tdOffsetTitolo');
		arr_TBL_B.push(objGriglia.id);
		arr_TBL_B.push('" style="width:15px;"></td></tr><tr><td colspan=2><div id="divBody_');
		arr_TBL_B.push(objGriglia.id);
		arr_TBL_B.push('" style="height:');
		arr_TBL_B.push(objGriglia.bodyHeight);
		arr_TBL_B.push('px; overflow:auto;">');
		arr_TBL_B.push(TBL_std2);
		arr_TBL_B.push(TBL_BODY);
		arr_TBL_B.push('</table></div></td></tr></table>');
		
		var TBL_B = arr_TBL_B.join('');
	}

	if(targetDiv){
		if(objGriglia.lockedTitles)
			targetDiv.innerHTML = TBL_B;
		else
			targetDiv.innerHTML = TBL;
	}
	if(objGriglia.lockedTitles) //se non è visualizzata la scrollbar, visualizzo la tabella normale
		if(!(document.getElementById('divBody_' + objGriglia.id).scrollHeight > document.getElementById('divBody_' + objGriglia.id).clientHeight))
			targetDiv.innerHTML = TBL;
};

var _cercaColDefault = function(arrObjCols){	
	//ritorna la colonna di default oppure null
	nels = arrObjCols.length;
	for(var i=0; i<nels; i++)
		if(arrObjCols[i]["fieldname"] == 'default_column')			
			return arrObjCols[i];
	return null;
}

var _AggiungiColonneNonDefinite = function(cols, unCds){
	//aggiungo a "columns" tutte le colonne non predefinite dall'utente
	if(!cols){
		cols = new Array();
	}
	var nr = cols.length;
	var trovato;
	
	var colDefault = _cercaColDefault(cols);
	
	for(var f in unCds[0]){
		trovato = true;
		if(f.toUpperCase() != "TOJSONSTRING"){
			trovato = false;
			for(var i=0; i<nr ; i++){
				if(cols[i]["fieldname"] == f){
					trovato = true;
					break;
				}
			}			
		}
		if(!trovato) {
			cols.push(eval("({'fieldname' : '" + f + "'})"));
			//copio le proprieta dall''eventuale default_column
			if(colDefault)
				for(var v in colDefault)
					if(v!='fieldname')
						cols[cols.length-1][v] = colDefault[v];
		}
	}
	return cols;
}

var _RiordinaColonne = function(cols, unCds){
	//ordino le colonne in base alle impostazioni definite
	if(!cols || cols.length==0)
		return;
	var cdsOut = new Array();
	var nr = unCds.length;
	var nc = cols.length;
	var valoreCella;
	for(var c=0; c<nc; c++){
		var nomeColonna = cols[c]["fieldname"];
		
		//scorro le righe del cds
		for(var r=0; r<nr; r++){
			trovato = false;
			for(var f in unCds[r]){
				if(f == nomeColonna){
					valoreCella = unCds[r][nomeColonna];
					trovato = true;
					break;
				}
			}
			if(trovato){
				if(!cdsOut[r])
					cdsOut[r] = new Object();
				cdsOut[r][nomeColonna] = valoreCella;
			}
		}
	}
	return cdsOut;
}

var AssociativeArrLength = function(array){
	lung = 0;
	for (var object in array)
		lung++;
	return lung;
}

var CheckDataset = function(unCds){
	//controllo che i record del dataset contengano tutti gli stessi campi
	var nRighe = unCds.length;
	if(nRighe==1)
		return true;		
	//leggo tutti i campio del primo record
	var campioPrimoRecord = new Array();
	for(var f in unCds[0])
		campioPrimoRecord.push(f);	
	var nCampi = campioPrimoRecord.length;	
	//confronto i campi degli altri record con quelli del primo
	for(var i=1; i<nRighe; i++){		
		if(AssociativeArrLength(unCds[i]) != nCampi) //se il numero di campi è diverso => false
			return false;
		for(var x=0; x<nCampi; x++)
			if(unCds[i][campioPrimoRecord[x]] == null) //se il campo non esiste => false
				return false;
	}
	return true;
}


var _eg = new Array(); //contiene l'elenco delle griglie della pagina; è necessario per gestire gli eventi
var campoOrdinamento;
var dataTypeOrdinamento;
var versoAZ = true;
var nonEseguireClickTR=false;
var lastClickedSelectorCell=new Array();
var lastClickedNonSelectorCell=new Array();

var dummy;
var SJSGrid = function(_tableId, unDataset, objParametri){
	var _divContenitore; //tag in cui effettuare l'innerHTML della griglia
	var _checkDataset = true;
	var _tableClass = ""; 
	var _tableStyle = "width:100%; font-family:Arial; font-size:10px; border-collapse: separate; border-spacing:1px; *border-collapse: expression('separate', cellSpacing = '1px');"; 
	var _trClass = ""; 
	var _trStyle = ""; 
	var _thClass = ""; 
	var _thStyle = "padding:5px; background-color:#A0A0A0; color:#FFFFFF;"; 
	var _onRowTitleClick;
	var _onRowTitleDblClick;
	var _onRowTitleOver;
	var _onRowTitleOut;
	var _onTitleClick;
	var _onTitleDblClick;
	var _onTitleOver;
	var _onTitleOut;
	var _onRowClick;
	var _onRowDblClick;
	var _onRowOver;
	var _onRowOut;
	var _onCellClick;
	var _onCellDblClick;
	var _onCellOver;
	var _onCellOut;
	var _onCalcFields;
	var _onCalcTD;
	var _onCalcTitles;
	var _columns;
	var _cellClass
	var _rowClassOdd;
	var _rowClassEven;
	var _titleClass;
	var _selectorClass;
	var _selectableRows = false;
	var _selectableCells = false;
	var _rowSelector = false;
	var _multiRowSelection=true;
	var _multiCellSelection=true;
	var _colSelection = false;
	var _colOrder = false;
	var _lockedTitles = false;
	var _bodyHeight = false;
	var _selectedCells = new Array();
	var _selectedRows = new Array();
	
	for(var proprieta in objParametri){		
		switch(proprieta){			
			case 'checkDataset':				_checkDataset = objParametri[proprieta]; break;
			case 'tableClass': 					_tableClass = objParametri[proprieta]; break;
			case 'tableStyle': 					_tableStyle  = objParametri[proprieta]; break;
			case 'cellClass':						_cellClass = objParametri[proprieta]; break;
			case 'rowClassOdd':					_rowClassOdd = objParametri[proprieta]; break;
			case 'rowClassEven':				_rowClassEven = objParametri[proprieta]; break;
			case 'titleClass':					_titleClass = objParametri[proprieta]; break;
			case 'selectorClass':				_selectorClass = objParametri[proprieta]; break;
			case 'columns':							_columns = objParametri[proprieta]; break;
			case 'selectableRows':			_selectableRows = objParametri[proprieta]; break;
			case 'selectableCells':			_selectableCells = objParametri[proprieta]; break;
			case 'rowSelector':					_rowSelector = objParametri[proprieta]; break;
			case 'multiRowSelection':		_multiRowSelection = objParametri[proprieta]; break;
			case 'multiCellSelection':	_multiCellSelection = objParametri[proprieta]; break;
			case 'colSelection':				_colSelection = objParametri[proprieta]; break;
			case 'colOrder':						_colOrder = objParametri[proprieta]; break;
			case 'lockedTitles':				_lockedTitles = objParametri[proprieta]; break;
			case 'bodyHeight':					_bodyHeight = objParametri[proprieta]; break;
			case 'onRowTitleClick':			_onRowTitleClick = objParametri[proprieta]; break;
			case 'onRowTitleDblClick':  _onRowTitleDblClick = objParametri[proprieta]; break;
			case 'onRowTitleOver':			_onRowTitleOver = objParametri[proprieta]; break;
			case 'onRowTitleOut':				_onRowTitleOut = objParametri[proprieta]; break;
			case 'onTitleClick':				_onTitleClick = objParametri[proprieta]; break;
			case 'onTitleDblClick':  		_onTitleDblClick = objParametri[proprieta]; break;
			case 'onTitleOver':					_onTitleOver = objParametri[proprieta]; break;
			case 'onTitleOut':					_onTitleOut = objParametri[proprieta]; break;
			case 'onCellClick':					_onCellClick = objParametri[proprieta]; break;
			case 'onCellDblClick': 			_onCellDblClick = objParametri[proprieta]; break;
			case 'onCellOver':					_onCellOver = objParametri[proprieta]; break;
			case 'onCellOut':						_onCellOut = objParametri[proprieta]; break;
			case 'onRowClick':					_onRowClick = objParametri[proprieta]; break;
			case 'onRowDblClick': 		 	_onRowDblClick = objParametri[proprieta]; break;
			case 'onRowOver':						_onRowOver = objParametri[proprieta]; break;
			case 'onRowOut':						_onRowOut = objParametri[proprieta]; break;
			case 'onCalcFields':				_onCalcFields = objParametri[proprieta]; break;
			case 'onCalcTD':						_onCalcTD = objParametri[proprieta]; break;
			case 'onCalcTitles':				_onCalcTitles = objParametri[proprieta]; break;			
		}
	}
		
	if(_tableId == undefined || _tableId == ''){
		alert("Errore: Il parametro 'id' è obbligatorio e non è stato definito.")
		return;
	}
	else if(!unDataset || unDataset == undefined || typeof(unDataset)!='object'){
		alert("Errore: Il parametro 'dataset' è obbligatorio e non è stato definito.")
		return;
	}
	
	if(_checkDataset){
		if(!CheckDataset(unDataset))
			alert("Errore non bloccante: Il dataset contiene record non omogenei (record con campi diversi).");
	}
	
	
	_columns = _AggiungiColonneNonDefinite(_columns, unDataset);
	unDataset = _RiordinaColonne(_columns, unDataset);

	this.id 							= _tableId;	
	this.dataset 					= unDataset;	
	this.columns					= _columns;
	this.tableClass				= _tableClass;
	this.tableStyle				= _tableStyle;
	this.trClass					= _trClass;
	this.trStyle					= _trStyle;	
	this.thStyle					= _thStyle;
	this.cellClass				= _cellClass;
	this.rowClassOdd			= _rowClassOdd;
	this.rowClassEven			= _rowClassEven;

	if(this.trClass=="" && this.trStyle == "" && this.rowClassOdd == "" && this.rowClassEven == ""){
		this.trClass="testo";
		this.trStyle="background-color:#EEEEEE;" ;
	}	
	
	this.titleClass				= _titleClass;
	this.selectorClass		= _selectorClass;
	this.onRowTitleClick 		= _onRowTitleClick;
	this.onRowTitleDblClick	= _onRowTitleDblClick;
	this.onRowTitleOver			= _onRowTitleOver;
	this.onRowTitleOut 			= _onRowTitleOut;
	this.onTitleClick 		= _onTitleClick;
	this.onTitleDblClick	= _onTitleDblClick;
	this.onTitleOver			= _onTitleOver;
	this.onTitleOut 			= _onTitleOut;
	this.onRowClick 			= _onRowClick;
	this.onRowDblClick		= _onRowDblClick;
	this.onRowOver 				= _onRowOver;
	this.onRowOut 				= _onRowOut;
	this.onCellClick 			= _onCellClick;
	this.onCellDblClick		= _onCellDblClick;
	this.onCellOver 			= _onCellOver;
	this.onCellOut 				= _onCellOut;
	this.onCalcFields			= _onCalcFields;
	this.onCalcTD					= _onCalcTD;
	this.onCalcTitles			= _onCalcTitles;
	this.rowSelector	 		= _rowSelector;
	this.multiRowSelection=_multiRowSelection;
	this.multiCellSelection=_multiCellSelection || _selectableRows;
	this.colSelection 		= _colSelection;	
	this.selectableRows 	= _selectableRows;
	this.selectableCells 	= _selectableCells || _colSelection;
	this.colOrder					= _colOrder;
	this.fieldnameOrder 	= '_default';
	this.dataTypeOrder		= 'string';
	this.idx 							= _eg.length;
	this.recordCount 			= unDataset.length;	
	this.selectedRows 		= _selectedRows;	
	this.selectedCells 		= _selectedCells;	
	this.selectAllCells 	= _selectAllCells;	

	this.lockedTitles			= _lockedTitles;
	this.bodyHeight				= _bodyHeight;

	this.Sort	= _sort;
	this.Show = _draw;			
	
	_eg.push(this);	
	return this;
};

/*--------------------------------------------------------------------------*/
/*  SJSGrid JavaScript grid, version 1.3.5
 *  2008 - Gianluca Ungaro
 *  Creation date: 25/11/2008
 *	Last Update 02/07/2009
/*--------------------------------------------------------------------------*/
