﻿addEvent(window, "load", findSortableTables);

var sortedColumn = 0;
var lastSortedColumn = 1;

function findSortableTables()
{
    var tables = document.getElementsByTagName("table");
    
    for(var i = 0; i < tables.length; i++)
    {
        if(tables[i].className.indexOf("sortable") >= 0)
        {
            prepareSortableTable(tables[i]);
        }
    }
}

function prepareSortableTable(table)
{
    var cols = table.getElementsByTagName("col");
    for(var i = 0; i < cols.length; i++)
    {
        if(cols[i].className.indexOf("sorted") >= 0)
        {
            sortedColumn = i;
            lastSortedColumn = (i == 0) ? 1 : i - 1;
            break;
        }
    }

    var ths = table.getElementsByTagName("th");
    
    for(var i = 0; i < ths.length; i++)
    {
		if(cols[i] && cols[i].className.indexOf("sortable") >= 0)
		{
        	ths[i].className = "sortable";
	        addEvent(ths[i], "click", sortColumn);
			addEvent(ths[i], "mouseover", function() {this.style.cursor = "pointer";});
		}
    }
}

function sortColumn()
{
    var table = this.parentNode;
    while(table.nodeName.toLowerCase() != "table")
        table = table.parentNode;
        
    var cols = table.getElementsByTagName("col");

    if(this.className.indexOf("sorted_ascending") >= 0)
        this.className = this.className.replace("sorted_ascending", "sorted_descending");
    else if(this.className.indexOf("sorted_descending") >= 0)
        this.className = this.className.replace("sorted_descending", "sorted_ascending");
    else
    {
        var ths = this.parentNode.getElementsByTagName("th");
        for(var i = 0; i < ths.length; i++)
        {
            if(this == ths[i])
            {
                if(i >= cols.length)
                    return;
                
                lastSortedColumn = (sortedColumn != i) ? sortedColumn : lastSortedColumn;
                sortedColumn = i;
            }
        }
                    
        for(var i = 0; i < ths.length; i++)
        {
            ths[i].className = ths[i].className.replace("sorted_ascending", "").replace("sorted_descending", "");
        }
        
        this.className += " sorted_ascending";
    }
    
    for(var i = 0; i < cols.length; i++)
    {
        cols[i].className = cols[i].className.replace("sorted", "");
    }
    
    cols[sortedColumn].className += " sorted";
    
    var tbody = table.getElementsByTagName("tbody")[0];
    var trs = tbody.getElementsByTagName("tr");
    var data = [];
    
    for(var i = trs.length - 1; i >= 0; i--)
    {
        data.push(trs[i]);
        tbody.removeChild(trs[i]);
    }
    
    data.sort(sortData);
    
    if(this.className.indexOf("sorted_descending") >= 0)
        data.reverse();
    
    for(var i = 0; i < data.length; i++)
    {
		var tds = data[i].getElementsByTagName("td");
		for(var j = 0; j < tds.length; j++)
		{
			tds[j].className = tds[j].className.replace("sorted", "");
		}
		
		tds[sortedColumn].className += " sorted";
		data[i].className = data[i].className.replace("oneven", "").replace("even", "");
		if(i % 2 == 0)
			data[i].className += " oneven"
		else
			data[i].className += " even";

        tbody.appendChild(data[i]);
    }
}

function sortData(a, b)
{
    if(!a.getElementsByTagName("td")[sortedColumn].hasChildNodes() && !b.getElementsByTagName("td")[sortedColumn].hasChildNodes())
        return 0;
    else if(!a.getElementsByTagName("td")[sortedColumn].hasChildNodes() && b.getElementsByTagName("td")[sortedColumn].hasChildNodes())
        return -1;
    else if(a.getElementsByTagName("td")[sortedColumn].hasChildNodes() && !b.getElementsByTagName("td")[sortedColumn].hasChildNodes())
        return 1;

    var aa = a.getElementsByTagName("td")[sortedColumn].firstChild.nodeValue.toLowerCase();
    var bb = b.getElementsByTagName("td")[sortedColumn].firstChild.nodeValue.toLowerCase();
    
    aa = tryParse(aa);
    bb = tryParse(bb);
    
    if(aa == bb)
    {
        if(!a.getElementsByTagName("td")[lastSortedColumn].hasChildNodes() && !b.getElementsByTagName("td")[lastSortedColumn].hasChildNodes())
            return 0;
        else if(!a.getElementsByTagName("td")[lastSortedColumn].hasChildNodes() && b.getElementsByTagName("td")[lastSortedColumn].hasChildNodes())
            return -1;
        else if(a.getElementsByTagName("td")[lastSortedColumn].hasChildNodes() && !b.getElementsByTagName("td")[lastSortedColumn].hasChildNodes())
            return 1;
    
        aa = a.getElementsByTagName("td")[lastSortedColumn].firstChild.nodeValue;
        bb = b.getElementsByTagName("td")[lastSortedColumn].firstChild.nodeValue;
        
        aa = tryParse(aa);
        bb = tryParse(bb);
        
        return (aa == bb) ? 0 : (aa < bb) ? -1 : 1;
    }
    
    return (aa < bb) ? -1 : 1;
}

function tryParse(val)
{
	if(val == null)
		return val;

    //try parsing time
    if(val.match(/[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/))
    {
        var segments = val.split(":");
        var hour = segments[0];
        var min = segments[1];
        var sec = segments[2];
        
        var date = new Date();
        date.setHours(hour);
        date.setMinutes(min);
        date.setSeconds(sec);
        
        return date;
    }
    
    //try parsing to integer
    return (isNaN(parseInt(val))) ? val : parseInt(val);
}