var _SELECT_TOOLS_ = true;
var _ERROR_REPORTER_;
var VALUE_SPACER = ",", NAME_SPACER = "|";


function SelectObject(formElement){
this.element=formElement;
this.get=getSO;
this.set=setSO;
this.numSelected=numSelectedSO;
addAdvancedProperties(this);
}
function addAdvancedProperties(obj){
obj.numOptions=numOptionsSO;
obj.hasValue=hasValueSO;
obj.getAll=getAllSO;
obj.getNames=getNamesSO;
obj.setDefault=setDefaultSO;
obj.selectAll=selectAllSO;
obj.insert=insertSO;
obj.remove=removeSO;
obj.replace=replaceSO;
obj.sortedInsert=sortedInsertSO;
obj.sort=sortSO;
obj.reverse=reverseSO;
obj.swap=swapSO;
obj.rename=renameSO;
obj.moveSelected=moveSelectedSO;

obj.addPriv=addPSO;
obj.insertPriv=insertPSO;
obj.sortPriv=sortPSO;
obj.buildPriv=buildPSO;
obj.findPriv=findPSO;
obj.removePriv=removePSO;
obj.resetPriv=resetPSO;
obj.swapPriv=swapPSO;
obj.setRangePriv=setRangePSO;
}
function numOptionsSO(){
return this.element.length;
}
function numSelectedSO(){
return this.buildPriv();
}
function getSO(which){
if(which!=null){
this.buildPriv();
var i=this.findPriv(which);
return i==-1?"":(this.options[i].selected?which:"")
}
var returnVal=new Array();
for(var i=0; i<this.element.length; i++)
if(this.element.options[i].selected)
returnVal[this.element.options[i].value]=true;
return setToString(returnVal,VALUE_SPACER);
}
function hasValueSO(value){
this.buildPriv();
return this.findPriv(value)!=-1;
}
function getAllSO(){
var returnVal=new Array();
for(var i=0; i<this.element.length; i++)
returnVal[this.element.options[i].value]=true;
return setToString(returnVal,VALUE_SPACER);
}
function getNamesSO(values){
var i, value, returnVal=new Array();
values=stringToSet(values!=null ? values : this.get(),VALUE_SPACER);
this.buildPriv();
for(value in values){
var i=this.findPriv(value);
if(i!=-1) returnVal[this.options[i].text]=true;
}
return setToString(returnVal,NAME_SPACER);
}
function setSO(values,which){
if(which!=null){
this.buildPriv();
var i=this.findPriv(which);
if(i!=-1) this.element.options[i].selected = (values>"")
return;
}
values=stringToSet(values,VALUE_SPACER);
for(var i=0; i<this.element.length; i++)
this.element.options[i].selected = values[this.element.options[i].value]==true;
}
function setDefaultSO(values){
values=stringToSet(values, VALUE_SPACER);
for(var i=0; i<this.element.length; i++)
this.element.options[i].defaultSelected = values[this.element.options[i].value]==true;
}
function selectAllSO(){
for(var i=0; i<this.element.length; i++)
this.element.options[i].selected=true;
}
function insertSO(names,values,allowDuplicates){

this.buildPriv();
this.insertPriv(names,values,allowDuplicates,false);
this.resetPriv();
}
function removeSO(values){
values=stringToSet(values,VALUE_SPACER);
for(var i=0; i<this.element.length; i++)
if(values[this.element.options[i].value]){
this.element.options[i]=null;
i--;
this.options=null;
}
}
function replaceSO(curValues,names,values){
if(curValues==null) curValues=this.getAll();
this.buildPriv();
curValues=stringToSet(curValues,VALUE_SPACER);
values=stringsToMap(values,names,VALUE_SPACER,NAME_SPACER);
var curValue,i=0,j=0,vals=new Array(),indxs=new Array();
for(curValue in curValues) indxs[i++]=this.findPriv(curValue);
for(curValue in values) vals[j++]=curValue;
j=0;
for(i=0; i<indxs.length && j<vals.length; i++)
if(indxs[i]!=-1){
this.options[indxs[i]].value=vals[j];
this.options[indxs[i]].setName(values[vals[j++]]);
this.setRangePriv(indxs[i]);
}
while(i<indxs.length){
for(var k=i+1; k<indxs.length; k++)
if(indxs[k]>indxs[i]) indxs[k]--;
this.removePriv(indxs[i++]);
}
while(j<vals.length) this.addPriv(values[vals[j]],vals[j++],false);
this.resetPriv();
}
function reverseSO(){
this.buildPriv();
var i, stop=this.oLen/2, max=this.oLen-1;
for(i=0; i<stop; i++)
this.swapPriv(i, max-i);
this.resetPriv();
}
function sortSO(){
this.buildPriv();
this.sortPriv();
this.resetPriv();
}
function sortedInsertSO(names,values){
this.buildPriv();
if(this.getAll()=="") this.oLen=0;
for(var i=0; i<this.oLen; i++){
if(this.options[i].selected) this.setRangePriv(i);
this.options[i].selected=false;
}
this.insertPriv(names,values,false,true);
this.sortPriv();
this.resetPriv();
}
function swapSO(a, b){
this.swapPriv(a, b);
this.resetPriv();
}
function renameSO(value, name){
this.buildPriv();
var i=this.findPriv(value);
if(i!=-1){
this.options[i].setName(name);
this.setRangePriv(i);
this.resetPriv()
}
}
function moveSelected(name, amount){
var e=getElementObj(name);
if(e==null) return;
if(amount=="top") amount=-e.numOptions();
if(amount=="bottom") amount=e.numOptions();
e.moveSelected(amount);
}
function moveSelectedSO(amount){
if(amount==0 || this.buildPriv()==0) return;

var inc,start,stop,i,j,o=this.options;
if(amount<0){
inc=1; start=1; stop=this.oLen; amount=-amount;
}else{
inc=-1; start=this.oLen-2; stop=-1;
}
for(j=0; j<amount; j++)
for(i=start; i!=stop; i+=inc)
if(o[i].selected && !o[i-inc].selected)
this.swapPriv(i, i-inc);

this.resetPriv();
}

