//-------------- Helper functions --------------
var VALUE_SPACER = ",", NAME_SPACER = "|";
function nWrap(str){
	if(str == null) { return ""; }
	return NAME_SPACER + str + NAME_SPACER;
}
function vWrap(str){
	if(str == null) { return ""; }
	return VALUE_SPACER + str + VALUE_SPACER;
}

//-------------- SelectObject --------------
function SelectObject(formElement){
	this.element = formElement;
	this.get = getSO;
	addAdvancedProperties(this);
}
function addAdvancedProperties(obj){
	obj.getAll = getAllSO;
	obj.getNames = getNamesSO;
	obj.selectNone = selectNoneSO;
	obj.insert = insertSO;
	obj.remove = removeSO;
	obj.removeDuplicates = removeDuplicatesSO;
	obj.filterOut = filterOutSO;
	obj.sort = sortSO;
}
function getSelectObject(formName, selectName){
	return new SelectObject(document.forms[formName].elements[selectName]);
}
function getSO(which){
	if(which != null){
		for(var i = 0; i < this.element.length; i++)
			if(this.element.options[i].value == which)
				return this.element.options[i].selected ? which : "";
		return "";
	}
	var returnVal = "";
	for(var i = 0; i < this.element.length; i++)
		if(this.element.options[i].selected)
			returnVal += VALUE_SPACER + this.element.options[i].value;
	return returnVal.substring(1);
}
function getAllSO(){
	var returnVal = "";
	for(var i = 0; i < this.element.length; i++)
		returnVal += VALUE_SPACER + this.element.options[i].value;
	return returnVal.substring(1);
}
function getNamesSO(values){
	var returnVal = "";
	if(values == null) values = this.get();
	values = vWrap(values);
	var value, endPos = 0, startPos, lastChar = values.length - 1;
	while(endPos < lastChar){
		startPos = endPos + 1;
		endPos = values.indexOf(VALUE_SPACER, startPos);
		value = values.substring(startPos, endPos);
		for(var i = 0; i < this.element.length; i++){
			if(this.element.options[i].value == value){
				returnVal += NAME_SPACER + this.element.options[i].text;
				break;
			}
		}
	}
	return returnVal.substring(1);
}
function selectNoneSO() {
	for(var i = 0; i < this.element.length; i++)
		this.element.options[i].selected = false;
}
function insertSO(names, values, allowDuplicates){
	if(names == "" || names == null) { return; }
	var nameStart = 1, valueStart = 1, nameEnd, valueEnd, allValues = "", value;
	allowDuplicates = (allowDuplicates == true); // force boolean
	if(!allowDuplicates) {
		allValues = vWrap(this.getAll());
	}
	values = vWrap(values);
	names = nWrap(names);
	while(nameStart < names.length && valueStart < values.length){
		nameEnd = names.indexOf(NAME_SPACER, nameStart);
		valueEnd = values.indexOf(VALUE_SPACER, valueStart);
		value = values.substring(valueStart, valueEnd);
		if(allowDuplicates || allValues.indexOf(vWrap(value)) == -1){
			this.element.options[this.element.options.length] = new Option(names.substring(nameStart, nameEnd), value, false, false);
			if(!allowDuplicates) {
				allValues += value + VALUE_SPACER;
			}
		}
		nameStart = nameEnd + 1;
		valueStart = valueEnd + 1;
	}	
}
function removeSO(values){
	values = vWrap(values);
	for(var i = 0; i < this.element.length; i++)
		if(values.indexOf(vWrap(this.element.options[i].value)) != -1){
			this.element.options[i] = null;
			i--;
		}
}
function removeDuplicatesSO() {
	var SO = getSelectObject(this.element.form.name, this.element.name);
	var tempValues = SO.getAll();
	var tempNames = SO.getNames(tempValues);
	SO.remove(tempValues);
	SO.insert(tempNames, tempValues, false); // allowDuplicates = false
}
function filterOutSO(toFilter) {
	var selValues = toFilter.getAll();
//	alert(this.element.name+" toFilter out "+toFilter.element.name+": "+selValues);
	this.remove(selValues);
	this.removeDuplicates();
	toFilter.removeDuplicates();
}
function sortSO(){
	var e = this.element, len = e.length;
	if(len <= 1) { return; }
	var options = new Array();
	for(i = 0; i < len; i++){
		options[i] = new NameVal(e.options[i].text, e.options[i].value);
	}
	sortUtil(e, options);
}
function sortUtil(e, options){
	var temp, curLen = e.length, len = options.length, temp;

	for(i = 1; i < len; i++) {
		for(j = i; j > 0; j--) {
			if(options[j].name < options[j - 1].name){
				temp = options[j];
				options[j] = options[j - 1];
				options[j - 1] = temp;
			}
		}
	}
	values = "";
	for(i = 0; i < curLen; i++){
		e.options[i].text = options[i].name;
		e.options[i].value = options[i].value;
	}
	for( ; i < len; i++){
		e.options[i] = new Option(options[i].name, options[i].value, false, false);
	}
}
function NameVal(name, value){
	this.name = name;
	this.value = value;
}
