/**
 * @author 	Pascal Noordink
 * @version 12-11-2008
 */
var poGridInstance 	= null;

 /**
 * Als de body geladen is dan het `PioenPartners_JS_Grid` object aan het
 * grid koppelen. 
 */
/*laOnloadActions.push(
	function() {
 		// Instantie van de grid maken.
 		PioenPartners_JS_Grid.initGrid("PPGrid");
	}
);*/

var PioenPartners_JS_Grid = {
 	_lnSorted : 0,
 
 	/**
 	 * Maak een instantie van het Grid en geef het Grid een standaard ordening.
 	 *
 	 * @param	lcGrid
 	 * @return	void
 	 */
 	initGrid : function(lcGrid) { 	
 		// Grid element opvragen.
 		var loGrid		= document.getElementById(lcGrid);
 		var loBody 		= document.getElementById(lcGrid + "Body");
 		var loHeader	= document.getElementById(lcGrid + "Header");

 		// Gegevens uit het grid mogen niet geselecteerd worden.
 		this._disableSelect(loBody);
 		this._disableSelect(loHeader);
 		
	 	// De body van het grid resizen. (Dit kan niet in CSS)	 	
	 	try {
	 		if(loGrid.style.width.indexOf("%") == -1) {
	 			loBody.style.height = (parseInt(loGrid.style.height) - 20) + "px";
	 			loBody.style.width  = (parseInt(loGrid.style.width)) + "px";
	 		} else {
	 			//loBody.style.height = (parseInt(loGrid.style.height) - 30) + "px";
	 			//loBody.style.width  = (parseInt(loGrid.style.width)) + "%";
	 		}
 		} catch(e) {}
	 	
 		// Instantie van de `PioenPartners_JS_Grid` class in een globable variabele
 		// opslaan. Bij het uitvoeren van functies op het grid kan de instantie
 		// gebruikt worden. Deze is op dat punt namelijk niet meer bekend.
 		poGridInstance = this; 		

 		// Lege textNodes verwijderen om problemen met FireFox te voorkomen.
		this._cleanNodes(loGrid) 		
 		
		// De eerste regel selecteren.
		var loRow = loHeader.getElementsByTagName("div")[0];
		
		// Alle kolommen van het grid doorlopen en deze sorteerbaar maken.
		var lnColumns = loRow.getElementsByTagName("div").length;
		
		for(var lnI = 0; lnI < lnColumns; lnI++) {
			var loColumn = loRow.getElementsByTagName("div")[lnI];
			
			// Een `onclick` event toevoegen aan de header. Als er op de header
			// wordt geklikt dan wordt de functie `doSort` voor de desbetreffende
			// kolom uitgevoerd.
			loColumn.onclick = new Function("document.getElementById('"+ lcGrid +"Wait').style.visibility = 'visible'; setTimeout(\"PioenPartners_JS_Grid.doSort('"+ lcGrid +"', "+ lnI +");\", 100);");
			
			// Standaard is geen enkele kolom geordend. In de functie `doSort`
			// wordt een kolom gekozen om op te ordenen.
			loColumn.className = 'OrderNone';
		}

 		// Even en oneven regels tekenen.
 		this._showLines(loBody);		
 	},
 	
 	/**
 	 * De functie 'chromeFix' voegt alle regels opnieuw toe aan het Grid
 	 * om Chrome en Safari expliciet de grootte opnieuw te laten bepalen.
 	 */
 	chromeFix : function(lcGrid) {
 		// Grid element opvragen.
 		var loGrid		= document.getElementById(lcGrid);
 		var loBody 		= document.getElementById(lcGrid + "Body");
	 	
		// Alle rows doorlopen en deze in een array opslaan, als er straks wordt
		// geordend opnieuw opbouwen. 
		var laRows = new Array();
		var lnRows = loBody.getElementsByTagName("div").length;
		
		for(var lnI = 0; lnI < lnRows; lnI++) {
			if(loBody.getElementsByTagName("div")[lnI].className != "PPGridColumn") {
				laRows.push(loBody.getElementsByTagName("div")[lnI]);
			}
		}
		
		// Alle geordende rows weer toevoegen aan de grid.
		var lnRows = laRows.length;
		
		for(var lnI = 0; lnI < lnRows; lnI++) {
			loBody.appendChild(laRows[lnI]);
		}
 	},
 	
 	/**
 	 * De regels ordenen op inhoud. Tevens de weergave van de header wijzigen
 	 * als een sorteer volgorde wordt gewijzigd.
 	 *
 	 * @param	lcGrid
 	 * @param	lnIndex
 	 * @return	void
 	 */ 	
 	doSort : function(lcGrid, lnIndex) {
 		// Grid element opvragen.
 		var loBody 		= document.getElementById(lcGrid + "Body");
 		var loHeader	= document.getElementById(lcGrid + "Header");

		// Div tonen om te laten zien dat het grid bijgewerkt wordt.
		document.getElementById(lcGrid +"Wait").style.visibility = "visible";

 		// De kolom die wordt gesorteerd opslaan in de variabele `_lnSorted`
 		// zodat de sorteer functie er nog bij kan.
 		this._lnSorted = lnIndex;

 		// De gekozen kolom opvragen.
 		var loRow 		= loHeader.getElementsByTagName("div")[0];
		var loColumn	= loRow.getElementsByTagName("div")[lnIndex];
		
		// Als de gekozen kolom al een order heeft dan omdraaien, als dat niet
		// het geval is dan beginnen met ASC.
		var lcOrder = 'ASC';
		
		switch(loColumn.className) {
			case 'OrderASC':
				loColumn.className  = 'OrderDESC';
				lcOrder				= 'DESC'
				break;
				
			case 'OrderDESC':
				loColumn.className = 'OrderASC';
				break;
				
			case 'OrderNone':
				loColumn.className = 'OrderASC';
				break;
		}
		
		// Alle andere kolommen mogen geen order meer bevatten. Tevens dient
		// het uiterlijk te worden gewijzigd door de css class naam te wijzigen.
		var lnColumns = loRow.getElementsByTagName("div").length;
		
		for(lnI = 0; lnI < lnColumns; lnI++) {
			if(lnI != lnIndex) {
				loRow.getElementsByTagName("div")[lnI].className = 'OrderNone';
			}
		}
		
		// Alle rows doorlopen en deze in een array opslaan, als er straks wordt
		// geordend opnieuw opbouwen. 
		var laRows = new Array();
		var lnRows = loBody.getElementsByTagName("div").length;
		
		for(var lnI = 0; lnI < lnRows; lnI++) {
			if(loBody.getElementsByTagName("div")[lnI].className != "PPGridColumn") {
				laRows.push(loBody.getElementsByTagName("div")[lnI]);
			}
		}
	
		// Initieel String.
		var lcType = "String";
		var lnRows = laRows.length;

		for(var lnI = 0; lnI < lnRows; lnI++) {
			var luValue = this._getColumnValue(laRows[lnI].childNodes[lnIndex]);
			
			// Voor uiterlijk plaatsen we vaak een streepjes tussen de datum en tijd, hier dus
			// ook op testen.
			if(luValue.length != 0) {
				if(luValue.match(/[0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}/)) {
					lcType = "DateTime";
				} else if(luValue.match(/[0-9]{2}-[0-9]{2}-[0-9]{4} - [0-9]{2}:[0-9]{2}/)) {
					lcType = "DateTime";		
				} else if(luValue.match(/[0-9]{2}-[0-9]{2}-[0-9]{4}/)) {
					lcType = "Date";					
				} else if(!isNaN(luValue)) {
					lcType = "Numeric";
				} else {
					lcType = "String";
				}
				
				// Type is gevonden dus stoppen.
				lnI = laRows.length;					
			}
		}
		
		// Alle rows ordenen met de functie `_doSort.......`.
		if(lcType == "DateTime") {
			laRows.sort(this._doSortDateTime);
		} else if(lcType == "Date") {
			laRows.sort(this._doSortDate);
		} else if(lcType == "Numeric") {
			laRows.sort(this._doSortNumeric);
		} else {
			laRows.sort(this._doSortString);
		}

		// Als de order op DESC staat dan de array omdraaien.
		if(lcOrder == 'DESC') {
			laRows.reverse();
		}

		// Alle geordende rows weer toevoegen aan de grid.
		for(var lnI = 0; lnI < lnRows; lnI++) {
			loBody.appendChild(laRows[lnI]);
		}

		// Het ordenen is gereed dus de melding kan weer weg worden gehaald.
		document.getElementById(lcGrid +"Wait").style.visibility = "hidden";

 		// Even en oneven regels tekenen.
 		this._showLines(loBody);				
 	},
 	
 	/**
 	 * De functie 'doFilter' loopt alle elementen in het Grid langs en maakt
 	 * de elementen die niet aan het filter voldoen onzichtbaar.
 	 *
 	 * @param	lcGrid
 	 * @param	lcFilterText
 	 * @return	Void
 	 */
 	doFilter : function(lcGrid, lcFilterText) {
 		/** 
 		 * Grid element opvragen.
 		 */
 		var loBody 			= document.getElementById(lcGrid + "Body");
 		var lcFilterText	= lcFilterText.toUpperCase();
 		
 		/**
 		 * Alle regels in het Grid langslopen.
 		 */
 		var lnRows = loBody.getElementsByTagName("div").length;
		for(var lnI = 0; lnI < lnRows; lnI++) {
			/**
			 * De regel node opvragen.
			 */
			var loRow = loBody.getElementsByTagName("div")[lnI];
				
			if(loRow.className != "PPGridColumn") {
				/**
				 * Alle kolommen in de regel doorlopen, als er ook maar één aan
				 * de voorwaarde voldoet dan blijven tonen.
				 */ 
				var llFound = false;
				
				/**
				 * Als er geen filter is opgegeven dan alles tonen.
				 */
				if(lcFilterText == "") {
					llFound = true;
				} else {
					/**
					 * Voor de snelheid gaan we niet elke kolom langs maar alleen de
					 * volledige tekst van de regel. Hierin zit dan jammergenoeg
					 * ook de opmaak dus bij het intikken van bijvoorbeeld 'DIV' zijn
					 * alle regels gewoon zichtbaar.
					 */
					if(document.all){
         				llFound = loRow.innerText.toUpperCase().indexOf(lcFilterText) != -1;
		            }   
		            else{
		                llFound = loRow.textContent.toUpperCase().indexOf(lcFilterText) != -1;
		            }   
		           //var lnColumns = loRow.getElementsByTagName("div").length;
					//
					//for(var lnC = 0; lnC < lnColumns; lnC++) {
					//	if(poGridInstance._getColumnValue(loRow.childNodes[lnC]).toUpperCase().indexOf(lcFilterText) != -1) {
					//		llFound = true;
					//		break;
					//	}
					//}
				}
				
				/**
				 * Als geen enkele waarde aan het filter voldoet dan niet meer
				 * tonen.
				 */
				if(llFound == false) {
					loRow.style.display = "none";
				} else {
					loRow.style.display = "block";
				}
			}
		} 		

 		/** 
 		 * Even en oneven regels tekenen.
 		 */
 		this._showLines(loBody);
 	},
 	
  	/**
 	 * Sorteer functie die wordt aangeroepen vanuit de functie `doSort`. Als de
 	 * methode `sort` op een array wordt uitgevoerd dan wordt deze functie 
 	 * aangeroepen.
 	 * De functie vergelijkt 2 waarden met elkaar en geeft dan.
 	 *	. -1 terug als A voor B ligt.
 	 *	. 0 terug als de waardes gelijk zijn. 	 
 	 *	. 1 terug als B voor A ligt. 
 	 *
 	 * @param	loRowA
 	 * @param	loRowB
 	 * @return	Integer
 	 */ 	 	
 	_doSortDateTime : function(loRowA, loRowB) {
 		// De waarden van regel A vergelijken met regel B.
		var lcValueA = poGridInstance._getColumnValue(loRowA.childNodes[poGridInstance._lnSorted]).toLowerCase();
		var lcValueB = poGridInstance._getColumnValue(loRowB.childNodes[poGridInstance._lnSorted]).toLowerCase();

		// De eventuele streep tussen de datum en tijd verwijderen.
		lcValueA = lcValueA.replace(" - ", " ");
		lcValueB = lcValueB.replace(" - ", " ");
		
		// De opgegeven datums en tijden omschrijven naar het formaat: `jjjjmmddhhmm`.
		var lnValueA = lcValueA.substr(6, 4) + lcValueA.substr(3, 2) + lcValueA.substr(0, 2) + lcValueA.substr(11, 2) + lcValueA.substr(14, 2);
		var lnValueB = lcValueB.substr(6, 4) + lcValueB.substr(3, 2) + lcValueB.substr(0, 2) + lcValueB.substr(11, 2) + lcValueB.substr(14, 2);
		
		// Als de waardes overeenkomen dan `0` retourneren.
		if (lnValueA == lnValueB) {
			return 0;
		}
		
		// Als de waarde van A voor de waarde van B ligt dan `-1` retourneren.
		if (lnValueA < lnValueB) {
			return -1;
		}
		
		// Als de waarde van B voor de waarde van A ligt dan `1` retourneren.
		return 1;
 	}, 	
 	
 	/**
 	 * Sorteer functie die wordt aangeroepen vanuit de functie `doSort`. Als de
 	 * methode `sort` op een array wordt uitgevoerd dan wordt deze functie 
 	 * aangeroepen.
 	 * De functie vergelijkt 2 waarden met elkaar en geeft dan.
 	 *	. -1 terug als A voor B ligt.
 	 *	. 0 terug als de waardes gelijk zijn. 	 
 	 *	. 1 terug als B voor A ligt. 
 	 *
 	 * @param	loRowA
 	 * @param	loRowB
 	 * @return	Integer
 	 */ 	 	
 	_doSortDate : function(loRowA, loRowB) {
 		// De waarden van regel A vergelijken met regel B.
		var lcValueA = poGridInstance._getColumnValue(loRowA.childNodes[poGridInstance._lnSorted]).toLowerCase();
		var lcValueB = poGridInstance._getColumnValue(loRowB.childNodes[poGridInstance._lnSorted]).toLowerCase();

		// De opgegeven datums omschrijven naar het formaat: `jjjjmmdd`.
		var lnValueA = lcValueA.substr(6, 4) +"-"+ lcValueA.substr(3, 2) +"-"+ lcValueA.substr(0, 2);
		var lnValueB = lcValueB.substr(6, 4) +"-"+ lcValueB.substr(3, 2) +"-"+ lcValueB.substr(0, 2);
			
		// Als de waardes overeenkomen dan `0` retourneren.
		if (lnValueA == lnValueB) {
			return 0;
		}
		
		// Als de waarde van A voor de waarde van B ligt dan `-1` retourneren.
		if (lnValueA < lnValueB) {
			return -1;
		}
		
		// Als de waarde van B voor de waarde van A ligt dan `1` retourneren.
		return 1;
 	}, 	
 	
 	/**
 	 * Sorteer functie die wordt aangeroepen vanuit de functie `doSort`. Als de
 	 * methode `sort` op een array wordt uitgevoerd dan wordt deze functie 
 	 * aangeroepen.
 	 * De functie vergelijkt 2 waarden met elkaar en geeft dan.
 	 *	. -1 terug als A voor B ligt.
 	 *	. 0 terug als de waardes gelijk zijn. 	 
 	 *	. 1 terug als B voor A ligt. 
 	 *
 	 * @param	loRowA
 	 * @param	loRowB
 	 * @return	Integer
 	 */ 	 	
 	_doSortNumeric : function(loRowA, loRowB) {
 		// De waarden van regel A vergelijken met regel B.
		var lnValueA = parseFloat(poGridInstance._getColumnValue(loRowA.childNodes[poGridInstance._lnSorted]));
		var lnValueB = parseFloat(poGridInstance._getColumnValue(loRowB.childNodes[poGridInstance._lnSorted]));

		// Als de waardes overeenkomen dan `0` retourneren.
		if (lnValueA == lnValueB) {
			return 0;
		}
		
		// Als de waarde van A voor de waarde van B ligt dan `-1` retourneren.
		if (lnValueA < lnValueB) {
			return -1;
		}
		
		// Als de waarde van B voor de waarde van A ligt dan `1` retourneren.
		return 1;		
 	}, 	 	
 	
 	/**
 	 * Sorteer functie die wordt aangeroepen vanuit de functie `doSort`. Als de
 	 * methode `sort` op een array wordt uitgevoerd dan wordt deze functie 
 	 * aangeroepen.
 	 * De functie vergelijkt 2 waarden met elkaar en geeft dan.
 	 *	. -1 terug als A voor B ligt.
 	 *	. 0 terug als de waardes gelijk zijn. 	 
 	 *	. 1 terug als B voor A ligt. 
 	 *
 	 * @param	loRowA
 	 * @param	loRowB
 	 * @return	Integer
 	 */ 	
 	_doSortString : function(loRowA, loRowB) {
 		// De waarden van regel A vergelijken met regel B.
		var lcValueA = poGridInstance._getColumnValue(loRowA.childNodes[poGridInstance._lnSorted]).toLowerCase();
		var lcValueB = poGridInstance._getColumnValue(loRowB.childNodes[poGridInstance._lnSorted]).toLowerCase();

		// Als de waardes overeenkomen dan `0` retourneren.
		if (lcValueA == lcValueB) {
			return 0;
		}
		
		// Als de waarde van A voor de waarde van B ligt dan `-1` retourneren.
		if (lcValueA < lcValueB) {
			return -1;
		}
		
		// Als de waarde van B voor de waarde van A ligt dan `1` retourneren.
		return 1;		
 	},
 	
 	/**
 	 * De waarde uit een opgegeven kolom opvragen.
 	 *
 	 * @param	loColumn
 	 * @return	Undefined
 	 */ 	
 	 _getColumnValue : function(loColumn) {
 	 	// Initieel leeg.
 	 	var luValue = "";
 	 	
		// Alle kinderen van de opgegeven kolom doorlopen.
		var laChildren = loColumn.childNodes;

		try {
			var lnChildren = laChildren.length;
			
			for(var lnI = 0; lnI < lnChildren; lnI++) {
				if(laChildren[lnI].tagName != "DIV") {
					if(laChildren[lnI].nodeValue.length != 0) {
						luValue = laChildren[lnI].nodeValue;
						break;
					}
				} else {
					luValue = this._getColumnValue(laChildren[lnI].childNodes);
				}			
			}
		} catch(e) {}
 	 
		// Waarde retourneren.
		return luValue; 	 	
 	 },
 	 
	/**
	 * Opschonen van het DOM (Data Object Model).
	 * textNodes vallen binnen de set van Childnodes in FireFox.
	 * Binnen IE worden ze genegeerd, om de verwerking hetzelfde te houden
	 * worden de textNodes verwijdert als deze leeg zijn.
	 *
	 * @param	loNode
	 */
	_cleanNodes : function(loNode) {
		// Alle kinderen opvragen.
		var loExpr 	= /\S/;
		var lnNodes = loNode.childNodes.length;
			
		for(var lnI = 0; lnI < lnNodes; lnI++) {
			try {
				var loChildNode = loNode.childNodes[lnI];
				
				// Als de node een textnode is en leeg is dan verwijderen.
				if(loChildNode.nodeType == 3 && 
				   !loExpr.test(loChildNode.nodeValue)) {
					loNode.removeChild(loNode.childNodes[lnI]);
				
					lnI--;
				}
				
				// Als de node kinderen kan hebben dan deze ook opschonen.
				if (loChildNode.nodeType == 1) {
					this._cleanNodes(loChildNode);
				}
			} catch(e) {}
		}
	},
 	
 	/**
 	 * Even en oneven regels een andere kleur geven. Tevens regels waar met de muis
 	 * overheen wordt bewogen een andere kleur geven.
 	 *
 	 * @param	loBody
 	 * @return	void
 	 */ 	
 	_showLines : function(loBody) {
 		// Alle regels doorlopen. 
 		var lnShownRows = 0;
 		var lnRows		= loBody.getElementsByTagName("div").length;
 		 
 		for(var lnI = 0; lnI < lnRows; lnI++) {
	 		/**
	 		 * Rownode opvragen.
	 		 */
	 		var loRow = loBody.getElementsByTagName("div")[lnI];
	 		
	 		/**
	 		 * Kolommen opnieuw kleuren.
	 		 */
			if(loRow.className != "PPGridColumn") {
				/**
				 * Alleen zichtbare kolommen opnieuwe kleuren.
				 */
				if(loRow.style.display != "none") {
		 			// Even krijgt de class naam `Even`.
		 			// Oneven krijgt de class naam `Odd`.
					if((lnShownRows % 2) == 0) {
						loRow.className = 'Even';
					} else {
						loRow.className = 'Odd';
					}
					
					lnShownRows++;
				}
				
				/**
				 * Een mouseover en mouseout event koppelen, hierdoor
				 * verandert de kleur van de regel bij mousover.
				 */
				loRow.onmouseover = function() {
					this.className = 'Hover';
				}
				
				// Als de muis van de regel af wordt bewogen dan de className
				// veranderen in het origineel.
				loRow.classOld = loRow.className;
							
				loRow.onmouseout = function(e) {
					this.className = this.classOld;				
				} 
			}
 		}
 	},

 	/**
 	 * De mogelijkheid voor de gebruiker om tekst te selecteren onmogelijk maken
 	 * voor het opgegeven object.
 	 *
 	 * @param	loElement
 	 * @return	void
 	 */ 	
 	_disableSelect : function(loElement) {
 		// Functie toevoegen die wordt getriggered als er met de muis tekst
 		// wordt geselecteerd.
 		loElement.onselectstart = function() {
        	return false;
    	};
    	
    	// Voor alle browsers zorgen dat de tekst niet geselecteerd kan worden.
    	loElement.unselectable 			= "on";
    	loElement.style.MozUserSelect 	= "none";
    	loElement.style.cursor 			= "default";
 	}
 };
