/*  # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    #                   CONCENTRATION CALCULATOR
    # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/

    function conc_calc() // do molar calc
    { // Copyright 2001 Array Genetics, Inc. All rights reserved.

      var o   = document.molarCalc;
      var c   = o.conc.value;
      var mw  = o.mw.value;

      if (c =="") { alert('please enter "Concentration" value,'); return false; }
      if (mw=="") { alert('please enter "Molecular Weight" value,');  return false; }

      o.mc.value = '???';  // clear output

      var i  = o.concUnit.selectedIndex;
      var i2 = o.outUnits.selectedIndex;

      if      (i == 0) cf1 = "1e0"; //  g/ml
      else if (i == 1) cf1 = "1e3"; // mg/ml
      else if (i == 2) cf1 = "1e6"; // ug/ml

      if      (i2 == 0) cf2 = "1e0";  // (M)
      else if (i2 == 1) cf2 = "1e3";  // (mM)
      else if (i2 == 2) cf2 = "1e6";  // (uM)
      else if (i2 == 3) cf2 = "1e9";  // (nM)
      else if (i2 == 4) cf2 = "1e12"; // (pM)

      /** conversion notes:
       *    1 mole per liter equals 1 molar.
       *    'mw' is measured in grams per mole.
       *    hence: grams/liter  /  grams/mole  =  moles/liter = molar [M]
      **/
      var cStr =   "("          +      // substance concentration in solution
                      c         +      // conc. in input units
                      "*1e3"    +      // convert ml to liters
                      "/" + cf1 +      // convert to grams
                   ")";                // result: grams per liter

      var molarStr = cStr + "/" + mw + // calculate moles per liter = molar
                     "*" + cf2;        // convert to molar output units.


      var mc = eval( molarStr );

      with (Math)
      { e=0;
        mc2 = mc;
        if (mc<1)  while (mc<1)   { mc = mc * 10; e--; }
        else       while (mc>=10) { mc = mc / 10; e++; }

        if      ((e>-4) && (e<0)) while (e<0)  { mc = mc / 10; e++; }
        else if ((e>0)  && (e<4)) while (e>0)  { mc = mc * 10; e--; }

        vStr = String( round(mc*1000) / 1000 );
        if (e!=0)  vStr += 'E'+ String(e);
        vStr += '  ' + o.outUnits.options[i2].text;;

        // o.mc.value = String(mc2) + ' ::: ' + vStr; // test correctness
        o.mc.value = vStr;
      }

/*
      does not work on freeBSD KDE browser, must be something with browser ID

      if ( ie4)
      { // o.mc.value =  mc.toFixed(3);
        // o.mc.value =  mc.toExponential(3);
        o.mc.value = " " + mc.toPrecision(4);
      }
      else
      {
        o.mc.value = String ( mc );      // no formating
      }
      o.mu.value = o.outUnits.options[i2].text;
*/

    }


