// Created by Will Dudziak, 03.09.05, www.dudziak.com

function CreateArray(dim1) {
	if (CreateArray.arguments.length == 1) {
		return new Array(dim1);
	} else {
		var multiArray = new Array(dim1)
		for (var i = 0; i < dim1; i++) {
			multiArray[i] = new Array(CreateArray.arguments[1]);
		}
		return multiArray;
	}
}

function TriQuickSort2D (inpArray, PrimarySort, PrimaryAscending, SecondarySort, SecondaryAscending) { // Ascending is a boolean variable
	var indexArray = CreateArray(inpArray.length);
	for (var i = 0; i < indexArray.length; i++) {
		indexArray[i] = i;
	}
	TriQuickSortMain2D(inpArray, indexArray, 4, 0, inpArray.length - 1, PrimarySort);
	InsertionSort2D(inpArray, indexArray, 0, inpArray.length - 1, PrimarySort);
	if (!PrimaryAscending) {
		ReverseIndex(indexArray);
	}
	ApplyIndex2D(inpArray, indexArray)
	if (SecondarySort != null) {
		inpArray = ApplySecondarySort2D(inpArray, PrimarySort, SecondarySort, SecondaryAscending);
	}
	return inpArray;
}

function TriQuickSortMain2D (inpArray, indexArray, iSplit, iMin, iMax, ColNo) {
	var temphold
	var vTemp
	if (iMax - iMin > iSplit) { 
		i = Math.floor((iMax + iMin) / 2);
		if (inpArray[indexArray[iMin]][ColNo].toLowerCase() > inpArray[indexArray[i]][ColNo].toLowerCase()) {
			temphold = indexArray[iMin]; indexArray[iMin] = indexArray[i]; indexArray[i] = temphold;
		}
		if (inpArray[indexArray[iMin]][ColNo].toLowerCase() > inpArray[indexArray[iMax]][ColNo].toLowerCase()) {
			temphold = indexArray[iMin]; indexArray[iMin] = indexArray[iMax]; indexArray[iMax] = temphold;
		}
		if (inpArray[indexArray[i]][ColNo].toLowerCase() > inpArray[indexArray[iMax]][ColNo].toLowerCase()) {
			temphold = indexArray[i]; indexArray[i] = indexArray[iMax]; indexArray[iMax] = temphold;
		}
		j = iMax - 1;
		temphold = indexArray[i]; indexArray[i] = indexArray[j]; indexArray[j] = temphold;
		i = iMin;
		vTemp = inpArray[indexArray[j]][ColNo].toLowerCase()
		var loopvar;
		loopvar = 2;
		while (loopvar != 1) {
			loopvar++;
			i++; while (inpArray[indexArray[i]][ColNo].toLowerCase() < vTemp) { i++; }
			j--; while (inpArray[indexArray[j]][ColNo].toLowerCase() > vTemp) { j--; }
			if (j < i) break;
			temphold = indexArray[i]; indexArray[i] = indexArray[j]; indexArray[j] = temphold;
		}
		temphold = indexArray[i]; indexArray[i] = indexArray[iMax - 1]; indexArray[iMax - 1] = temphold;
		TriQuickSortMain2D(inpArray, indexArray, iSplit, iMin, j, ColNo);
		TriQuickSortMain2D(inpArray, indexArray, iSplit, i + 1, iMax, ColNo);
	}
}

function InsertionSort2D (inpArray, indexArray, iMin, iMax, ColNo) {
	for (var i = iMin; i < iMax + 1; i++) { ;
		vTemp = indexArray[i];
		j = i;
		while (j > iMin) {
			if (inpArray[indexArray[j - 1]][ColNo].toLowerCase() <= inpArray[vTemp][ColNo].toLowerCase()) { break; }
			indexArray[j] = indexArray[j - 1];
			j = j - 1;
		}
		indexArray[j] = vTemp;
	}
}

function ReverseIndex (indexArray) {
	var temphold;
	if (indexArray.length != 1) {
		for (var abc = 0; abc < Math.floor(indexArray.length / 2); abc++) {
			temphold = indexArray[abc];
			indexArray[abc] = indexArray[indexArray.length - abc - 1];
			indexArray[indexArray.length - abc - 1] = temphold;
		}
	}
}

function ApplyIndex2D (inpArray, indexArray) {
	var tmpArray = CreateArray(inpArray.length, inpArray[0].length);
	for (var abc = 0; abc < inpArray.length; abc++) {
		for (var def = 0; def < inpArray[0].length; def++) {
			tmpArray[abc][def] = inpArray[abc][def];
		}
	}	
	for (var abc = 0; abc < inpArray.length; abc++) {
		for (var def = 0; def < inpArray[0].length; def++) {
			inpArray[abc][def] = tmpArray[indexArray[abc]][def];
		}
	}	
}

function ApplySecondarySort2D (ssArray, PrimarySort, SecondarySort, SecondaryAscending) {
	simiarcount = 1; startval = 0; 
	for (var abc = 1; abc < ssArray.length; abc++) {
		if (ssArray[abc][PrimarySort] == ssArray[abc - 1][PrimarySort] && abc != ssArray.length - 1) {
			simiarcount++; 	
		} else {
			if ( (simiarcount != 1) && ( (abc != ssArray.length - 1) || (ssArray[abc][PrimarySort] == ssArray[abc - 1][PrimarySort]) ) )  {
				if (abc == ssArray.length - 1) simiarcount++;
				if (simiarcount != 1) {
					var tmpArray = CreateArray(simiarcount, ssArray[0].length);
					for (var def = startval; def < startval + simiarcount; def++) {
						for (var ghi = 0; ghi < ssArray[0].length; ghi++) {
							tmpArray[def - startval][ghi] = ssArray[def][ghi];
						}
					}
					tmpArray = TriQuickSort2D(tmpArray, SecondarySort, SecondaryAscending);
					for (var def = startval; def < startval + simiarcount; def++) {
						for (var ghi = 0; ghi < ssArray[0].length; ghi++) {
							 ssArray[def][ghi] = tmpArray[def - startval][ghi];
						}
					}
				}
			}
			simiarcount = 1; startval = abc;
		}
	}
	return ssArray;
}
