/** This script contains all of the javascript functions used in the ElastoDB.
 I hated using javascript, but it was the best way to make the 
 forms interactive
*/

var exon = /^\d+[a-zA-Z]*$/;            //regex for valid exon numbers
var real = /^-?\d+(\.\d+)?$/;           //regex for real numbers
var aa = /^[\s]*([ACDEFGHIKLMNPQRSTVWY]{3,}[\s]*)+$/i;   //regex for amino acids

/** This function validates *most* search criteria before it is
 submitted.  It does not validate exon ranges because they can be lettered.
*/
function validate(_form)
{
//MINEXON CHECK
  var minExon = trim(_form.fromEx.value);
  if (minExon == "")
  {
    alert('You must specify a lower exon bound.');
    return false;
  }

  if (window.RegExp && !exon.test(minExon))
  {
    alert('Invalid lower exon bound');
    return false;
  }

//MAXEXON CHECK
  var maxExon = trim(_form.toEx.value);
  if (maxExon == "")
  {
    alert('You must specify an upper exon bound');
    return false;
  }
                                                                               
  if (window.RegExp && !exon.test(maxExon))
  {
    alert('Invalid upper exon bound');
    return false;
  }

//MINCOL CHECK
  var hMinCol = trim(_form.hMinCol.value);
  var cMinCol = trim(_form.cMinCol.value);
  if (hMinCol == "")
  {
    alert('You must specify a Min value for the hydrophobic colour range');
    return false;
  }
  
  if (window.RegExp && !real.test(hMinCol))
  {
    alert('Invalid hydrophobic colour range Min value');
    return false;
  }
  if (_form.cOptions.selectedIndex != 7)
  {
    if (cMinCol == "")
    {
      alert('You must specify a Min value for the cross-linking colour range');
      return false;
    }
                                                                                                         
    if (window.RegExp && !real.test(cMinCol))
    {
      alert('Invalid cross-linking colour range Min value');
      return false;
    }
  }


//MAXCOL CHECK
  var hMaxCol = trim(_form.hMaxCol.value);
  var cMaxCol = trim(_form.cMaxCol.value);
  if (hMaxCol == "")
  {
    alert('You must specify a Max value for the hydrophobic colour range');
    return false;
  }
                                                                               
  if (window.RegExp && !real.test(hMaxCol))
  {
    alert('Invalid colour range Max value');
    return false;
  }
  if (_form.cOptions.selectedIndex != 7)
  {
    if (cMaxCol == "")
    {
      alert('You must specify a Max value for the cross-linking colour range');
      return false;
    }
                                                                                                         
    if (window.RegExp && !real.test(cMaxCol))
    {
      alert('Invalid cross-linking colour range Max value');
      return false;
    }
  }

//COLOURRANGE CHECK
  if (!(hMaxCol - hMinCol >= 0))
  {
    alert('Invalid hydrophobic colour range');
    return false;
  }
  if ((_form.cOptions.selectedIndex != 7) && !(cMaxCol - cMinCol >= 0))
  {
    alert('Invalid cross-linking colour range');
    return false;
  }

//CHECKBOXES
  var noneChecked = true;
  var inputElems = _form.getElementsByTagName("input");
  for (i=0; i < inputElems.length; i++)
  {  
    if (inputElems[i].type == 'checkbox' && inputElems[i].name == 'searchItem[]' && inputElems[i].checked)
    {
      noneChecked = false;
      break;
    }
  }
  if (noneChecked)
  {
    alert('You must choose at least one organism');
    return false;
  }

//MOTIF CHECK
  var motifs = trim(_form.motifs.value);
  if (motifs != "")
  {
    if (window.RegExp && !aa.test(motifs))
    {
      alert('Invalid motif(s)');
      return false;
    }
  }

  //Otherwise, all is well so return true.
  return true;
}

/** This function updates the colour ranges whenever a new
 property of interest is selected.
*/
function refresh(_select, _max, _min)
{
  _max.disabled = false;
  _min.disabled = false;

  var max;                 //the upper and lower bounds
  var min;

  //set min and max based on which property was selected
  switch (_select.options[_select.selectedIndex].value)
  { 
    //molecular weight
    case "0":
      max = 7733;
      min = 672;
      break;

    //pI
    case "1":
      max = 12.6;
      min = 3.5;
      break;
  
    //charge at pI
    case "2":
      max = 0.11;
      min = -0.13;
      break;

    //kytedoolittle
    case "3":
      max = 0.14;
      min = -0.087;
      break;
  
    //hoppwoods
    case "4":
      max = 0.032;
      min = -0.076;
      break;

    //rose
    case "5":
      max = 0.081;
      min = 0.0048;
      break;
 
   //wolfenden
    case "6":
      max = 0.19;
      min = -0.35;
      break;
   //motif
    case "7":
      max = 0;
      min = 0;
      _max.disabled = true;
      _min.disabled = true;
  }

  //fill in the textboxes
  _max.value = max;
  _min.value = min;
}