/*
    # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    #                   MOLECULAR WEIGHT CALCULATOR
    # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/

    /**
     * by: Gary Argraves - 2000.0310  (c) 2001
     * email: gArgraves@earthlink.net
     * cross checked w/program at URL http://expasy.cbr.nrc.ca/tools/protparam.html
    **/
    var w1 = null;  // window object

    function f(s,l)
    { // return a formated string of length l
      s = "          " + s;
      return s.substr(s.length - l);
    }

    function f2(s)
    { // add leading 0 before a decimal number < 1., i.e., .463 becomes 0.463
      if ( s.charAt(0) == "." ) s = "0" + s; // need leading 0
      return s;
    }

    function extinction_Co_calc() // do Extinction Coefficient Calc.
    {
       if (document.extCoefCalc.tarSeq.value == "")
       {
         alert('Need Target Sequence.');
         return;
       }

       var nl = "<br>"; // or "\n";
       var s = document.extCoefCalc.tarSeq.value.toUpperCase(); // input protein sequence string
       var r = "";  // result;
       a = "ABCDEFGHI.KLMN.PQRST.VWXYZ"; // include residues here
/*
       Ala (A)
       Asx (B)  // Asx not regular  Asp (D) or Asn (N) mw = (114.1+115.1) / 2 = 114.6
       Cys (C)
       Asp (D)
       Glu (E)
       Phe (F)
       Gly (G)
       His (H)
       Ile (I)
            J   // not used
       Lys (K)
       Leu (L)
       Met (M)
       Asn (N)
            O   // not used
       Pro (P)
       Gln (Q)
       Arg (R)
       Ser (S)
       Thr (T)
            U   // not used
       Val (V)
       Trp (W)
       Xaa (X)  // Xaa not regular        median of all= 118.9.  avg of all = 114.6
       Tyr (Y)
       Glx (Z)  // Glx not regular  Glu (E) or Gln (Q)  mw =  (129.1 + 128.1) / 2 = 128.6
*/
       uc =  [  // universal codes
       "Ala","Asx","Cys","Asp","Glu","Phe","Gly","His","Ile","   ","Lys",
       "Leu","Met","Asn","   ","Pro","Gln","Arg","Ser","Thr","   ","Val",
       "Trp","Xaa","Tyr","Glx"];


       /** Reference: Laboratory Techniques in Biochemistry and Molecular Biology
        * Sequencing of proteins and Peptides, Elsevier, G. Allen page 2-4.
       **/
       /*
       m_wt0= [
         //  A     B     C    D     E      F    G    H      I   J  K
            71.1,114.6,103.1,115.1,129.1,147.2,57.1,137.2,113.2,0,128.2,
         //  L     M     N   O  P    Q      R    S    T    U  V     W     X     Y   Z
           113.2,131.2,114.1,0,97.1,128.1,156.2,87.1,101.1,0,99.1,186.2,114.6,163.2,128.6 ];
       */
       /** Revised 3/10/2001
        *  Reference: Proteins Structures  and  Molecular Properties, 2nd
        *  Edition, Thomas E. Creighton, W. H. Freeman and Co., New York
        *  note:  These MW values  are  minus  the  weight  of water  (mw=18).
        *         When you string amino acids together all but the last have
        *         lost 18 so you need to add it to the sum.
       **/
       /*
       m_wt1 = [
          71.09, 114.6, 103.15, 115.09, 129.12, 147.18,  57.05, 137.14, 113.6,
           0,    129.17,113.16, 131.19, 114.11,   0,     97.12, 128.14, 156.19,
          87.08, 101.11,  0,     99.14, 186.21, 119.4,  163.18, 128.6 ];
       */
       m_wt2 = [ // use old I and K
          71.09, 114.6, 103.15, 115.09, 129.12, 147.18,  57.05, 137.14, 113.2,
           0,    128.17,113.16, 131.19, 114.11,   0,     97.12, 128.14, 156.19,
          87.08, 101.11,  0,     99.14, 186.21, 119.4,  163.18, 128.6 ];

       /*** init. residue count array ***/
       cnt = new Array(26);
       for (var i=0; i<26; i++) cnt[i]=0;

       /*** count residues ***/
       var invalid_residues = 0;
       r += "--- User Provided Protein Sequence -----------------"+nl;
       r += "<pre>";
       r += "      1          11         21         31         41         51\n";
       r += "      |          |          |          |          |          |";
       var j=0;
       for (var i=0; i<s.length; i++)
       {
         c = s.charAt(i);
         if ( a.indexOf(c) != -1 )
         {
           if ( (j % 60)==0 )
           {
             if (j) r += f( String(j), 6);
             r += "\n";
             r += f( String(j+1), 5);
           }

           if ((j % 10)==0) r += " ";
           j++;
           r += c;
           cnt[ a.indexOf(c) ]++;
         }
         else invalid_residues++;
       }
       r += "</pre>";
       r += nl;

       /*** display residue count ***/
       r += "--- Residue Count -------------------------------"+nl;
       var rc = 0; // count all valid residues
       for (var i=0; i<a.length; i++)
       {
         if (a.charAt(i)==".") continue; // invalid residue
         if ( !cnt[i]) continue; // do not display zero counts
         rc += cnt[i];
       }
       /*** Total No. of Residues ***/
       r += "Total No. of Residues = " + String (rc);
       r += nl;
       if ( invalid_residues )
       {
         r += "Invalid Residue Count = " + String( invalid_residues );
         r += nl;
       }

       r += "<pre>";
       for (var i=0; i<a.length; i++)
       {
         if (a.charAt(i)==".") continue; // invalid residue
         if ( !cnt[i]) continue; // do not display zero counts
         r += uc[i] + " (" + a.charAt(i) + ")";
         r +=  f( String(cnt[i]), 5);
         p =  String(Math.round(cnt[i]/rc * 1000)/10);
         if (p.indexOf(".") == -1) p += ".0"; // assure 1 decimal place format
         r +=  f( p + "%", 7);
         r += "\n"; // new line
       }
       r += "</pre>";
       r += nl;

       r += "--- Sequence Attributes --------------------------"+nl;

       /*** Molecular Weight
        * Add MW of all residues then (minus water) then add 18
        * notes:  - (m.w. of H20 = 18).
        *         - the last residue in the string has not lost water so
        *           you need to add 1 water
       **/
       var mw = 0;
       for (var i=0; i<26; i++) mw += (cnt[i] * m_wt2[i]);
       if (mw) mw += 18;
       r += "Molecular Weight = " + String ( Math.round(mw*10)/10 );
       r += nl;

       /*** Extinction Coefficient ***/
       var extinct_cof = 5690 * cnt[ a.indexOf("W")] +
                         1280 * cnt[ a.indexOf("Y")] +
                           60 * cnt[ a.indexOf("C")];
       r += "Extinction Coefficient (280 nm) = " + String ( extinct_cof );
       r += nl;

       /*** Estimated Extinction Coefficient (A280 nm 0.1%) ***/
       if ( mw ) // guard against divide by zero
       {
         r += "Estimated Extinction Coefficient (A280 nm 0.1%) = ";
         r += f2( String( Math.round(extinct_cof/mw*1000)/1000 ) );
         r += nl;
       }

       /*** put resultant to output device ***/

//       document.extCoefCalc.tarSeq.value =  r;

// http://www.xs4all.nl/~ppk/js/browsers.html cross browser help
       if ( w1 ) if ( !w1.closed ) w1.close();
       w1 = window.open('about:blank','mwCalc','resizable,scrollbars');
       o = w1.document; // write object
       o.open();
       o.writeln('<HTML><HEAD><TITLE>Extinction Coefficient Calculator Results</TITLE>');
       o.writeln('</HEAD>');
       o.writeln('<BODY text="black" bgcolor="white">');
       o.writeln( r );
       o.writeln('</BODY></HTML>');
       o.close();
    }



