//joseanpg.net
//2009-04-28
//En preparación

(function (){

   var text, index, explorer, list;

   var regexBeginOfStringCommentRegex = /["']|\/\/|\/\*|\//g;

   function split(t) {
      text  = t;
      list  = [];
      index = 0;
      explorer = 0;
      for(;;){
        regexBeginOfStringCommentRegex.lastIndex = explorer;
        var result = regexBeginOfStringCommentRegex.exec(text);
        if (result) {
          explorer = regexBeginOfStringCommentRegex.lastIndex;
          hunters[result[0]]();
        }
        else {
          break;
        }
      }
      list.push(['code',text.slice(index)]);
      return list;
   };

   var hunters = {
      '\'' : getString1,
      '"'  : getString2,
      '//' : getComment1,
      '/*' : getComment2,
      '/'  : getRegex
   };

   var regexGetString1  = /(?:[^'\\]|\\.)*'/g,
       regexGetString2  = /(?:[^"\\]|\\.)*"/g,
       regexGetComment1 = /.*$/gm;

   function get(regex,type,tam) {
     regex.lastIndex = explorer;
     var result = regex.exec(text);
     if (result) {
        explorer = explorer - tam;
        var nextIndex = regex.lastIndex;
        list.push(['code',text.slice(index,explorer)]);
        list.push([type,text.slice(explorer,nextIndex)]);
        index    = nextIndex;
        explorer = index;
     }
     else {
       throw new Error('Error:'+type);
     }
   };

   function getString1()  {get(regexGetString1, 'string',1);};
   function getString2()  {get(regexGetString2, 'string',1);};
   function getComment1() {get(regexGetComment1,'comment',2);};

   var regexBeginEndComment2 = /\*\/|\/\*/g;
   function getComment2(){
     regexBeginEndComment2.lastIndex = explorer;
     var level = 1;
     for (;;) {
       var result = regexBeginEndComment2.exec(text);
       if (result) {
         level += (result[0]==='*/')? -1:1;
         if (level == 0) {
           explorer = explorer - 2;
           var nextIndex = regexBeginEndComment2.lastIndex;
           list.push(['code',text.slice(index,explorer)]);
           list.push(['comment',text.slice(explorer,nextIndex)]);
           index = nextIndex;
           explorer = index;
           return;
         }
       }
       else {
         throw new Error('Error: demasiados /*');
       }
     }
   };

   var regexRegex = /(?:[^\\\/]|\\.)*\/[gim]*/g;
   function getRegex(){
     var i=explorer-2;
     while (i>=index) {
       var c = text.charAt(i);
       if (/\s/.test(c)) i--;
       else break;
     }
     if (i===index || ';\n\r(='.indexOf(text.charAt(i))>-1) {
       regexRegex.lastIndex = explorer;
       var result = regexRegex.exec(text);
       if (result) {
         explorer = explorer - 1;
         var nextIndex = regexRegex.lastIndex;
         list.push(['code',text.slice(index,explorer)]);
         list.push(['regex',text.slice(explorer,nextIndex)]);
         index = nextIndex;
         explorer = index;
       }
       //else: explorer index no se modifican. explorer != index     
     }
     //else: explorer index no se modifican. explorer != index     
   };

//----------------------------------------------------------------

/*
  var regexNewline = /\n/g;

  function numberOfLines(s) {
    var r = s.match(regexNewline);
    return r.length;

  }
*/
//----------------------------------------------------------------

   var regexKeywords    = /\b(break|else|new|var|case|finally|return|void|catch|for|switch|while|continue|function|this|with|default|if|throw|delete|in|try|do|instanceof|typeof)\b/g;
   var regexBrackets    = /([(){}[\]])/g;
   //var regexProperties1  = /(\.[_a-zA-Z][\w]*)/g;
   //var regexProperties2  = /(\b[_a-zA-Z]\w*\s*:)/g;


   window.format = function(text) {
      var list = split(text);
      result = '';
      for (var j=0, len = list.length;j<len;j++) {
        var type = list[j][0];
        var frag = list[j][1];
        //frag = frag.replace(/&/g,'&amp;').replace(/</g,'&lt;');
        frag = frag.replace(/\u0020/g,'&nbsp;');//Evil IE
        frag = frag.replace(/\t/g,'&nbsp;&nbsp;&nbsp;&nbsp;');
        frag = frag.replace(/\n/g,'<br>');//Evil IE
        if ('code' === type) {
           result += frag.replace(regexKeywords,'<span class="keyword">$1</span>')
                         .replace(regexBrackets,'<span class="bracket">$1</span>')
                         //.replace(regexProperties1,'<span class="property">$1</span>')
                         //.replace(regexProperties2,'<span class="property">$1</span>');
        }
        else {
           result += '<span class="'+type+'">'+frag+'</span>';
        }
      }
      return result;
   };


  window.magic = function() {
     var pres = document.getElementsByTagName('PRE');
     for (var j=0, len=pres.length; j<len; j++) {
       var pre     = pres[j];
       pre.innerHTML = format(pre.innerHTML);
/*
       var preText = pre.innerHTML;
       var forText = format(preText);
       var n       = numberOfLines(preText);
       var x = [];
       for (var j = 1 ;j<=n;j++) {
         x.push(j);x.push('.<br>');
       }
       x = x.join('');
       pre.style.display = 'none';
       var div0 = pre.parentNode.insertBefore(document.createElement('TABLE'),pre);
       div0.innerHTML = '<tbody style="background:#e0d0d0"><tr><td style="text-align:right">'+x+'</td><td>'+forText+'</td></tr></tbody></table>';
*/
     }

     styleText = 
     'pre {font-family:verdana, monospace;font-size:14px;padding:32px;border:1px solid black}'+
     'span.string  {color:#700;}'+
     'span.comment {color:#aaa;}'+
     'span.regex   {color:#0aa;}'+
     'span.keyword {color:#02a;font-weight:bold}'+
     'span.bracket {color:blue;font-weight:200}'+
     'span.property {color:#aa0;font-style:italic}';


     var style = document.createElement('STYLE');
     style.appendChild(document.createTextNode(styleText));
     document.documentElement.firstChild.appendChild(style);



  };



})();