/**
 This function trims a string.
 */
function trim(sInString) {
  sInString = sInString.replace( /^\s+/g, "" );     // strip leading
  return sInString.replace( /\s+$/g, "" );          // strip trailing
}

/**
 This function changes the style tag of an object so that it has a red border.
 */
function highlight(_object)
{ 
  _object.style.border = "1px solid red";
}

/**
 This function changes selects all organisms on the Search page
 or clears all selected organisms.
 */
function selectAll(_form)
{ 
  var inputElems = _form.getElementsByTagName("input");
  for (i=0; i < inputElems.length; i++)
  {  
    if (inputElems[i].type == 'checkbox' && inputElems[i].name == 'searchItem[]')
    {
      inputElems[i].checked = true;
    }
  }

	//expand all menus
	expandAll();
}

/**
 This function changes selects all organisms on the Search page
 or clears all selected organisms.
 */
function selectNone(_form)
{ 
  var inputElems = _form.getElementsByTagName("input");
  for (i=0; i < inputElems.length; i++)
  {  
    if (inputElems[i].type == 'checkbox' && inputElems[i].name == 'searchItem[]')
    {
      inputElems[i].checked = false;
    }
  }
}

/** added on April 11, 2006
 This function expands/collapses the Organism menus
 */
function toggleMenu(_form)
{
	var listElement = document.getElementById(_form);
	if ( listElement.style.display != 'none' )
	{
		listElement.style.display = 'none';
	} else
	{
		listElement.style.display = '';
	}
}

/**
 This function expands all of the menus
*/
function expandAll()
{
	var listElems = document.getElementsByTagName('div');
	for (i=0; i < listElems.length; i++)
	{
		if (listElems[i].className == 'list')
		{
			listElems[i].style.display = '';
		}
	}
}

/** 
 This function collapses all of the menus on initial load.
 If the page is refreshed, it will remember the state of the menus
 */
function collapseAll()
{
	var activeCheckbox = false;
	var listElems = document.getElementsByTagName('div');

	for (i=0; i < listElems.length; i++)
	{
		if (listElems[i].className == 'list')
		{
			activeCheckbox = checkInput(listElems[i]);
			if (activeCheckbox == false)
			{
				listElems[i].style.display = 'none';
			}
		}
	}
}

/**
 Given the element, check to see if the child input elements have a completed checkbox
 */
function checkInput(_form)
{
	var inputElems = _form.getElementsByTagName('input');

	for (j=0; j < inputElems.length; j++)
	{
		if (inputElems[j].type == 'checkbox' && inputElems[j].name == 'searchItem[]' && inputElems[j].checked == true)
		{
			return true;
		}
	}
	return false;
}

/**
 This is another validate function that verifies the selections made for viewing sequence comparisons
 */
function validateGenes(_form)
{
  //similar to the part that verifies the checkboxes in validate()
	var numChecked = 0;
  var noneChecked = true;
	var input = _form.getElementsByTagName("input");
	for (i=0; i < input.length; i++)
	{
	  if (input[i].type == 'checkbox' && input[i].name == 'compareItem[]' && input[i].checked)
		{
		  noneChecked = false;
			numChecked++;
		}
	}
	if (noneChecked)
	{
	  alert('You must select at least one gene');
		return false;
	}

	/**
	//if only one checkbox is checked, the display confirm message
	if (numChecked == 1)
	{
	  var selection = confirm("You have selected only one gene. All exons in this gene will be displayed.\nPress OK to proceed or Cancel to abort");
		return selection;
	}
	*/

	//Otherwise, return true
	return true;
}
	  
/**
 This is the same as selectAll() and clearAll(), but it is used for the checkboxes on the results page.
 The select all and clear all functionality are incorporated into this one function.
 */
function toggleSelectGenes(_id, _bool)
{
  var input = document.getElementById(_id);
	input = input.getElementsByTagName("input");
	for (i=0; i < input.length; i++)
	{
	  if (input[i].type == 'checkbox' && input[i].name == 'compareItem[]' && !input[i].disabled)
		{
		  input[i].checked = _bool;
		}
	}
}

