/*

Dynamic table sorting code.  Copyright (c) 2007.  Matt Cowperthwaite.  All rights reserved.

	Based extensively on the following code, which is freely
	available at the following URL's.

	Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
	Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
	Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html.
	Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.  Version 1.5.6
	
	Code modified to include nested sorted of multiple columns.

*/

var SORT_COLUMN_INDEX;
var SORT_DIRETION;
var SORT_COLS        = new Array(7);
var PRIMARY_SORT_COL = -1;
var SORT_DIR         = new Array(7);
var LAST_SORTED;

make_sort_cols();

function ts_resortTable( tableName, column ) {
		
	/* change direction of sort if its a repeated click on the same column
		or a the first time we are sorting the column
	
		if we are selecting a new table to be sorted, then we want to 
		reset the sort directions to their default values
		
	*/
	
	// if we are sorting the same column in the table last sorted
	//  then we change the direction of the sort for that column
	// otherwise, if we are sorting a new table, then we reset
	// the sort dir array to be ascending in all columns
	if ( tableName == LAST_SORTED && column == PRIMARY_SORT_COL )
		SORT_DIR[column] *= -1;
	else if ( tableName != LAST_SORTED ) {
		for ( i = 0; i < 7; ++i )
			SORT_DIR[i] = 1;
	}
		
	/*  if the user clicked producer or item as the primary sort,
		then we always want vintage as descending
	*/
	if ( column == 3 || column == 5 )
		SORT_DIR[2] = -1;
	
	var t = document.getElementById( tableName );
	if ( t.tBodies[0].rows.length <= 1 )
		return;
		
	var newRows = new Array();
	for ( j = 0; j < t.tBodies[0].rows.length; j++)
		newRows[j] = t.tBodies[0].rows[j];
		
	PRIMARY_SORT_COL = column;
	newRows.sort( masterSort )
	
    // We appendChild rows that already exist to the tbody, so it moves
	// them rather than creating new ones
    for (i = 0; i < newRows.length; i++)
		t.tBodies[0].appendChild(newRows[i]);
	
	delete t;
	delete newRows;
	LAST_SORTED = tableName;
	
}

function masterSort( a, b ) {
	
	for ( var k = 0; k < SORT_COLS.length; k++ ) {
		
		if ( k != 3 ) {

			SORT_COLUMN_INDEX = SORT_COLS[PRIMARY_SORT_COL][k];

			// Work out a type for the column
			var sortfn;	
			if ( SORT_COLUMN_INDEX == 3 || SORT_COLUMN_INDEX == 5 )
				sortfn = ts_sort_caseinsensitive;
			else
				sortfn = ts_sort_numeric;
			
			SORT_DIRECTION = SORT_DIR[SORT_COLUMN_INDEX];
		
			var result = sortfn( a, b );
		
			if ( result != 0 )
				return result;
			
		}
			
	}
		
	return 0;
		
}

/* set up a matrix with the order of sorting 
	contingent upon the column clicked and the
	array for the sort directionality
*/

function make_sort_cols ( ) {
	
	for ( i = 0; i < 7; ++i ) {
		SORT_COLS[i] = new Array(7);
		SORT_DIR[i] = 1;
	}
	
	// sort order of vintage
	// vintage, producer, descr, size, price, pack
	SORT_COLS[2][0] = 2;
	SORT_COLS[2][1] = 3;
	SORT_COLS[2][2] = 5;
	SORT_COLS[2][4] = 1;
	SORT_COLS[2][5] = 6;
	SORT_COLS[2][6] = 0;
	
	// column 4 producer will sort on column 3 (the hidden sort value)
	// producer, descr, vintage, size, price, pack
	SORT_COLS[3][0] = 3;
	SORT_COLS[3][1] = 5;
	SORT_COLS[3][2] = 2;
	SORT_COLS[3][4] = 1;
	SORT_COLS[3][5] = 6;
	SORT_COLS[3][6] = 0;
	
	// sort order for description
	// descr, producer, vintage, size, price, pack
	SORT_COLS[5][0] = 5;
	SORT_COLS[5][1] = 3;
	SORT_COLS[5][2] = 2;
	SORT_COLS[5][4] = 1;
	SORT_COLS[5][5] = 6;
	SORT_COLS[5][6] = 0;	
		
}

