/* rot13.js
   Copyright © Richard Sabey 2003. All rights reserved.
   Last updated 8 November 2003.

   The regexp and charcode algorithm of rot13r might seem to be a
   perverse method, not least because the only kind of search I need is
   for a single character, and searching for a regexp seems to be needlessly
   complex. However, this algo is actually quicker than more straighforward
   methods I tried.

   Here are my timings. Accuracy of timing is limited by my reaction time
   and capacity to operate my stopwatch.

           Input file size:      ====100kB=== ===30kB=== =======10kB=======
   funct   Algorithm              IE6  Netsc7 IE5 Netsc7 IE5  Netsc7 Opera7
   rot13r  regexp & charcode      1.4s   6.6s <1s     2s  <1s    <1s    28s
   rot13a  result = result + char  65s    16s  5s     5s 1.4s   1.9s   5.5s
   rot13p  result = char + result  78s 2m 22s  5s    18s 1.4s   4.1s     5s
           Bill Martin's                      34s 1m 45s  10s    35s    38s
           Lagmonster's           3.6s                        

   In all cases the app ran on a Windows 98 PC with a Pentium III processor
   clocked at 500MHz.

   I find it hard to believe that building an n-character string one character
   at a time is an O(n*n) operation. Perhaps it is (even if finding the end of
   a string is O(1)), because a new String() is constructed every time.

   That isn't the whole story, though. Note that IE5 takes about the same
   time to build a string one character at a time, whether by appending or
   prepending. By contrast, Netscape7 does much better than IE5 when appending,
   and much worse than IE5 when prepending. Perhaps Netscape has some
   optimisation for string append (at any rate when the added string is short).

   Opera 7, though, what can I say. I am disappointed. I guess that Opera's
   implementation of String.replace is woeful compared to IE's or Netscape's.

   Because Opera 7 is so hopelessly slow at rot13r, I supply rot13a which
   implements the "appending" algorithm.

   Bill Martin's e-mail address is sscripts@simple-scripts.net. Simple
   isn't necessarily best.
*/

/* Do rot13 in situ by appending to a string one character at a time. */
function rot13a(that) {
 var s=that.value, l=s.length, r='';
 coa = "a".charCodeAt(0);
 com = "m".charCodeAt(0);
 coz = "z".charCodeAt(0);
 for(j=0; j< l; j++) {
  c = s.substr(j,1);
  colcc = c.toLowerCase().charCodeAt(0);
  if(colcc>=coa && colcc<=com)
   r += String.fromCharCode(s.charCodeAt(j)+13);
  else if(colcc>com && colcc<=coz)
   r += String.fromCharCode(s.charCodeAt(j)-13);
  else
   r += c;
 }
 that.value=r;
}

/* Do rot1 in situ by appending to a string one character at a time. */
function rot1a(that) {
 var s=that.value, l=s.length, r='';
 coa = "a".charCodeAt(0);
 coy = "y".charCodeAt(0);
 coz = "z".charCodeAt(0);
 for(j=0; j< l; j++) {
  c = s.substr(j,1);
  colcc = c.toLowerCase().charCodeAt(0);
  if(colcc>=coa && colcc<=coy)
   r += String.fromCharCode(s.charCodeAt(j)+1);
  else if(colcc==coz)
   r += String.fromCharCode(s.charCodeAt(j)-25);
  else
   r += c;
 }
 that.value=r;
}

function rot25a(that) {
 var s=that.value, l=s.length, r='';
 coa = "a".charCodeAt(0);
 coz = "z".charCodeAt(0);
 for(j=0; j< l; j++) {
  c = s.substr(j,1);
  colcc = c.toLowerCase().charCodeAt(0);
  if(colcc==coa)
   r += String.fromCharCode(s.charCodeAt(j)+25);
  else if(colcc>coa && colcc<=coz)
   r += String.fromCharCode(s.charCodeAt(j)-1);
  else
   r += c;
 }
 that.value=r;
}


/* Do rot13 by prepending to a string one character at a time. */
function rot13p(that) {
 var s=that.value, l=s.length, r='';
 coa = "a".charCodeAt(0);
 com = "m".charCodeAt(0);
 coz = "z".charCodeAt(0);
 for(j=l-1; j>=0; j--) {
  c = s.substr(j,1);
  colcc = c.toLowerCase().charCodeAt(0);
  if(colcc>=coa && colcc<=com)
   r = String.fromCharCode(s.charCodeAt(j)+13) + r;
  else if(colcc>com && colcc<=coz)
   r = String.fromCharCode(s.charCodeAt(j)-13) + r;
  else
   r = c + r;
 }
 that.value=r;
}