/*
Calculator
    others
    http://www.douze.net/calcul.php
*/
var display_value = new String('                  ');
var stack = new String('');
var operator = new String('');
var pointer = 0;
var decimal = '';
var digits=18;

function calculator(pressed)
{
  if ( pressed == 'clal' ) {
    pointer=0;
    decimal = '';
    display_value = '                  ';
    stack = '';
  }
  else if ( pressed == 'clen' ) {
    pointer=0;
    decimal = '';
    display_value = '                  ';
  }
  else if ( pressed == 'back' ) {
    if ( pointer > 0 ) {
      pointer=pointer-1;
      if ( display_value.substring(digits-1,digits) == '.' ) { decimal = ''; }
      display_value = ' '+display_value.substring(0,digits-1);
    }
  }
  else if ( pressed == 'plus' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        stack = Math.pow(stack,display_value).toString(); }
      else {
        stack = eval(stack+operator+display_value).toString();
      }
      operator = '+'; }
    else {
      operator = '+';
      stack = display_value;
    }
    pointer=0;
    decimal = '';
    display_value = stack;
  }
  else if ( pressed == 'mins' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        stack = Math.pow(stack,display_value).toString(); }
      else {
        stack = eval(stack+operator+display_value).toString();
      }
      operator = '-'; }
    else {
      operator = '-';
      stack = display_value;
    }
    pointer=0;
    decimal = '';
    display_value = stack;
  }
  else if ( pressed == 'mult' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        stack = Math.pow(stack,display_value).toString(); }
      else {
        stack = eval(stack+operator+display_value).toString();
      }
      operator = '*'; }
    else {
      operator = '*';
      stack = display_value;
    }
    pointer=0;
    decimal = '';
    display_value = stack;
  }
  else if ( pressed == 'divd' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        stack = Math.pow(stack,display_value).toString(); }
      else {
        stack = eval(stack+operator+display_value).toString();
      }
      operator = '/'; }
    else {
      operator = '/';
      stack = display_value;
    }
    pointer=0;
    decimal = '';
    display_value = stack;
  }
  else if ( pressed == 'powr' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        stack = Math.pow(stack,display_value).toString(); }
      else {
        stack = eval(stack+operator+display_value).toString();
      }
      operator = 'powr'; }
    else {
      operator = 'powr';
      stack = display_value;
    }
    pointer=0;
    decimal = '';
    display_value = stack;
  }
  else if ( pressed == 'plmn' ) {
    display_value = eval('-1*'+display_value).toString();
  }
  else if ( pressed == 'sqrt' ) {
    display_value = Math.sqrt(parseFloat(display_value)).toString();
    pointer=0;
    decimal = '';
  }
  else if ( pressed == 'sqrd' ) {
    display_value = eval(display_value+'*'+display_value).toString();
    pointer=0;
    decimal = '';
  }
  else if ( pressed == 'recp' ) {
    display_value = eval('1.0/'+display_value).toString();
    pointer=0;
    decimal = '';
  }
  else if ( pressed == 'pi' ) {
    display_value = Math.PI.toString();
    pointer=0;
    decimal = '';
  }
  else if ( pressed == 'equl' ) {
    if ( stack ) {
      if ( operator == 'powr' ) {
        display_value = Math.pow(stack,display_value).toString(); }
      else {
        display_value = eval(stack+operator+display_value).toString();
      }
      pointer = 0;
      stack = '';
    }
  }
  else if ( pressed == 'deci' && !decimal && pointer < digits ) {
    if ( pointer == 0 ) { display_value = '                  '; }
    pointer=pointer+1;
    decimal = '1';
    display_value = display_value.substring(1,digits)+'.';
  }
  else if ( pressed.substring(0,3) == 'key' && pointer < digits ) {
    if ( pointer == 0 ) { display_value = '                  '; }
    pointer=pointer+1;
    if ( pressed == 'key0' ) {
      display_value = display_value.substring(1,digits)+'0'; }
    else if ( pressed == 'key1' ) {
      display_value = display_value.substring(1,digits)+'1'; }
    else if ( pressed == 'key2' ) {
      display_value = display_value.substring(1,digits)+'2'; }
    else if ( pressed == 'key3' ) {
      display_value = display_value.substring(1,digits)+'3'; }
    else if ( pressed == 'key4' ) {
      display_value = display_value.substring(1,digits)+'4'; }
    else if ( pressed == 'key5' ) {
      display_value = display_value.substring(1,digits)+'5'; }
    else if ( pressed == 'key6' ) {
      display_value = display_value.substring(1,digits)+'6'; }
    else if ( pressed == 'key7' ) {
      display_value = display_value.substring(1,digits)+'7'; }
    else if ( pressed == 'key8' ) {
      display_value = display_value.substring(1,digits)+'8'; }
    else if ( pressed == 'key9' ) {
      display_value = display_value.substring(1,digits)+'9'; }
  }

  while ( display_value.length < digits ) display_value = ' '+display_value;
  document.allVars.display.value = display_value;
}
