//----------------------------------------------------------------------------------------------------------
//                                        Dual Select Control
//    Notes:
//       Functions for use with dual select pop-up window
//
//    Usage:
//       1. Create text field to hold results and button to popup dual select
//       2. Create HTML for dual select containing:
//             - call to this script
//             - the 2 multi-select boxes - these should contain actions for the onDblClick event:
//                ondblclick="one2two([reference to left select element], document.form1.right)" for left select box
//                ondblclick="two2one([reference to left select element], document.form1.right)" for right select box
//             - text box for searching [optional] - this should contain following event actions:
//                onkeyup="locateOption(this, [reference to left select element])"
//                onkeypress="checkForEnter(event, [reference to left select element], [reference to right select element])"
//             - buttons for move left/right (execute the one2two and two2one methods)
//             - buttons for moving selected elements up/down [optional] (execute the moveup() and movedown() methods)
//             - OK button (execute the processOK() method)
//             - onLoad event in BODY tag must execute init() method
//
//    Revision History:
//       -  Created 9/21/01 - Aidan Curran (includes functions from the file 1to2.js)
//
//    Copyright ?995-2001, Agile Software Corp. All rights reserved.   
//----------------------------------------------------------------------------------------------------------

 

// this function is used to move the items that have previously been selected (i.e. from the textbox) into the second list
// params: left multi-select element, right multi-select element, text element for results, use values flag (if true, option value used in comparison. if false, option text used)
function init(m1, m2, objResultsField, bUseValues) {
   var strOptionCompareValue;
  
   arrExistingItems = objResultsField.value.split(", ")     // create array of items from text box which will be seperated bu comma and space
   // loop through options in select list and move them to right if they match items in array
   for (var i = 0; i < m1.length; i++) {
      for (var j = 0; j < arrExistingItems.length; j++) {
         if (bUseValues)
            strOptionCompareValue = m1.options[i].value
         else
            strOptionCompareValue = m1.options[i].text
         if (strOptionCompareValue == arrExistingItems[j]) {
            m1.options[i].selected = true;   // select the matching fields
            break;
         }
      }
   }
   one2two(m1, m2);  // move the selected items
}


// this function is used to place the selected items in the results textbox on the opener form
// params: text element for results, right multi-select element
function processOK(objResultsField, m2){

   var results = "";

   for (i = 0; i < m2.length; i++) {
      results += m2.options[i].text;
      if (i != m2.length - 1) results  += ", ";
   }

   if (objResultsField.value != "eHubs")
      objResultsField.value = results;
   window.close();
}

var intLastSelected;    // var to hold index of last option selected with the search box


// match text being typed in in search box to option in select list and select that option
// params: input text, left multi-select element
function locateOption(objText, objSelect)
{
   if (objSelect.length > 0) { // should only work if there are options in the list
      var regExpr = new RegExp("^\\s*" + objText.value, "i")
      regExpr.ignoreCase = true;
  
      // deselect last selected item(s)
      if(objSelect.selectedIndex != -1) {
         for ( i=objSelect.selectedIndex; i < objSelect.length ; i++) {
            objSelect.options[i].selected = false;
         }
      }
     
      //if (intLastSelected != null)  // last selection made by
      //   objSelect.options[intLastSelected].selected = false;
                    
      for ( i=0; i < objSelect.length ; i++) {
       
        if (objSelect.options[i].text.search(regExpr) != -1) {
            objSelect.options[i].selected = true;
            intLastSelected = i;
            break;
        }
      }
    }
}

// move selected options from left to right if enter key pressed
function checkForEnter(evt, m1, m2, objText) {
   evt = (evt) ? evt : event;
   var charCode = (evt.which) ? evt.which : evt.keyCode;
   if (charCode == 13) {
      objText.value = "";
      one2two(m1, m2);
   }
   return false;
}

 


// Note: the following functions were originally from 1to2.js

