
/***************************************************************************
*   Copyright (C) 2006, Paul Lutus                                        *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/

function jsHandleError(e,f,ln) // error, file, line
{
   document.myForm.output.value = "JavaScript Error: " + e + " (" + ln + ")";
   return true;
}

window.onerror = jsHandleError; // tell javaScript about error handler

var input;
var program;

var jsTabString = "    "; // default: 4 spaces

var jsResult;

function print(x)
{
   jsResult += x;
}

var indentParen;
var indentBrace;
var indentBracket;

function jsTestIndent(x,indent)
{
   for(var i = 0;i < x.length;i++) {
      var c = x.substr(i,1);
      switch(c) {
         case ("("):
         {
            indentParen++;
            indent++;
            break;
         }
         case (")"):
         {
            indentParen--;
            indent--;
            break;
         }
         case ("["):
         {
            indentBracket++;
            indent++;
            break;
         }
         case("]"):
         {
            indentBracket--;
            indent--;
            break;
         }
      }
   }
   return indent;
}

function addDelim(src,index,gt,lt)
{
   while(index < 0) {
      src += lt;
      index++;
   }
   while(index > 0) {
      src += gt;
      index--;
   }
   return src;
}

function jsBeautify()
{
   indentParen = 0;
   indentBracket = 0;
   indentBrace = 0;
   var s = document.myForm.editArea.value;
   var sa = s.split("\r\n");
   var indent = 0;
   var r = "";
   for(var i = 0;i < sa.length;i++) {
      while((sa[i].length > 0) && (sa[i].substr(0,1) <= 32)) {
         sa[i] = sa[i].substr(1);
      }
      indent = jsTestIndent(sa[i],indent);
      if(sa[i].indexOf("}") != -1) {
         indentBrace--;
         indent--;
      }
      var si = "";
      for(var j = 0;j < indent;j++) {
         si += jsTabString;
      }
      if(sa[i].indexOf("{") != -1) {
         indentBrace++;
         indent++;
      }
      r += si + sa[i] + "\r\n";
   }
   r = r.substring(0,r.length-2); // fixes a stupid bug
   document.myForm.editArea.value = r;
   if((indentBracket == 0) && (indentBrace == 0) && (indentParen == 0)) {
      document.myForm.beautifyResults.value = "No beautify errors.";
   }
   else {
      var item = "";
      item = addDelim(item,indentBracket,"[","]");
      item = addDelim(item,indentBrace,"{","}");
      item = addDelim(item,indentParen,"(",")");
      document.myForm.beautifyResults.value = "Error: excess \"" + item + "\"";
   }
   return true;
}

function jsProcess()
{
   input = document.myForm.input.value;
   program = document.myForm.editArea.value;
   jsResult = "";
   eval(program);
   main();
   document.myForm.output.value = jsResult;
   return true;
}

function jsTestInstant()
{
   if(document.myForm.instant.checked) {
      jsProcess();
   }
   return true;
}

// this is used more than once, so make a constant out of it

var srchRplcRoutine = "// in string \"src\", for each string \"a\", replace with string \"b\"\n\nfunction searchReplace(src,a,b)\n{\nvar dest = \"\";\nif(a.length > 0) { // this must be true for the routine to stop\nwhile ((i = src.indexOf(a)) != -1) { // each time \"a\" is found,\ndest += src.substring(0,i) + b; // replace \"a\" with \"b\",\nsrc = src.substring(i + a.length); // then skip over \"a\" in \"src\".\n}\ndest += src; // finally, capture any remaining characters\n}\nelse { // return the original string\ndest = src;\n}\nreturn(dest);\n}\n";

// entries: "code|optional: string for input window|optional: any char to set "run on each keystroke" mode

var scenarioSet = new Array(
   "// Simple \"Hello World\" program\n\nfunction main()\n{\nprint(\"Hello World!\");\n}\n",
   "// Math + loop structure example\n\nfunction main()\n{\nfor(var i = 1;i <= 10;i++) {\nprint(\"The square root of \" + i + \" is \" + Math.sqrt(i) + \"\\n\");\n}\n}\n",
   "// Character numbers example\n\nfunction main()\n{\nfor(var c = 32;c < 256;c++) {\nprint(\"Character \" + c + \" is \" + String.fromCharCode(c) + \"\\n\");\n}\n}\n",
   "// Parse text example\n\nfunction main()\n{\nvar sa = input.split(\" \");\nfor(var i = 0;i < sa.length;i++) {\nprint(\"[\" + sa[i] + \"]\\r\\n\");\n}\n}|this is my test sentence",
   "// Reverse text example\n\nfunction main()\n{\nvar sa = input.split(\" \");\nfor(var i = sa.length-1;i >= 0;i--) {\nprint(sa[i] + \" \");\n}\n}|this is my test sentence",
   "// Examine the window.document object\n\nfunction main()\n{\nvar x = window.document;\nfor(n in x) {\nprint(\"window.document.\" + n + \" \\t\\t= \" + x[n] + \"\\n\");\n}\n}\n",
   "// Examine the window.navigator object\n\nfunction main()\n{\nvar x = window.navigator;\nfor(n in x) {\nprint(\"window.navigator.\" + n + \" \\t\\t= \" + x[n] + \"\\n\");\n}\n}\n",
   "// Global search & replace example using search subroutine\n\nfunction main()\n{\nvar result = searchReplace(input,\"poem\",\"song\");\nresult = searchReplace(result,\"bad\",\"good\");\nprint(result);\n}\n\n" + srchRplcRoutine + "|I feel so bad\nI think I'll write a poem\nany poem\nthis poem.\n",
   "// Another global search & replace example -- just for fun!\n// Replace the word \"chipmunk\" below with anything that comes into your head.\n\nvar replace = \"chipmunk\";\n\nfunction main()\n{\nvar result = searchReplace(input,\"x\",replace);\nprint(result);\n}\n\n" + srchRplcRoutine + "|Those nasty xs -- we should get rid of them and their x offspring, too. Those xs are taking over everywhere, leaving x notions and x detritus for all of us non-xs to put up with. Let's deport all those xs back to wherever they came from!\n\n(isn't it fun being completely stupid?)|x",
   "// Enter a number in the \"input\" window\n\nfunction main()\n{\nvar n = parseFloat(input);\nprint(\"\" + n)\n}\n|1e400|x",
   "// Enter pretty much anything in the \"input\" window\n\nfunction main()\n{\nvar n = eval(input);\nprint(\"\" + n)\n}\n|80/81|x",
   "// Regular Expressions\r\n\r\nfunction main()\r\n{\r\n    var re = /(\\w+)(\\s+)(\\w+)/;\r\n    var out = input.match(re);\r\n    for(i = 0;i < out.length;i++) {\r\n        print(i + \" = [\" + out[i] + \"]\\n\");\r\n    }\r\n}|Alpha Beta",
   "// Have fun!\n\nfunction main()\n{\n\n}\n",
   ""
);

function jsChooseScenario(x)
{
   var sa = scenarioSet[x].split("|");
   document.myForm.editArea.value = sa[0];
   if("" + sa[1] == "undefined") {
      sa[1] = "";
   }
   document.myForm.instant.checked = ("" + sa[2] != "undefined");
   document.myForm.input.value = sa[1];
   jsBeautify();
   jsProcess();
   return true;
}

function jsInit()
{
   jsChooseScenario(0);
   return true;
}