function insertPSO(names,values,allowDuplicates,selected){
var value, allValues=allowDuplicates ? new Array() : stringToSet(this.getAll(),VALUE_SPACER);
values=stringsToMap(values,names,VALUE_SPACER,NAME_SPACER);
for(value in values){
if(allValues[value]!=true)
this.addPriv(values[value],value,selected);
allValues[value]=true;
}
}
function sortPSO(){
quickSort(this,0,this.oLen);
}
function bubbleSort(e,lo,hi){
var o=e.options, i, j;
for(i=lo+1; i<hi; i++)
for(j=i; j>lo; j--)
if(o[j].sortName < o[j-1].sortName)
e.swapPriv(j, j-1);
}
function partition(e,lo,hi){
var o=e.options;
hi--;
e.swapPriv(lo,(lo+hi)>>1);
while(true){
while(lo<hi && o[lo].sortName<o[hi].sortName) hi--;
if (lo>=hi) return lo;
e.swapPriv(lo++,hi);

while(lo<hi && o[lo].sortName<o[hi].sortName) lo++;
if(lo>=hi) return hi;
e.swapPriv(lo,hi--);
}
}
function quickSort(e,lo,hi){
if (hi-lo<=10){
bubbleSort(e,lo,hi);
return;
}
var m=partition(e,lo,hi);
quickSort(e,lo,m);
quickSort(e,m+1,hi);
}
function NameVal(name,value,selected){
this.value=value;
this.selected=selected;
this.setName=setNameNV;
this.setName(name);
}
function setNameNV(str){
var c, out="", onLtr=false;
this.text=str;
if(this.value==""){this.sortName=" ";return;}
str=str.toLowerCase();
for(var i=0; i<str.length; i++){
c=str.charAt(i);
if(c>="a" && c<="z" || c>="0" && c<="9"){
out+=c;
onLtr=true;
}else if(onLtr){
out+=' ';
onLtr=false;
}
}
this.sortName=out=='other'?"~":out;
}
function buildPSO(){
var e=this.element, num=0, i, create=false;
if(this.options==null || this.hiOption!=null || this.oLen!=e.length){
this.options = new Array();
this.hiOption = null;
create = true;
this.oLen=e.length;
}
var o = this.options;
for(i = 0; i < this.oLen; i++){
if(create)
o[i] = new NameVal(e.options[i].text, e.options[i].value, e.options[i].selected);
else
o[i].selected = e.options[i].selected;
if(o[i].selected) num++;
}
return num;
}
function resetPSO(){
var e = this.element; curLen = e.length, o = this.options;
for(i = this.loOption; i < curLen && i <= this.hiOption; i++){
e.options[i].text = o[i].text;
e.options[i].value = o[i].value;
e.options[i].selected = o[i].selected;
}
for( ; i < this.oLen && i <= this.hiOption; i++){
e.options[i] = new Option(o[i].text, o[i].value, false, o[i].selected);
}
while(e.options.length > this.oLen)
e.options[e.options.length-1]=null;
this.hiOption = null;
}
function swapPSO(a, b){
if(this.options == null) this.buildPriv();
var o = this.options;
if(a >= this.oLen || a < 0 || b >= this.oLen || b < 0) return;
var temp = o[a]; o[a] = o[b]; o[b] = temp;
this.setRangePriv(a); this.setRangePriv(b);
}
function addPSO(n,v,s){
this.options[this.oLen++] = new NameVal(n, v, s);
this.setRangePriv(this.oLen-1);
}
function findPSO(value){
for(var i=0; i<this.oLen; i++)
if(this.options[i].value==value)
return i;
return -1
}
function removePSO(index){
this.oLen--
for(var i=index; i<this.oLen; i++){
this.setRangePriv(i);
this.options[i]=this.options[i+1];
}
}
function setRangePSO(val){
if(this.hiOption == null){
this.hiOption = val;
this.loOption = val;
}else{
if(this.hiOption < val) this.hiOption = val;
if(this.loOption > val) this.loOption = val;
}
}




