// --- Multi sort ---

function MultiSortClass(opt)
{
var root  = this;
this.opt  = {};
this.opt.cmp = {};
this.opt.source = [];
this.diakritika = [
"徜栾殪礤掘篝鲟殱鵀聊认商团家釉掷妽谫茌貛",
"aacdeeillnooorstuuuyrzAACDEEILLNOOORSTUUUYRZ"
];

this.func = {};

this.func.cmpStrAsc = function (a,b)
	{
	a = a.toLowerCase();
	b = b.toLowerCase();
	return a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpStrDesc = function (b,a)
	{
	a = a.toLowerCase();
	b = b.toLowerCase();
	return a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpStrlenAsc = function (a,b)
	{
	a = a.toLowerCase();
	b = b.toLowerCase();
	return a.length>b.length || a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpStrlenDesc = function (b,a)
	{
	a = a.toLowerCase();
	b = b.toLowerCase();
	return a.length>b.length || a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpNumAsc = function (a,b)
	{
	return a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpNumDesc = function (b,a)
	{
	return a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpStrnumAsc = function (a,b)
	{
	var a0,b0,a1,b1,cmp0,cmp1;
	a0 = a.replace(/[^a-z]/gi,'');	// str
	b0 = b.replace(/[^a-z]/gi,'');	// str
	a1 = a.replace(/[^0-9]/gi,'');	// num
	b1 = b.replace(/[^0-9]/gi,'');	// num
	cmp0 = root.func.cmpStrAsc(a0,b0);
	cmp1 = root.func.cmpStrAsc(a1,b1);
	return cmp0==0 ? cmp1 : cmp0;
	}
this.func.cmpStrnumDesc = function (b,a)
	{
	return root.func.cmpStrnumAsc(a,b);
	}
this.func.cmpStrzasuvkaAsc = function (a,b)	// num, 'Fa'+num+'/'+num, 'Gi'+num+'/'+num, 'g'+'+num+'/'+num
	{
	var a0,b0,a1,b1,a2,b2,cmp;
	a0 = a.replace(/^[0-9]+$|[0-9]+.*$/i,"");	// str0
	b0 = b.replace(/^[0-9]+$|[0-9]+.*$/i,"");	// str0
	a1 = a.replace(/^[^0-9]+|[\/].*$/gi,"");	// num1
	b1 = b.replace(/^[^0-9]+|[\/].*$/gi,"");	// num1
	a2 = a.replace(/.*?[\/]|^[0-9]+$/gi,"");	// num2
	b2 = b.replace(/.*?[\/]|^[0-9]+$/gi,"");	// num2
	cmp = root.func.cmpStrAsc(a0.toLowerCase(),b0.toLowerCase());
	if (cmp!=0)
		{
		return cmp;
		}
	cmp = root.func.cmpNumAsc(a1*1,b1*1)
	if (cmp!=0)
		{
		return cmp;
		}
	cmp = root.func.cmpNumAsc(a2*1,b2*1);
	return cmp;
	}
this.func.cmpStrzasuvkaDesc = function (b,a)
	{
	return root.func.cmpStrnumAsc(a,b);
	}
this.func.cmpStrdiakritikaAsc = function (a,b)
	{
	a = root.func.diakritika(a).toLowerCase();
	b = root.func.diakritika(b).toLowerCase();
	return a>b ? 1 : (a==b ? 0 : -1);
	}
this.func.cmpStrdiakritikaDesc = function (b,a)
	{
	return root.func.cmpStrdiakritikaAsc(a,b);
	}

this.cmp = function (a,b)
	{
	var out, i;
	out = 0;
	for (i in root.opt.cmp)
		{
		out = root.opt.cmp[i](a[i],b[i]);
		if (out!=0)
			{
			return out;
			}
		}
	return out;
	}

this.func.diakritika = function (str)
{
var i, i_end, j, out, chr;
out = '';
i_end = str.length;
for(i = 0; i < i_end; i++)
	{
	chr = str.charAt(i);
	j   = root.diakritika[0].indexOf(chr);
	if (j!==-1)
		{
		out += root.diakritika[1].charAt(j);
		continue;
		}
	out += chr;
	}
return out;
}

this.func.cbUpper = function(match,content0,content1)
	{
	return content0.toUpperCase() + content1.toLowerCase();
	}

this.func.setOpt = function (opt)
	{
	var row, i, i_end, func;
	root.opt = {};
	root.opt.cmp = {};
	root.opt.source = [];
	if (!(isExist(opt) && isArray(opt)))
		{
		return;
		}
	i_end = opt.length;
	for (i=0;i<i_end;i++)	// convert {col:2,cmp:'num',order:'asc'} => root.func.cmpNumAsc
		{
		if (!isObject(opt[i]))
			{
			continue;
			}
//alert('a'+i)
		row = opt[i];
		row.cmp   = isExist(row.cmp)   ? row.cmp.replace(/^([a-z])([a-z]+)$/i,root.func.cbUpper) : 'str';
		row.order = isExist(row.order) ? row.order.replace(/^([a-z])([a-z]+)$/i,root.func.cbUpper) : 'asc';
		func      = 'cmp' + row.cmp + row.order;
//alert(func)
		if (isFunction(root.func[func]))
			{
			root.opt.cmp[row.col] = root.func[func];
			root.opt.source[root.opt.source.length] = row;
			}
		}
	}
this.func.setOpt(opt);
}
/*
var arr = [
['a', 1, 11],
['a', 0, 10],
['a', 1, 9],
['a', 0, 8],
]
var x;
x = new MultiSortClass([
		{col:1,cmp:'num',order:'asc'},
		{col:2,cmp:'num',order:'asc'}
		]);
arr.sort(x.cmp)
str = '';
for (i=0;i<arr.length;i++)
	{
	str += arr[i].join(', ') + ' \n '
	}
alert(str)
*/
