// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
//


// -------------------------------------------------------------------
// selectUnselectMatchingOptions(select_object,regex,select/unselect,true/false)
//  This is a general function used by the select functions below, to
//  avoid code duplication
// -------------------------------------------------------------------
function selectUnselectMatchingOptions(obj,regex,which,only) {
   if (window.RegExp) {
      if (which == "select") {
         var selected1=true;
         var selected2=false;
      }
      else if (which == "unselect") {
         var selected1=false;
         var selected2=true;
      }
      else {
         return;
      }
      var re = new RegExp(regex);
      for (var i=0; i<obj.options.length; i++) {
         if (re.test(obj.options[i].text)) {
            obj.options[i].selected = selected1;
         }
         else {
            if (only == true) {
               obj.options[i].selected = selected2;
            }
         }
      }
   }
}
      
// -------------------------------------------------------------------
// selectMatchingOptions(select_object,regex)
//  This function selects all options that match the regular expression
//  passed in. Currently-selected options will not be changed.
// -------------------------------------------------------------------
function selectMatchingOptions(obj,regex) {
   selectUnselectMatchingOptions(obj,regex,"select",false);
}

// -------------------------------------------------------------------
// selectOnlyMatchingOptions(select_object,regex)
//  This function selects all options that match the regular expression
//  passed in. Selected options that don't match will be un-selected.
// -------------------------------------------------------------------
function selectOnlyMatchingOptions(obj,regex) {
   selectUnselectMatchingOptions(obj,regex,"select",true);
}

// -------------------------------------------------------------------
// unSelectMatchingOptions(select_object,regex)
//  This function Unselects all options that match the regular expression
//  passed in. 
// -------------------------------------------------------------------
function unSelectMatchingOptions(obj,regex) {
   selectUnselectMatchingOptions(obj,regex,"unselect",false);
}
   
// -------------------------------------------------------------------
// sortSelect(select_object)
//   Pass this function a SELECT object and the options will be sorted
//   by their text (display) values
// -------------------------------------------------------------------
function sortSelect(obj) {
   var o = new Array();
   for (var i=0; i<obj.options.length; i++) {
      o[o.length] = new Option( obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected, obj.options[i].selected) ;
   }
   o = o.sort( 
      function(a,b) { 
         if ((a.text+"") < (b.text+"")) { return -1; }
         if ((a.text+"") > (b.text+"")) { return 1; }
         return 0;
      } 
   );

   for (var i=0; i<o.length; i++) {
      obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
   }
}

// -------------------------------------------------------------------
// selectAllOptions(select_object)
//  This function takes a select box and selects all options (in a 
//  multiple select object). This is used when passing values between
//  two select boxes. Select all options in the right box before 
//  submitting the form so the values will be sent to the server.
// -------------------------------------------------------------------
function selectAllOptions(obj) {
   for (var i=0; i<obj.options.length; i++) {
      obj.options[i].selected = true;
   }
}
   
// -------------------------------------------------------------------
// moveSelectedOptions(select_object,select_object[,autosort(true/false)[,regex]])
//  This function moves options between select boxes. Works best with
//  multi-select boxes to create the common Windows control effect.
//  Passes all selected values from the first object to the second
//  object and re-sorts each box.
//  If a third argument of 'false' is passed, then the lists are not
//  sorted after the move.
//  If a fourth string argument is passed, this will function as a
//  Regular Expression to match against the TEXT or the options. If 
//  the text of an option matches the pattern, it will NOT be moved.
//  It will be treated as an unmoveable option.
//  You can also put this into the <SELECT> object as follows:
//    onDblClick="moveSelectedOptions(this,this.form.target)
//  This way, when the user double-clicks on a value in one box, it
//  will be transferred to the other (in browsers that support the 
//  onDblClick() event handler).
// -------------------------------------------------------------------
function moveSelectedOptions(from,to) {
   // Unselect matching options, if required
   if (arguments.length>3) {
      var regex = arguments[3];
      if (regex != "") {
         unSelectMatchingOptions(from,regex);
      }
   }
   // Move them over
   for (var i=0; i<from.options.length; i++) {
      var o = from.options[i];
      if (o.selected) {
         to.options[to.options.length] = new Option( o.text, o.value, false, false);
      }
   }
   // Delete them from original
   for (var i=(from.options.length-1); i>=0; i--) {
      var o = from.options[i];
      if (o.selected) {
         from.options[i] = null;
         }
      }
   if ((arguments.length<3) || (arguments[2]==true)) {
      sortSelect(from);
      sortSelect(to);
      }
   from.selectedIndex = -1;
   to.selectedIndex = -1;
}

