// 定数定義
var PARENT_TAG_NAME = 'THEAD';
var GENRE_ROW_INDEX = 1;

function sortTable ( section, index, cmpfn, getfn ) {
 	var x = new Array();
	var rows = section.rows;
	var N = rows.length;
 	var marker = document.createElement('tbody');
	for (var i = 0; i < N; i++) {
		x[i] = Object( getfn( rows[i].cells[index] ) );
		x[i].row = rows[i];
	}
	
	x.sort(cmpfn);
	
	section.parentNode.replaceChild( marker, section );
	for (var i = 0; i < N; i++ ) {
		section.appendChild(x[i].row);
	}
	
	marker.parentNode.replaceChild( section, marker );
}

function categorySort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// カテゴリで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? -1 : 1;
		}
	}
	var getFunc = function(cell) {
		// category
		cell.innerHTML.match(/\[([^\]]+)\]/);
		var val1 = "" + RegExp.$1;
		if (val1 == "ee1") {
			val1 = 101;
	    } else if (val1 == "ee2") {
			val1 = 102;
	    } else if (val1 == "版権") {
			val1 = 100;
	    } else if (val1 == "CS") {
			val1 = 99;
	    } else {
			val1 = Number(val1);
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function categoryRSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// カテゴリで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? 1 : -1;
		}
	}
	var getFunc = function(cell) {
		// category
		cell.innerHTML.match(/\[([^\]]+)\]/);
		var val1 = "" + RegExp.$1;
		if (val1 == "ee1") {
			val1 = 101;
	    } else if (val1 == "ee2") {
			val1 = 102;
	    } else if (val1 == "版権") {
			val1 = 100;
	    } else if (val1 == "CS") {
			val1 = 99;
	    } else {
			val1 = Number(val1);
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function genreSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		var val = strcmp(a, b);
		return val < 0? -1 : 1;
	}
	var getFunc = function(cell) {
	  	cell.firstChild.innerHTML.match(/>(.+?)<.a>/);
		return RegExp.$1;
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function genreRSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		var val = strcmp(a, b);
		return val < 0? 1 : -1;
	}
	var getFunc = function(cell) {
		cell.firstChild.innerHTML.match(/>(.+?)<.a>/);
		return RegExp.$1;
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function bpmSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// bpmで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? -1 : 1;
		}
	}
	var getFunc = function(cell) {
		// bpm
		var val1 = "" + cell.firstChild.nodeValue.match(/^[0-9]+/);
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function bpmRSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// bpmで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? 1 : -1;
		}
	}
	var getFunc = function(cell) {
		// bpm
		cell.firstChild.nodeValue.match(/([0-9]+)\??$/);
		var val1 = "" + RegExp.$1;
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}

function notesSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// Notesで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? -1 : 1;
		}
	}
	var getFunc = function(cell) {
		// Notes
		var val1;
		if (cell.innerHTML == "" || cell.innerHTML == undefined) {
			val1 = 0
		} else {
			cell.innerHTML.match(/([0-9]+)$/);
			val1 = Number(RegExp.$1);
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);

		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function notesRSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// Notesで決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? 1 : -1;
		}
	}
	var getFunc = function(cell) {
		// Notes
		var val1;
		if (cell.innerHTML == "" || cell.innerHTML == undefined) {
			val1 = 0
		} else {
			cell.innerHTML.match(/([0-9]+)$/);
			val1 = Number(RegExp.$1);
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);

		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}

function difficultSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// 難易度で決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? -1 : 1;
		}
	}
	var getFunc = function(cell) {
		// difficult
		var val1;
		if (cell.firstChild != null) {
			val1 = cell.firstChild.nodeValue.match(/[-+][0-9]\.?[0-9]*/) - 0;
		} else {
			val1 = -999; // 適当に最低値
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}
function difficultRSort(sender, rowIndex) {
	var thead = getParentElementByTagName(sender, PARENT_TAG_NAME);
	var tbody = thead.nextSibling.nextSibling;
	var compareFunc = function(a, b) {
		// 難易度で決まらないならgenreソート
		if (Number(a[0]) == Number(b[0])) {
			return strcmp(a[1], b[1]) < 0? -1 : 1;
		} else {
			return (Number(a[0]) < Number(b[0]))? 1 : -1;
		}
	}
	var getFunc = function(cell) {
		// difficult
		var val1;
		if (cell.firstChild != null) {
			val1 = cell.firstChild.nodeValue.match(/[-+][0-9]\.?[0-9]*/) - 0;
		} else {
			val1 = -999; // 適当に最低値
		}
		// genre
		var val2 = "" + cell.parentNode.cells[GENRE_ROW_INDEX].firstChild.innerHTML.match(/>(.+?)<.a>/);
		return [val1, val2];
	}
	sortTable(tbody, rowIndex, compareFunc, getFunc);
}

// 指定した要素の親要素をタグ名より取得する
function getParentElementByTagName(sender, tagName) {
    var parent = sender.parentNode;
    tagName = tagName.toUpperCase();

    // 親要素にタグ名と同一のものがあれば其の時点で終了して要素を返す
    while(true) {
        if (parent.tagName.toUpperCase() == tagName) {
            break;
        }
        parent = parent.parentNode;

        // 永久ループするのは怖いので適当にガード
        if (parent == null || parent == 'undefined' || parent.tagName == 'undefined') break;
    }

    return parent;
}
// 指定した要素以降の要素より、タグ名と一致するものを取得する
function getParentElementByNextSibiling(sender, tagName) {
    var element = sender.nextSibling;
    tagName = tagName.toUpperCase();
    
    while (element != null && element != 'undefined') {
        if (element.tagName.toUpperCase() == tagName) {
            break;
        }
        
        element = sender.nextSibling;
    }

    return element;
}

// 文字列比較関数
function strcmp(str1, str2)
{
    var ct;
    var cmp;
/*
    if((cmp = str1.length - str2.length) != 0){
        return cmp;
    }
*/
    for(ct = 0; ct < str1.length; ct++) {
        var c1 = str1.charCodeAt(ct);
        var c2 = str2.charCodeAt(ct);
        if((cmp = (c1 - c2)) != 0){
            break;
        }
    }
    return cmp;
}