function one2two(m1, m2)
{
    m1len = m1.length ;
    for ( i=0; i<m1len ; i++){
        if (m1.options[i].selected == true ) {
            m2len = m2.length;
            m2.options[m2len]= new Option(m1.options[i].text, m1.options[i].value);
        }
    }

  
 j = -1;
    for ( i = (m1len -1); i>=0; i--){
        if (m1.options[i].selected == true ) {
            m1.options[i] = null;
   j = i;
        }
    }
 
 if (j == -1)
  return;
  
 sortOptions (m2);
 
 
 // move focus to the next item
 if (m1.length <= 0)
  return;
  
 if ((j < 0) || (j > m1.length))
  return;
  
 if (j == 0)
  m1.options[j].selected = true;
 else if (j == m1.length)
  m1.options[j-1].selected = true
 else
  m1.options[j].selected = true;
}

function two2one(m1, m2)
{
    m2len = m2.length ;
 for ( i=0; i<m2len ; i++){
  if (m2.options[i].selected == true ) {
   m1len = m1.length;
   m1.options[m1len]= new Option(m2.options[i].text);
  }
 }

 
 j = -1;
 for ( i=(m2len-1); i>=0; i--) {
  if (m2.options[i].selected == true ) {
   m2.options[i] = null;
   j = i;
  }
 }

 if (j == -1)
  return;
  
 sortOptions (m1);
 
 // move focus to the next item
 if (m2.length <= 0)
  return;
  
 if ((j < 0) || (j > m2.length))
  return;
  
 if (j == 0)
  m2.options[j].selected = true;
 else if (j == m2.length)
  m2.options[j-1].selected = true
 else
  m2.options[j].selected = true;
}

function deleteOption(object,index) {
    object.options[index] = null;
}

function addOption(object,text,value) {
    var defaultSelected = false;
    var selected = false;
    var optionName = new Option(text, value, defaultSelected, selected)
    object.options[object.length] = optionName;
    object.options[object.length-1].selected = false;

}

function sortOptions(what) {
    var copyOption = new Array();
    for (var i=0;i<what.options.length;i++)
        copyOption[i] = new Array(what[i].text,what[i].value);

    copyOption.sort(sorti);

    for (var i=what.options.length-1;i>-1;i--)
        deleteOption(what,i);

    for (var i=0;i<copyOption.length;i++)
        addOption(what,copyOption[i][0],copyOption[i][1])
}

function getselected (selections, m1, m2)
{
 selections.value = "";
 for (var i=0; i<m2.length; i++)
 {
  selections.value += m2.options[i].text + ";";
 }
 
 // reset the multiple selections for the two list box
 // because cgi will send multiple values to the form otherwise
 for (i=0; i<m1.length; i++)
  m1.options[i].selected = false;
 for (i=0; i<m2.length; i++)
  m2.options[i].selected = false;
 
 return true;
}

/**********************************************************************************
 * the following functions were originally in ValidationsLib.js
 *********************************************************************************/
function moveUp(m2)
{
   for (i=0; i<m2.length; i++)
   {
 if (m2.options[i].selected == true)
 {
  var opText = m2.options[i].text;
  var opValue = m2.options[i].value;
  
  if (i > 0)
  {
   m2.options[i] = new Option (m2.options[i-1].text, m2.options[i-1].value, true);
   m2.options[i-1] = new Option (opText, opValue);
   m2.options[i-1].selected = true;
  }
 }
   }
}

function moveDown(m2)
{
 for (i=(m2.length-1); i>=0; i--)
 {
  if (m2.options[i].selected == true)
  {
   var opText = m2.options[i].text;
   var opValue = m2.options[i].value;
   
   if (i < (m2.length-1))
   {
    m2.options[i] = new Option (m2.options[i+1].text, m2.options[i+1].value, true);
    m2.options[i+1] = new Option (opText, opValue);
    m2.options[i+1].selected = true;
   }
  }
 }
}

