/* $Id: DVdb.js,v 1.25 2008/04/07 22:55:41 drsmith Exp $ */

function saveForms()
{
  frm=0;
  while (frm < top.form.document.forms.length) {
    top.form.document.forms[frm].submit();
    frm++;
  }

  nav.Save.disabled = true;
  nav.Reset.disabled = true;
}

function resetForms()
{
  frm=0;
  while (frm < top.form.document.forms.length) {
    top.form.document.forms[frm].reset();
    frm++;
  }

  nav.Save.disabled = true;
  nav.Reset.disabled = true;
}

function navButton(op, value) 
{
  nav=top.navbar;
  doc=new String(top.form.document.location);
  isMain = (doc.match('main.php') != null);

  if (isMain) {
    frm=top.form.document.forms[0];
  }

  if (op == 'init') {
    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    nav.document.getElementById('Delete').disabled = isMain && (frm.CLIP_ID.value == '');
    nav.document.getElementById('Copy').disabled = isMain && (frm.CLIP_ID.value == '');
    nav.document.getElementById('Find').disabled = false;
  }
  else if (op == 'new') {
    top.form.location = 'main.php';

    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    nav.document.getElementById('Delete').disabled = isMain && (frm.CLIP_ID.value == '');
    nav.document.getElementById('Copy').disabled = isMain && (frm.CLIP_ID.value == '');
    nav.document.getElementById('Find').disabled = false;
  } 
  else if (op == 'change') {
    if (nav.document.getElementById('Save').disabled == true) {
      nav.document.getElementById('Save').disabled=false;
      nav.document.getElementById('Reset').disabled=false;
    }
  }
  else if (op == 'find')  {
    if (isMain) {
      frm.op.value = 'Find';
    }
    top.form.location = "search.php";
  }
  else if (op == 'save')  {
    if (isMain) {
      frm.op.value = 'Save';
    }
    saveForms(); 
  }
  else if (op == 'delete') {
    if (isMain) {
      frm.op.value = 'Delete';
    }
    saveForms(); 
  }
  else if (op == 'copy') {
    if (isMain) {
      frm.CLIP_ID.value = '';
    }
    nav.document.getElementById('Delete').disabled=true;
    nav.document.getElementById('Copy').disabled=true;
    nav.document.getElementById('Save').disabled=false;
    nav.document.getElementById('Reset').disabled=false;
  }
  else if (op == 'reset')  {
    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    resetForms(); 
  }
  else if (op == 'opts') {
    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    nav.document.getElementById('Delete').disabled = true;
    nav.document.getElementById('Copy').disabled = true;
    nav.document.getElementById('Find').disabled = false;
    nav.document.getElementById('Options').selectedIndex = 0;

    if (value == 'search_results') {
      top.form.location = 'conf_sr.php';
    }
    else if (value == 'defaults') {
      top.form.location = 'conf_def.php';
    }
    else if (value == 'selections') {
      top.form.location = 'conf_sel.php';
    }
    else if (value == 'names') {
      top.form.location = 'conf_names.php';
    }
    else if (value == 'fam_names') {
      top.form.location = 'conf_fam_names.php';
    }
    else if (value == 'missing_images') {
      top.form.location = 'missing.php?new';
    }
    else if (value == 'sync') {
      top.form.location = 'sync.php?new';
    }
    else if (value == 'versions') {
      top.form.location = 'conf_ver.php';
    }
    else {
      // take no action
    }
  }
  else if (op == 'summary') {
    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    nav.document.getElementById('Delete').disabled = true;
    nav.document.getElementById('Copy').disabled = true;
    nav.document.getElementById('Find').disabled = false;
    nav.document.getElementById('Summary').selectedIndex = 0;
    top.form.location = 'summary.php?q=' + value;
  }
  else if (op == 'projects') {
    nav.document.getElementById('Save').disabled = true;
    nav.document.getElementById('Reset').disabled = true;
    nav.document.getElementById('Delete').disabled = true;
    nav.document.getElementById('Copy').disabled = true;
    nav.document.getElementById('Find').disabled = false;
    top.form.location = 'projects.php';
  }
  else {
    throw("Unknown OP");
  }

  return(false);
}
function changeSort(obj)
{
  if (obj.value == '') {
    obj.value='+';
  }
  else if (obj.value == '+') {
    obj.value = '-';
  }
  else if (obj.value == '-') {
    obj.value = '';
  }
  else {
    alert('confused now');
  }
}

