/*
  This module contains the javascript functions to give extra 
  fuctionality to the ms-cpa webpages

  Copyright (c) 2008. Regents of the University of California.
  All rights reserved.

  Changes:
  09/04/08 - Creation (jung@ucsd.edu)
*/

// This is to test that the script is loaded 
function HelloWorld() {
  document.write("Hello World!");
}

// Return the letters of the sequence in non-duplicated form  
function dereplicate(sequence) {
  var ret_seq = '';
  for (i = 0; i < sequence.length; i++) {
    if (sequence.indexOf(sequence.charAt(i)) == i) {
      ret_seq += sequence.charAt(i);
    }
  }
  return ret_seq;
}

// Convert that the sequence is compose of [a-zA-Z]
function convert_alpha(sequence) {
  var ret_seq = '';
  matches = sequence.match(/[a-zA-Z]+/g);
  if (matches == null)  return '';     // take care of the nothingness
  for (i = 0; i < matches.length; i++) {
    ret_seq += matches[i]; 
  }
  return ret_seq;
}


// Catch the return key and disallow autosubmit
function catch_return(e) {
  var keycode;
  if (window.event) keycode = window.event.keyCode;
  else if (e) keycode = e.which;
  else return true;
  
  if (keycode == 13)    return false;
  else                  return true;
}


// these are the known letters and known amino acid masses
aa_letter = 'ACEDGFIHKMLONQPSRTWVY';
aa_masses = new Array('71.03711', '103.00919', '129.04259', '115.02694', '57.02146', '147.06841', '113.08406', '137.05891', '128.09496', '131.04049', '113.08406', '114.07931', '114.04293', '128.05858', '97.05276', '87.03203', '156.10111', '101.04768', '186.07931', '99.06841', '163.06333');

// function to ignore the enter key
catch_return_str = "return catch_return(event)"
	  
// check whether this letter corresponds to a known mass
function get_mass(aa) {
  mass_index = aa_letter.indexOf(aa);
  if (mass_index < 0)   return -1;
  return aa_masses[mass_index];
}


// Function display the neccessary forms to ask for amino acid masses
function display_aa_forms(this_form, table_id) {
  // automatically convert the string to allowed letters 
  alpha_sequence = convert_alpha(this_form.value);
  simple_seq = dereplicate(alpha_sequence);
  this_form.value = alpha_sequence;

  //alert(simple_seq.length);
  table_obj = document.getElementById(table_id);
  // populate the previous mass values
  ori_rows = table_obj.tBodies[0].rows;
  ori_letters = '';
  ori_masses = new Array();  
  for (i = 1; i < ori_rows.length; i++) {
     ori_letters += ori_rows[i].cells[0].firstChild.nodeValue;
     ori_masses[i-1] = ori_rows[i].cells[1].firstChild.value;
  }

  // create the new table body
  t_body = document.createElement("tbody");
  for (i = 0; i < simple_seq.length; i++) {
    this_letter = simple_seq.charAt(i);
    
    if (i == 0) {
      // add the header
      var new_row = document.createElement('tr');
      var new_cell = document.createElement('th');
      var new_text = document.createTextNode('Letter');
      new_cell.appendChild(new_text);
      new_row.appendChild(new_cell);
      var new_cell = document.createElement('th');
      var new_text = document.createTextNode('Mass');
      new_cell.appendChild(new_text);
      new_row.appendChild(new_cell);
      t_body.appendChild(new_row);
    }
    
    var new_row = document.createElement('tr');

    var new_cell = document.createElement('td');
    var new_text= document.createTextNode(this_letter);
    new_cell.appendChild(new_text);
    new_row.appendChild(new_cell);

    input_name = 'mass_' + this_letter;
    var new_cell = document.createElement('td');
    var new_input = document.createElement('input');
    new_input.setAttribute('type', 'text');
    new_input.setAttribute('name', input_name);
    new_input.setAttribute('size', '8');
    new_input.setAttribute('onkeypress', catch_return_str);

    // populate with previous value, or prefilled value
    var this_value = '';
    var default_mass = get_mass(this_letter);
    if (default_mass > 0) {
      this_value = default_mass;
      new_input.setAttribute('readonly', 'yes');
    } 
    else { 
      var this_index = ori_letters.indexOf(this_letter);
      if (this_index >= 0) {
        this_value = ori_masses[this_index]; 
      }
    }
    new_input.setAttribute('value', this_value);
    new_input.setAttribute('align', 'right');
    new_cell.appendChild(new_input);
    new_row.appendChild(new_cell);
        
    t_body.appendChild(new_row);
  }
  table_obj.replaceChild(t_body, table_obj.tBodies[0]);
} 


// Test whether the value can be converted to numeric
function to_number(value) {
  converted = Number(value)
  if (isNaN(converted)) {
    return value
  }
  return converted
}
  
// Sort the table_obj by this column
function sort_table_obj(table_obj, column_index, reverse) {
  var rows = new Array();

  ori_rows = table_obj.tBodies[0].rows
  // first row is the header  
  for (i=ori_rows.length-1; i>=1; i--) {
    ori_row = ori_rows[i];

    // push the current row into a js array
    cont = new Object()      // the container for the array
    cont.row = ori_row
    cont.value = to_number(ori_row.cells[column_index].firstChild.nodeValue);
    rows.push(cont);

    // remove this row
    ori_row.parentNode.removeChild(ori_row);
  }

  // inner function for sorting
  if (reverse) {
    var sort_fn = function(a, b) {
      if (a.value > b.value) return 1;
      if (a.value < b.value) return -1;
      return 0;
    } 
    rows.sort(sort_fn);
  }
  else {
    var sort_fn = function(a, b) {
      if (a.value > b.value) return -1;
      if (a.value < b.value) return 1;
      return 0;
    } 
    rows.sort(sort_fn);
  }

  // insert everything back
  for (row_index in rows) {
    table_obj.tBodies[0].appendChild(rows[row_index].row);
  }
}


// a wrapper that toggles the sort of the given column_index
function sort_table(table_id, column_index) {

  // get the table obj and make sure it is valid
  table_obj = document.getElementById(table_id);
  if (!table_obj || table_obj.nodeName.toLowerCase()!='table') {
    return;   // not a table
  }
  
  t_node = table_obj.tBodies[0].rows[0].cells[column_index];
  reverse_attr = t_node.attributes.getNamedItem("reverse");
  if (reverse_attr && reverse_attr.value=="true") {
    t_node.setAttribute("reverse", "false");
    sort_table_obj(table_obj, column_index, true)
  }  
  else {
    t_node.setAttribute("reverse", "true");
    sort_table_obj(table_obj, column_index, false)
  }  
}