/* Do rot13 by global-replacing one letter at a time.

   This algorithm rot13s by going through the pairs of characters that rot13
   to each other. Take 'a' and 'n' for example. My algo globally replaces
   all the a's in the text area by n's, and vice versa. (This of course
   needs three operations. Ironically, rot13's useful property of being
   self-inverse is a liability here, in that it increases the number of
   global replaces by 50%.)
*/
function rot13r(that) {
 var a=that, b, x=String.fromCharCode(1), r=new RegExp(x, "g");
 b=a.replace(new RegExp("a","g"),x);a=b.replace(new RegExp("n","g"),"a");
 b=a.replace(r,"n");a=b.replace(new RegExp("A","g"),x);
 b=a.replace(new RegExp("N","g"),"A");a=b.replace(r,"N");
 b=a.replace(new RegExp("b","g"),x);a=b.replace(new RegExp("o","g"),"b");
 b=a.replace(r,"o");a=b.replace(new RegExp("B","g"),x);
 b=a.replace(new RegExp("O","g"),"B");a=b.replace(r,"O");
 b=a.replace(new RegExp("c","g"),x);a=b.replace(new RegExp("p","g"),"c");
 b=a.replace(r,"p");a=b.replace(new RegExp("C","g"),x);
 b=a.replace(new RegExp("P","g"),"C");a=b.replace(r,"P");
 b=a.replace(new RegExp("d","g"),x);a=b.replace(new RegExp("q","g"),"d");
 b=a.replace(r,"q");a=b.replace(new RegExp("D","g"),x);
 b=a.replace(new RegExp("Q","g"),"D");a=b.replace(r,"Q");
 b=a.replace(new RegExp("e","g"),x);a=b.replace(new RegExp("r","g"),"e");
 b=a.replace(r,"r");a=b.replace(new RegExp("E","g"),x);
 b=a.replace(new RegExp("R","g"),"E");a=b.replace(r,"R");
 b=a.replace(new RegExp("f","g"),x);a=b.replace(new RegExp("s","g"),"f");
 b=a.replace(r,"s");a=b.replace(new RegExp("F","g"),x);
 b=a.replace(new RegExp("S","g"),"F");a=b.replace(r,"S");
 b=a.replace(new RegExp("g","g"),x);a=b.replace(new RegExp("t","g"),"g");
 b=a.replace(r,"t");a=b.replace(new RegExp("G","g"),x);
 b=a.replace(new RegExp("T","g"),"G");a=b.replace(r,"T");
 b=a.replace(new RegExp("h","g"),x);a=b.replace(new RegExp("u","g"),"h");
 b=a.replace(r,"u");a=b.replace(new RegExp("H","g"),x);
 b=a.replace(new RegExp("U","g"),"H");a=b.replace(r,"U");
 b=a.replace(new RegExp("i","g"),x);a=b.replace(new RegExp("v","g"),"i");
 b=a.replace(r,"v");a=b.replace(new RegExp("I","g"),x);
 b=a.replace(new RegExp("V","g"),"I");a=b.replace(r,"V");
 b=a.replace(new RegExp("j","g"),x);a=b.replace(new RegExp("w","g"),"j");
 b=a.replace(r,"w");a=b.replace(new RegExp("J","g"),x);
 b=a.replace(new RegExp("W","g"),"J");a=b.replace(r,"W");
 b=a.replace(new RegExp("k","g"),x);a=b.replace(new RegExp("x","g"),"k");
 b=a.replace(r,"x");a=b.replace(new RegExp("K","g"),x);
 b=a.replace(new RegExp("X","g"),"K");a=b.replace(r,"X");
 b=a.replace(new RegExp("l","g"),x);a=b.replace(new RegExp("y","g"),"l");
 b=a.replace(r,"y");a=b.replace(new RegExp("L","g"),x);
 b=a.replace(new RegExp("Y","g"),"L");a=b.replace(r,"Y");
 b=a.replace(new RegExp("m","g"),x);a=b.replace(new RegExp("z","g"),"m");
 b=a.replace(r,"z");a=b.replace(new RegExp("M","g"),x);
 b=a.replace(new RegExp("Z","g"),"M");a=b.replace(r,"Z");

 return a;
 /*that.value=a;*/
}

function clear()
{
    document.forms[0].text1.value = "";
    document.forms[0].text2.value = "";
}