function sortResults()
{
  /*
   * construct an orderBy string from the sort buttons on each column
   * in the results table. 
   */ 
  var lastOrderByStr = document.getElementById('orderBy').value;

  var orderByStr = '';
  var i=0;
  var col;

  while((col = document.getElementById('sort_'+i))) {
    if (col.value == '+') {
      orderByStr += col.name + " ASC,";
    }
    else if (col.value == '-') {
      orderByStr += col.name + " DESC,";
    }
    i++;
  }

  /* set that string into the hidden orderBy field  */
  if (orderByStr != '') { 
    document.getElementById('orderBy').value = orderByStr.slice(0, -1);
  }
  else {
    document.getElementById('orderBy').value = lastOrderByStr;
  }

  /* submit the results form to refresh the results */
  document.getElementById('searchForm').submit(); 
}

function criteria(op, classVal)
{
  /* ignore any requests that have a null "op" */
  if (op == ''){
    return;
  }

  /* figure out how many criteria rows we have */
  var criteriaCnt = document.getElementById('criteriaCounter').value++;

  /* reset the criteria selector */
  var moreCriteria = document.getElementById('moreCriteria');
  moreCriteria.value = ''; 

  /*
   * prevent mixed use of 'and' and 'or' conjunctions since we don't 
   * have a conventient way to group critera.  (this is hokey but it
   * should work for now.)
   */
  moreCriteria.options[1] = new Option(op, op);
  moreCriteria.options[2] = null;
  
  /* get the basic table info for the search table */
  var tbl = document.getElementById('searchTable');
  var rowCount = tbl.rows.length;
  
  /*
   * add a new row to the table and populate it with blank
   * column, operator, value input structures.
   */
  var row = tbl.insertRow(rowCount);
  row.id = 'Row_'+criteriaCnt;
  
  var cell = row.insertCell(0);
  cell.innerHTML += (tbl.rows[0].cells[0].innerHTML).replace(/Col_[0-9]+/g, 'Col_'+criteriaCnt);
  document.getElementById('Col_'+criteriaCnt).selectedIndex = 0;
  
  cell = row.insertCell(1);
  cell.innerHTML = (tbl.rows[0].cells[1].innerHTML).replace(/Op_[0-9]+/g, 'Op_'+criteriaCnt);
  document.getElementById('Op_'+criteriaCnt).selectedIndex = 0;

  cell = row.insertCell(2);
  cell.innerHTML = (tbl.rows[0].cells[2].innerHTML).replace(/Val_[0-9]+/g, 'Val_'+criteriaCnt);
  setOpVal(document.getElementById('Col_'+criteriaCnt).value, row.id);
  
  /* move the moreCriteria selector to the new last row of the table */
  cell = row.insertCell(3);
  cell.innerHTML =  tbl.rows[rowCount-1].cells[3].innerHTML;

  /* 
   * set the value of the last cell in the PREVIOUS row to the
   * operator the user wants to use to add the new criteria.  
   * also add a hidden field to pass the operator to the server
   * when the query is submitted.
   */  
  cell = tbl.rows[rowCount-1].cells[3];
  cell.innerHTML = "<span class='"+classVal+"'>"+op+"</span>";
  cell.innerHTML += "<input name='Conj_"+(criteriaCnt-1)+"' type='hidden' value='"+op+"'>";
  cell.innerHTML += "<a href='javascript:remove("+(rowCount-1)+")'><span class='"+classVal+"'>[remove criteria]</span></a>";
}