// -------------------------------------------------------------------
// copySelectedOptions(select_object,select_object[,autosort(true/false)])
//  This function copies options between select boxes instead of 
//  moving items. Duplicates in the target list are not allowed.
// -------------------------------------------------------------------
function copySelectedOptions(from,to) {
   var options = new Object();
   for (var i=0; i<to.options.length; i++) {
      options[to.options[i].text] = true;
   }
   for (var i=0; i<from.options.length; i++) {
      var o = from.options[i];
      if (o.selected) {
         if (options[o.text] == null || options[o.text] == "undefined") {
            to.options[to.options.length] = new Option( o.text, o.value, false, false);
         }
      }
   }
   if ((arguments.length<3) || (arguments[2]==true)) {
      sortSelect(to);
   }
   from.selectedIndex = -1;
   to.selectedIndex = -1;
}

// -------------------------------------------------------------------
// moveAllOptions(select_object,select_object[,autosort(true/false)[,regex]])
//  Move all options from one select box to another.
// -------------------------------------------------------------------
function moveAllOptions(from,to) {
   selectAllOptions(from);
   if (arguments.length==2) {
      moveSelectedOptions(from,to);
   }
   else if (arguments.length==3) {
      moveSelectedOptions(from,to,arguments[2]);
   }
   else if (arguments.length==4) {
      moveSelectedOptions(from,to,arguments[2],arguments[3]);
   }
}

// -------------------------------------------------------------------
// copyAllOptions(select_object,select_object[,autosort(true/false)])
//  Copy all options from one select box to another, instead of
//  removing items. Duplicates in the target list are not allowed.
// -------------------------------------------------------------------
function copyAllOptions(from,to) {
   selectAllOptions(from);
   if (arguments.length==2) {
      copySelectedOptions(from,to);
   }
   else if (arguments.length==3) {
      copySelectedOptions(from,to,arguments[2]);
   }
}

// -------------------------------------------------------------------
// swapOptions(select_object,option1,option2)
//  Swap positions of two options in a select list
// -------------------------------------------------------------------
function swapOptions(obj,i,j) {
   var o = obj.options;
   var i_selected = o[i].selected;
   var j_selected = o[j].selected;
   var temp = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
   var temp2= new Option(o[j].text, o[j].value, o[j].defaultSelected, o[j].selected);
   o[i] = temp2;
   o[j] = temp;
   o[i].selected = j_selected;
   o[j].selected = i_selected;
}
   
// -------------------------------------------------------------------
// moveOptionUp(select_object)
//  Move selected option in a select list up one
// -------------------------------------------------------------------
function moveOptionUp(obj) {
   // If > 1 option selected, do nothing
   var selectedCount=0;
   for (i=0; i<obj.options.length; i++) {
      if (obj.options[i].selected) {
         selectedCount++;
      }
   }
   if (selectedCount > 1) {
      return;
   }
   // If this is the first item in the list, do nothing
   var i = obj.selectedIndex;
   if (i == 0) {
      return;
   }
   swapOptions(obj,i,i-1);
   obj.options[i-1].selected = true;
}

// -------------------------------------------------------------------
// moveOptionDown(select_object)
//  Move selected option in a select list down one
// -------------------------------------------------------------------
function moveOptionDown(obj) {
   // If > 1 option selected, do nothing
   var selectedCount=0;
   for (i=0; i<obj.options.length; i++) {
      if (obj.options[i].selected) {
         selectedCount++;
      }
   }
   if (selectedCount > 1) {
      return;
   }
   // If this is the last item in the list, do nothing
   var i = obj.selectedIndex;
   if (i == (obj.options.length-1)) {
      return;
   }
   swapOptions(obj,i,i+1);
   obj.options[i+1].selected = true;
}



function deleteAllOptions( obj ) {
   for (var i=(obj.options.length-1); i>=0; i--) {
      var o = obj.options[i];
         obj.options[i] = null;
      }
}