function ts_sort_numeric(a,b) {
	var aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
	aa = clean_num(aa);
	var bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
	bb = clean_num(bb);
	return compare_numeric(aa,bb);
}

function compare_numeric(a,b) {
	
	var a = parseFloat(a);
	a = (isNaN(a) ? 0 : a);
	var b = parseFloat(b);
	b = (isNaN(b) ? 0 : b);
	
	if ( SORT_DIRECTION > 0 )
		return a - b;

	return b - a;
		
}

function ts_sort_caseinsensitive(a,b) {
	
	aa = ts_getInnerText( a.cells[SORT_COLUMN_INDEX] ).toLowerCase();
	bb = ts_getInnerText( b.cells[SORT_COLUMN_INDEX] ).toLowerCase();
	
	cc = clean_wines(aa);
	dd = clean_wines(bb);
	
	// alert( aa + " --> " + cc + "\n" + bb + " --> " + dd )
		
	if ( cc == dd )
		return 0;
	
	if ( cc < dd ) {
		if ( SORT_DIRECTION > 0 )
			return -1;
		return 1;
	}
	
	if ( SORT_DIRECTION > 0 )
		return 1;
	return -1;
	
	delete cc;
	delete dd;
	
}

function clean_wines(str) {

	newStr = str.replace(new RegExp(/[âäàåáã]/g),"a");
	newStr = newStr.replace(new RegExp(/[Ñ]/g),"N");
	newStr = newStr.replace(new RegExp(/[Ý]/g),"Y");
	newStr = newStr.replace(new RegExp(/[ÉÊËÈ]/g),"E");
	newStr = newStr.replace(new RegExp(/[ÿý]/g),"y");
	newStr = newStr.replace(new RegExp(/[üûùú]/g),"u");
	newStr = newStr.replace(new RegExp(/[ß]/g),"ss");
	newStr = newStr.replace(new RegExp(/[Ç]/g),"C");
	newStr = newStr.replace(new RegExp(/[ïîìí]/g),"i");
	newStr = newStr.replace(new RegExp(/[éêëè]/g),"e");
	newStr = newStr.replace(new RegExp(/[ÄÅÁÂÀÃ]/g),"A");
	newStr = newStr.replace(new RegExp(/[ÖÓÔÒÕ]/g),"O");
	newStr = newStr.replace(new RegExp(/[ñ]/g),"n");
	newStr = newStr.replace(new RegExp(/[ç]/g),"c");
	newStr = newStr.replace(new RegExp(/[Æ]/g),"AE");
	newStr = newStr.replace(new RegExp(/[Ð]/g),"D");
	newStr = newStr.replace(new RegExp(/[ÍÎÏÌ]/g),"I");
	newStr = newStr.replace(new RegExp(/[æ]/g),"ae");
	newStr = newStr.replace(new RegExp(/[ôöòóðõ]/g),"o");
	newStr = newStr.replace(new RegExp(/[ÜÚÛÙ]/g),"U");
	newStr = newStr.replace(new RegExp(/[,]/g),"");
	
	return newStr;
	
}

function clean_num(str) {
	str = str.replace(new RegExp(/[^-?0-9.,]/g),"");
	return str;
}

function ts_getInnerText( el ) {
	
	if (typeof el == "string")
		return el;
	if (typeof el == "undefined")
		return el;
	
	if ( el.innerText )
		return el.innerText;	//Not needed but it is faster
	
	var str = "";
	var cs = el.childNodes;
	var l = cs.length;
	
	for ( var i = 0; i < l; i++ ) {
		
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
		
	}
	
	return str;
	
}
