var IE = (document.all) ? true : false;
var agt = navigator.userAgent.toLowerCase();
var MAC = (agt.indexOf("mac") != -1) ? true : false;
//////////////////////////////////////////////////////////////
function CopyAll(source, target) {
	var count;
	
	count = source.length;
	
	for(var i = 0; i < count; i++) {
		CopyByIndex(source, target, i, false);
	}
	
	sortText(target);
}

function CopyByIndex(source, target, idx, sort) {
	var o;
	
	o = MakeOption(GetText(source, idx, false), GetValue(source, idx, false));
	Add(o, target, target.length);
	
	if (sort == true)
		sortText(target);
	
	return;
}

function Copy(source, target, sort) {
	var o;
	
	if (source.selectedIndex = -1)
		return;
		
	if (source.multiple) {
		var count;
		var idx = Array();
		
		count = source.length;
		
		for(var i = 0; i < count; i++) {
			if (source.options[i].selected)
				idx[idx.length] = i;
		}
		
		if (idx.length == 0)
			return;
		
		for(var i = 0; i < (idx.length - 1); i++) 	
			CopyByIndex(source, target, (idx[i] - i), false);
		
		CopyByIndex(source, target, ((idx[(idx.length - 1)]) - i), sort);
		
		return;
	}		
	
	CopyByIndex(source, target, source.selectedIndex, sort);
	
	return;
}
//////////////////////////////////////////////////////////////
function MoveAll(source, target) {
	var count; 
	
	count = source.length;

	for(var i = 0; i < count; i++) {
		source.selectedIndex = 0;
		Move(source, target, false);
	}
	
	sortText(target);
	
	return;
}

function Move(source, target, sort) {
	var o;
	
	if (source.selectedIndex == -1)
		return;
		
	if (source.multiple) {
		var count;
		var idx = Array();
		
		count = source.length;
		
		for(var i = 0; i < count; i++) {
			if (source.options[i].selected)
				idx[idx.length] = i;
		}
		
		if (idx.length == 0)
			return;
		
		for(var i = 0; i < (idx.length - 1); i++) 	
			MoveByIndex(source, target, (idx[i] - i), false);
		
		MoveByIndex(source, target, ((idx[(idx.length - 1)]) - i), sort);
		
		return;
	}
		
	MoveByIndex(source, target, source.selectedIndex, sort);
	
	return;
}

function MoveByIndex(source, target, idx, sort) {
	var o;
	
	o = Remove(source, idx);
	Add(o, target, target.length);
	
	if (sort == true)
		sortText(target);
	
	return;
}
//////////////////////////////////////////////////////////////
function Add(opt, list, idx) {
	if (IE && !MAC)
		AddIE(opt, list, idx);
	else
		AddNS(opt, list, idx);
	
	return;
}

function AddNS(opt, list, idx) {
	list.options[idx] = opt;
	
	return;
}

function AddIE(opt, list, idx) {
	list.add(opt);
	
	return;
}
//////////////////////////////////////////////////////////////
function RemoveAll(list) {
	var count;
	
	count = list.length;
	
	for(var i = 0; i < count; i++) {
		var o = Remove(list, 0);
	}
	
	return;
}

function Remove(list, idx) {
	if (IE && !MAC)
		return RemoveIE(list, idx);
	else
		return RemoveNS(list, idx);
}

function RemoveIE(list, idx) {							 
	var opt = document.createElement("OPTION");
	
	opt.text = list.options[idx].text;
	opt.value = list.options[idx].value;
	list.remove(idx);

	return opt;
}

function RemoveNS(list, idx) {
	var opt = new Option();
	
	opt.text = list.options[idx].text;
	opt.value = list.options[idx].value;
	list.options[idx] = null;
	
	return opt;
}
//////////////////////////////////////////////////////////////
function MakeOption(text, value) {
	if (IE && !MAC)
		return MakeOptionIE(text, value);
	else
		return MakeOptionNS(text, value);
}

function MakeOptionIE(text, value) {
	var opt = document.createElement("OPTION");
	
	opt.text = text;
	opt.value = value;
	
	return opt;
}

function MakeOptionNS(text, value) {
	var opt = new Option();
	
	opt.text = text;
	opt.value = value;
	
	return opt;
}
//////////////////////////////////////////////////////////////
function listValuesAsString(list, delim) {
	var sTemp;
	var lo;
	var hi;
	var a;
	
	sTemp = "";
	lo = 0;
	hi = list.length;
	
	for(a = lo; a < hi; a++)
		sTemp += list.options[a].value + delim;
	
	sTemp = sTemp.substring(0, (sTemp.length - delim.length))
	
	return sTemp;
}
//////////////////////////////////////////////////////////////
function sortText(list) {
	Sort(list, 'text');
}