function startSearch()
{
  /* perform any pre-query valdiation and submit the request to the server */
  document.getElementById('searchForm').submit();
}

function cancelSearch()
{
  /* 
   * reset the contents of the search form to their state when the
   * page was first loaded (i.e. get rid of extra criteria and clear
   * the remaining column, operator, and value fields
   */
  var tbl = document.getElementById('searchTable');
  var rows = tbl.rows.length;
  
  /* 
   * move the moreCriteria selector to the last cell in first (soon
   * to be only) row of the table.
   */
  tbl.rows[0].cells[3].innerHTML = tbl.rows[rows-1].cells[3].innerHTML;
  
  /* delete all but the first row */
  while(--rows) {
    tbl.deleteRow();
  }

  /* reset the remaining form elements to the default values */
  document.getElementById('searchForm').reset();
}

function setOpVal(searchCol, rowId)
{
  /* extract the true row offset from the supplied Col_### string */
  rowId=rowId.substr(4);

  /* locate the row in the searchTable object */
  var row = document.getElementById("Row_" + rowId);

  /* 
   * set the Val cell (#2) in the indicated row to the selector
   * for the specified searchCol using the valTemplates array
   */
  var html = valTemplates[searchCol];
  html = html.replace(/###/g, rowId);

  /*
   * set third cell in the appropriate row of the searchTable to
   * the generated html.  
   */
  row.cells[2].innerHTML = html;
}


function setCol(searchType, rowId)
{
  /* locate the row in the searchTable object */
  var row = document.getElementById("Row_" + rowId);

  /* 
   * set the Col cell (#0) in the indicated row to the selector
   * for the specified searchType
   */
  var html = colTemplates[searchType];
  html = html.replace(/###/g, rowId);

  /*
   * set third cell in the appropriate row of the searchTable to
   * the generated html.  
   */
  row.cells[0].innerHTML = html;
}

function remove(row)
{
  var tbl = document.getElementById('searchTable');
  tbl.deleteRow(row);

  /* reset the criteria selector if we're down to one row */
  if (tbl.rows.length == 1) {
    moreCriteria = document.getElementById('moreCriteria');
    moreCriteria.value = ''; 
    moreCriteria.options[1] = new Option('and', 'and');
    moreCriteria.options[2] = new Option('or', 'or');
  }
}

var disableSuggest = -1;

function suggest(src)
{
  cFields = Array(
    Array('SCIENTIFIC_NAME', document.getElementById('SCIENTIFIC_NAME')),
    Array('COMMON_NAME_1', document.getElementById('COMMON_NAME_1')),
    Array('COMMON_NAME_2', document.getElementById('COMMON_NAME_2')),
    Array('FAMILY', document.getElementById('FAMILY')),
    Array('COMMON_FAMILY_NAME_1', document.getElementById('COMMON_FAMILY_NAME_1')),
    Array('COMMON_FAMILY_NAME_2', document.getElementById('COMMON_FAMILY_NAME_2'))
  );

  if (src == cFields[0][0]) {
    offset = 0;
  }
  else if (src == cFields[1][0]) {
    offset = 1;
  }
  else {
    throw('unknown source');
  }

  val = cFields[offset][1].value;

  if (val == '') {
    window.status = '';
    if (offset === disableSuggest) {
      disableSuggest = -1;
    }
    return;
  }
  else {
    val = val.toLowerCase();
  }

  if (disableSuggest != -1) {
    return;
  }

  for(key in sciNames) {
    if (((offset == 0) && (String(sciNames[key][0]).toLowerCase() == val)) ||
        ((offset == 1) && ((String(sciNames[key][1]).toLowerCase() == val) ||
                           (String(sciNames[key][2]).toLowerCase() == val) ))) {
      for(offset=0; offset < cFields.length; offset++) {
        cFields[offset][1].value=sciNames[key][offset];
      }
      return;
    }
  }
  disableSuggest = offset;
  window.status = 'Auto-suggest disabled.';
}

function autoComplete(event, fld, arr) {
  var match;
  var oldVal = fld.value;

  if (document.createEvent) {
    if (navigator.vendor == "Apple Computer, Inc.") {
      /* 
       * SAFARI: this needs to be a UIEvents type event rather than a vanilla Events event
       * otherwise Safari throws a DOM Exception #9.  Whatever that means.
       */
      var changeEvent = document.createEvent("UIEvents");
      changeEvent.initEvent("change", true, false);
    }
    else {
      /* 
       * FIREFOX: set up an event object to activate the navbutton event handling 
       */	 
      var changeEvent = document.createEvent("Events");
      changeEvent.initEvent("change", true, false);
    }
  }

  /* gack if we aren't called to handle a 'keyUp' event */
  if (event.type != 'keyup') {
    throw('autoComplete must be a keyUp event handler');
  }

  /* ignore mouse, "control key" and "alt key" events */
  if ((event.keyCode == 0) || (event.altKey) || (event.ctrlKey)) {
    return;
  }

  /* special handling for special characters */
  if (event.keyCode < 65) {
    switch (event.keyCode) {
      case 8 : /* backspace */
        /* clear the field if we're down to the last character */
        if (oldVal.length <= 1) {
          fld.value='';
          if (fld.dispatchEvent) {
            /* FIREFOX */
            fld.dispatchEvent(changeEvent);
          }
          else
          {
            /* IE */
            fld.fireEvent('onchange');
          }
          return;
        }
        oldVal = oldVal.substr(0, oldVal.length-1);
        break;

      case 40:  /* down arrow */
        for(i=0; i < arr.length; i++) {
          if (arr[i].toLowerCase() == oldVal.toLowerCase()) {
            if (i == (arr.length-1)) {
              fld.value = arr[0];
            }
            else {
              fld.value = arr[i+1];
            }
            if (fld.dispatchEvent) {
              /* FIREFOX */
                fld.dispatchEvent(changeEvent);
            }
            else
            {
              /* IE */
              fld.fireEvent('onchange');
            }
            return;
          }
        }
        break;

      case 38:  /* up arrow */
        for(i=0; i < arr.length; i++) {
          if (arr[i].toLowerCase() == oldVal.toLowerCase()) {
            if (i == 0) {
              fld.value = arr[arr.length-1];
            }
            else {
              fld.value = arr[i-1];
            }
            if (fld.dispatchEvent) {
              /* FIREFOX */
              fld.dispatchEvent(changeEvent);
            }
            else
            {
              /* IE */
              fld.fireEvent('onchange');
            }
            return;
          }
        }
        break;

      default:  /* all other special characters */
        /* take no action ... use default behaviour */
        return;
        break;
    }
  }

  /* search the array for the first match (assumes a sorted array) */
  for(i=0; i < arr.length; i++) {
    if (arr[i].toLowerCase().indexOf(oldVal.toLowerCase()) == 0) {
      match=arr[i];
      break;
    }
  }

  /* if we have a match, set the field */
  if (match != undefined) {
    fld.value = match;
  }

  /* fire any onChange handlers we have */
  if (fld.dispatchEvent) {
    /* FIREFOX */
    fld.dispatchEvent(changeEvent);
  }
  else
  {
    /* IE */
    fld.fireEvent('onchange');
  }

  /*
   * if we found a match, select the autocompleted portion of the string.
   *
   * NB: The text needs to be selected AFTER the onChange events are processed
   * to keep IE from deselecting the text in the course of processing the onChange
   * handler.  Stupid IE.
   */
  if (match != undefined) {
    fld.value = match;

    if (fld.setSelectionRange) {
      /* FIREFOX */
      fld.setSelectionRange(oldVal.length, match.length);
    }
    else {
      rng = fld.createTextRange();
      rng.moveStart('character', oldVal.length);
      rng.select();
    }
  }     

}

function optAddRem(op) 
{
  if (op.name == 'add') {
    fm= document.search_results.qry_results_unused;
    to= document.search_results.qry_results;
  }
  else if (op.name == 'remove') {
    fm= document.search_results.qry_results;
    to= document.search_results.qry_results_unused;
  }
  else {
    throw("optAddRem() doesn't understand: " + op.name);
  }
    
  fmIndex=fm.selectedIndex;

  if (fmIndex < 0) {
    alert("Please select an option to " + op.name + ".");
    return;
  }
  
  fmText=fm[fmIndex].text;
  fmValue=fm[fmIndex].value;
  fm[fmIndex] = null;

  toIndex=to.length;  
  to[toIndex]=new Option(fmText, fmValue, false, true);

  navButton('change');
  optMakeList();
}

function optUpDn(op) 
{
  fm = document.search_results.qry_results;
  fmIndex=fm.selectedIndex;

  if (fmIndex < 0) {
    alert("Please select an option to move " + op.name + ".");
    return;
  }

  if (op.name == 'up') {
    if (fmIndex == 0) {
      return;
    }
    
    toIndex = fmIndex-1;
  }
  else if (op.name == 'down'){
    if (fmIndex == (fm.length-1)) {
      return;
    }
    
    toIndex = fmIndex+1;
  }
  else {
    throw("optUpDn doesn't understand: " + op.name);
  }

  fmText=fm[fmIndex].text;
  fmValue=fm[fmIndex].value;
  
  fm[fmIndex].text = fm[toIndex].text;
  fm[fmIndex].value = fm[toIndex].value;
  
  fm[toIndex].text = fmText;
  fm[toIndex].value = fmValue;

  fm.selectedIndex = toIndex;
  
  navButton('change');
  optMakeList();
}

function optMakeList()
{
  fm = document.search_results.qry_results;
  to = document.search_results.fieldList;
  
  to.value = '';
  
  for(i=0; i < fm.length; i++) {
    if (to.value != '') {
      to.value += ',';
    }
    to.value += fm[i].text;
  }
}

function changeSearchType(searchType) 
{
  /* clobber any started search */
  cancelSearch();

  /* set the available criteria to match the requested search type /*/
  sType = document.getElementById('searchType');
  sType.value = searchType;

  setCol(searchType, 0);
}

// The following code is a modified version of DcomboBox.js
// Copywrite 2004 2005 Martin Krolik (martin@krolik.net)
// All rights reserved.  

function ComboInit(BaseName)
{
  var objA, objB, offset;
  offset = 0;
  if (navigator.appName.indexOf("Mozilla")>=0) offset = -1;
  objA = document.getElementById(BaseName);
  objB = document.getElementById(BaseName + "DcboBox");
  xMoveTo(objB, xPageX(objA) + offset, xPageY(objA));   
  xClip(objB , 0, xWidth(objB), xHeight(objB), xWidth(objB) - 23);
  xShow(objB);
  UnSelectAnyOptions(objB);
}

function UpdateDCBoxGeneric(evt)
{
  var objA, objB, strName;
  var objEvent = new xEvent(evt);
  objB = objEvent.target;
  strName = objB.name;  
  strName = strName.split("DcboBox")[0];
  objA = document.getElementById(strName);
  objA.value = objB.options[objB.selectedIndex].text;
  if (objA && (objA.onchange)) objA.onchange();
}

function UnSelectAnyOptions(selectElement)
{
  // this unselects any records
  for (var n = 0; n < selectElement.options.length; n++) {
    selectElement.options[n].selected = false;
  }
  if (selectElement.options.length > 0) {
    // this is for NS4 on X-Windows
    if (document.layers) {  
      // this is for NS4 on X-Windows
      selectElement.options[0].selected = true;
    }
    selectElement.options[0].selected = false;
  }
  selectElement.selectedIndex = -1;
  selectElement.value = null;
}

function SetDCBox(evt)
{
  var found;
  var objA, objB, strName;
  var objEvent = new xEvent(evt);
  objB = objEvent.target;
  strName = objB.name;  
  strName = strName.split("DcboBox")[0];
  objA = document.getElementById(strName);

  // this selects the right record
  found = -1;
  for (var n = 0; n < objB.options.length; n++) {
    if (objB.options[n].text == objA.value) {
      objB.options[n].selected = true;
      found = n;
    }
    else {
      objB.options[n].selected = false;
    }
  }
  if ((found == -1) && (objB.options.length > 0)) {
    // this is for NS4 on X-Windows
    if (document.layers) {  
      // this is for NS4 on X-Windows
      objB.options[0].selected = true;
    }
    objB.options[0].selected = false;
  }
  
  if (found == -1) {
    objB.selectedIndex = -1;
    objB.value = null;
  }
  else {
    objB.selectedIndex = found;
    objB.value = objA.value;
  }
}

function BuildDCBox(BaseName, StartValue, Options, PixelWidth, Other, AdditionalStyle)
{
  var strBuild = "";
  var DCOptions;
  if (!(PixelWidth)) PixelWidth = 200;
  if (!(StartValue)) StartValue = "";
  if (!(Other)) Other = "";
  if (!(AdditionalStyle)) AdditionalStyle = "";

  if ((typeof Options) == "string") { 
    DCOptions = eval(Options);
  }
  else if ((typeof Options[0]) == "string") {
    DCOptions = Options ;
  }
  else { 
    for (var cnt = 0; cnt < DCOptions.length; cnt++ ) {
      DCOptions[cnt] = Options[cnt][0];
    }
  }

  if (document.layers)
    strBuild += "<table border=0><tr><td align=center>";
  strBuild += "<input type='text' value=\"" + StartValue;
  strBuild += "\" name='" + BaseName + "' id='" + BaseName + "' ";
  if (!(document.layers))
    strBuild += "style='width: " + (PixelWidth - 19) + "px; position: relative; " + AdditionalStyle + "' ";
  if (typeof Options == "string") 
    strBuild += "onKeyUp='autoComplete(event, this, " + Options + ")'";
  strBuild += Other + " />";
  if (document.layers)
    strBuild += "</td></tr><tr><td align=center>- Or Select -</td></tr><tr><td align=center>";
  else
    strBuild += "<img border='0' height='1' width='23' />";
  strBuild += "<select name='" + BaseName + "DcboBox' id='" + BaseName ;
  strBuild += "DcboBox' "
    if (!(document.layers))
      strBuild += "style='width: " + PixelWidth + "px; position: absolute; visibility: hidden; " + AdditionalStyle + "' ";
  strBuild += "readonly='true'  onfocus='SetDCBox(event);' onchange='UpdateDCBoxGeneric(event);' >" ;
  if ((DCOptions) && (DCOptions.length)) {
    for (var cnt = 0; cnt < DCOptions.length; cnt++ ) {
      strBuild += "<option>" + DCOptions[cnt] + "</option>";
    }
  }
  strBuild += "</select>";
  if (document.layers)
    strBuild += "</td></tr></table>";
  return (strBuild);

}
function WriteDCBox(BaseName, StartValue, Options, PixelWidth, Other, AdditionalStyle)
{
  if (!(BaseName)) BaseName = "DefaultDComboBoxName";
  document.write(BuildDCBox(BaseName,StartValue,Options,PixelWidth,Other,AdditionalStyle));
  setTimeout("ComboInit('" + BaseName + "');", 5);
}

// End of modified version of DcomboBox.js