// Options transfer between select lists. Handles multiple moves.
// This function takes following parameters:
//  @param selectSrc - select box name
// @param selectTrg - select box name
// @param frm - form name
//  @param append - append or prepend
// @param ignore - flag to indicate the fields without any values should be ignored.
function moveOptions(selectSrc,selectTrg,frm,ignore,prepend)
{
    var source = eval("document."+frm+"."+selectSrc);
    var target = eval("document."+frm+"."+selectTrg);
 
 divId = selectTrg + "_div" ;   
 divs = document.getElementsByTagName("DIV");   
 myTarget = eval("divs." + divId);
 
 var arr = new Array();

 // create an array of new <OPTION> elements
    while (source.selectedIndex >= 0)
    {
  text = source.options[source.selectedIndex].text;
  value = source.options[source.selectedIndex].value;
   
  if ((typeof ignore != "undefined" && ignore) && (value == null || value == ''))
  {
   source.options[source.selectedIndex].selected = false;
   continue;
  }
  
  if ( text.indexOf("----") != -1 )
  {
   source.options[source.selectedIndex].selected = false;
   continue ;
  }
   
        arr[arr.length] = "<OPTION value=\"" + doEscape(value) + "\">" + doEscape(text) + "</OPTION>";
   
  eval(source.options[source.selectedIndex] = null);
    }
 
 joinSelectTag(myTarget,arr,prepend);

 target = eval("document."+frm+"."+selectTrg);
  
 // deselect all selected options 
 for ( i=0; i<target.length; i++ )
  target.options[i].selected = false ;
   
 // select last added element
 if ( target.length >= 1 )
 {
  if ( typeof prepend != "undefined" && prepend )
   target.options[0].selected=true ;
  else
   target.options[target.length-1].selected=true ;
 }
}

// use this function if the dual select has sections within
//  calls moveOptions, BUT has the prepend flag turned on
function moveSectionOptions(selectSrc,selectTrg,frm,ignore,seperator)
{
 // in case of groups, prepend values to top of select box
 moveOptions(selectSrc,selectTrg,frm,ignore,true)
}

// move selected options from left to right if enter key pressed in text box
function moveOptionsOnEnter(evt,objText,selectSrc,selectTrg,frm,ignore) {
   evt = (evt) ? evt : event;
   var charCode = (evt.which) ? evt.which : evt.keyCode;
   if (charCode == 13) {
      objText.value = "";
      moveOptions(selectSrc,selectTrg,frm,ignore);
   }
   return false;
}

// move selected options from left to right if enter key pressed in text box
function moveSectionOptionsOnEnter(evt,objText,selectSrc,selectTrg,frm,ignore,seperator) {
   evt = (evt) ? evt : event;
   var charCode = (evt.which) ? evt.which : evt.keyCode;
   if (charCode == 13) {
      objText.value = "";
      moveSectionOptions(selectSrc,selectTrg,frm,ignore,seperator)
   }
   return false;
}

// joins the final select tag together
// handles append or prepend modes
function joinSelectTag(myTarget,arr,prepend)
{
 if ( typeof prepend == "undefined" || !prepend )
 {
  myTarget.innerHTML = myTarget.innerHTML.substring(0,myTarget.innerHTML.length-9) + arr.join() + myTarget.innerHTML.substring(myTarget.innerHTML.length-9,myTarget.innerHTML.length);
 }
 else
 {
  var NS6 = (navigator.vendor == ("Netscape6") || navigator.product == ("Gecko"));
  var i = NS6 ? myTarget.innerHTML.indexOf("<option") : myTarget.innerHTML.indexOf("<OPTION") ; 
 
  if ( i == -1 )
   var i = NS6 ? myTarget.innerHTML.indexOf("</select>") : myTarget.innerHTML.indexOf("</SELECT>") ;
  
  var selectTag = myTarget.innerHTML.substring(0,i);

  // join <SELECT> tag
  myTarget.innerHTML = selectTag + arr.join() + myTarget.innerHTML.substring(i,myTarget.innerHTML.length);
 }
 //alert('inner html = ' + myTarget.innerHTML);
}

// sorts an array
function sorti(a, b)
{
 var A = a.toUpperCase ();
 var B = b.toUpperCase ();
 if (A <= B)
  return -1
 else
  return 1
}

 

function doEscape(str)
{
 var result = '';
 for (i=0; i<str.length; i++ )
 {
  switch (str.charAt(i))
  {
   case '<' :
    result += "&lt;";
    break ;
   case '>' :
    result += "&gt;";
    break ;
   case '"' :
    result += "&quot;";
    break ;
   case '\r' :
    result += "<br>";
    break ;
   default:
    result += str.charAt(i);
    break; 
  }
 }
 return result ;
}