function sortValue(list) {
	Sort(list, 'value');
}

function Sort(list, which) {
	var lo;
	var hi;
	
	lo = 0;
	hi = (list.length - 1);
	
	insertionSort(list, which, lo, hi);
	//quickSort(list, which, lo, hi);
	//bubbleSort(list, which, lo, hi);
}
//////////////////////////////////////////////////////////////
function Get(list, which, idx, ucase) {
	if (which == 'text') 
		return GetText(list, idx, ucase);
	else
		return GetValue(list, idx, ucase);
}

function GetText(list, idx, ucase) {
	if (ucase == true)
		return list.options[idx].text.toUpperCase();
	else
		return list.options[idx].text;
}

function GetValue(list, idx, ucase) {
	if (ucase == true)
		return list.options[idx].value.toUpperCase();
	else
		return list.options[idx].value;
}
//////////////////////////////////////////////////////////////
function SetOption(list, idx, t, v) {
	list.options[idx].text = t;
	list.options[idx].value = v;
	
	return;
}

function SetOption(list, idx, o) {
	list.options[idx].text = o.text;
	list.options[idx].value = o.value;
}

function GetOption(list, idx) {
	return MakeOption(list.options[idx].text, list.options[idx].value);
}
//////////////////////////////////////////////////////////////
function findValue(list, value) {
	return binarySearch(list, value, 'value', 0, (list.length - 1));
}

function findText(list, text) {
	return binarySearch(list, text, 'text', 0, (list.length - 1));
}

function binarySearch(list, search, which, start, end) {
	var results;
	
	if (start > end)
		return null;
		
	if (start == end) {
		if (compare(list, start, which, search) == 0)
			return start
		else
			return null;
	}
	
	var mid = Math.round(((start + end)/2));
	
	results = compare(list, mid, which, search);
	
	switch (results) {
		case 0:
			return mid;
		break;
		case -1:
			return binarySearch(list, search, which, start, (mid - 1));
		break;
		case 1:
			return binarySearch(list, search, which, (mid + 1), end);
		break;
	}
}

function compare(list, idx, which, search) {
	var target;
	
	if (which == 'text')
		target = list.options[idx].text;
	else
		target = list.options[idx].value;
		
	if (target == search)
		return 0;
	
	if (search > target)
		return 1;
		
	if (search < target)
		return -1;
		
}
//////////////////////////////////////////////////////////////
function bubbleSort(list, which, loBound, hiBound) {
	var a;
	var b;
	
	for(a = hiBound - 1; a >= loBound; a--)
		for(b = loBound; b <= a; b++)
			if (Get(list, which, (b + 1), false) < Get(list, which, b, false))
				Swap(list.options[b], list.options[(b + 1)]);
				
	return;
}

function quickSort(list, which, loBound, hiBound) {
	var hiSwap;
	var loSwap;
	var pivot;
	
	if (loBound < hiBound) {
		pivot = Get(list, which, loBound, false);
		loSwap = loBound - 1;		
		hiSwap = hiBound + 1;
		
		while (1) {
			while(Get(list, which, --hiSwap, false) > pivot);
			while(Get(list, which, ++loSwap, false) < pivot);
			
			if (loSwap < hiSwap)
				Swap(list.options[loSwap], list.options[hiSwap]);
			else
				break;
		}
		
		quickSort(list, which, loBound, hiSwap);
		quickSort(list, which, (hiSwap + 1), hiBound);
	}
}

function insertionSort(list, which, loBound, hiBound) {
	var j, i;
	var comp, item;
	
	for(j = loBound; j <= hiBound; j++) {
		comp = Get(list, which, j, false);
		item = GetOption(list, j);
		
		i = j - 1
		while(i >= 0 && Get(list, which, i, false) > comp) {
			SetOption(list, (i + 1), GetOption(list, i));
			i--;
		}
		SetOption(list, (i + 1), item);
	}
}

function Swap(opt1, opt2) {
	var temp1;
	var temp2;
	
	temp1 = opt1.text;
	temp2 = opt1.value;
	
	opt1.text = opt2.text;
	opt1.value = opt2.value;
	
	opt2.text = temp1;
	opt2.value = temp2;
	
	return;
}