function SelectSwitcher(formName,selectName0,selectName1,defaultText){
this.selects=new Array(2);
this.selects[0]=getSelectObject(formName,selectName0);
this.selects[1]=getSelectObject(formName,selectName1);

this.defaultText=defaultText;
this.move=moveSS;
this.insert=insertSS;
this.remove=removeSS;
this.selectAll=selectAllSS;
this.autoSort=true;
}
function moveSS(from,values){
if(values==null) values=this.selects[from].get();
if(values=="") return;
var to=1-from;
this.insert(to,this.selects[from].getNames(values),values);
this.selects[to].set(values);
this.remove(from,values)
return void(null);
}
function insertSS(to,names,values){
var nameCount=countTokens(names,NAME_SPACER);
var valueCount=countTokens(values,VALUE_SPACER);
if(nameCount!=valueCount || valueCount==0) return;

if(this.autoSort == true || this.autoSort == to)
this.selects[to].sortedInsert(names,values);
else
this.selects[to].insert(names,values);
if(this.defaultText) this.selects[to].remove("");
if(debug) window.status=this.selects[0].getAll()+"~|~"+this.selects[1].getAll();
}
function removeSS(from,values){
var valueCount=countTokens(values,VALUE_SPACER);
if(valueCount==0) return;
if(this.defaultText&&this.selects[from].numOptions()==valueCount)
this.selects[from].insert(this.defaultText,"");
this.selects[from].remove(values);
}
function selectAllSS(which){
this.selects[which].selectAll();
}

function countTokens(str,separator){
return objSize(stringToSet(str,separator));
}
function getSelectObject(formName,selectName){
if(_ERROR_REPORTER_==true && getFormObj(formName)!=null)
return getFormObj(formName).getElement(selectName);
return new SelectObject(document.forms[formName].elements[selectName]);
}
function setToString(set,separator){
var i, out=null;
for(i in set){
if (set[i]) {
if(out==null) out=""; else out+=separator;
out+=i;
}
}
return out;
}
function stringToSet(str,separator){
var out=new Array(), prev, pos=-1;
if(str==null) return out;
do{
prev=pos+1
pos = str.indexOf(separator, prev);
out[str.substring(prev, pos==-1 ? str.length : pos)]=true;
}while(pos!=-1);
return out;
}
function stringsToMap(keys,values,separatorK,separatorV){
var out=new Array(), prevK, prevV, posK=-1, posV=-1;
if(keys==null || values==null) return out;
do{
prevK=posK+1; prevV=posV+1;
posK=keys.indexOf(separatorK,prevK);
posV=values.indexOf(separatorV,prevV);
out[keys.substring(prevK, posK==-1 ? keys.length : posK)] =
values.substring(prevV, posV==-1 ? values.length : posV);
}while(posK!=-1 && posV!=-1);
return out;
}
function objSize(obj) {
var i,s=0;
for(i in obj) s++;
return s;
}
function setSize(set) {
var i,s=0;
for(i in set)
if(set[i]) s++;
return s;
}
var _SR_;
if(_SR_ != null) _SR_.notify("selecttools.js");