/*
Copyright (C) 2003-2005  Teleferique Collective


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.

*/



// Interpreteur de textes avec temporisation
//
// Deroule la chaine source dans un formulaire (textarea) 
// en modulant la vitesse d'affichage en fonction de balises 
// entre crochets [] incluses dans le texte.
//
// pour la syntaxe -> http:// ... 

// ------------------------------------------------------------------
 
// pour désactiver nibble: nibble=0
var nibble=0;
var source = "";
var replic;

var lsrc;
var possrc;
var posout;
var posouthead;

var now;

var starttimeout;

tagstart="[";
tagend="]";
tagparam="/";
tagescape="\\";



function DEFMODE(tag,trig0,trig1,notrig){
  this.activ=false;
  this.reactiv=false;
  this.tag=tag;
  this.trig0=trig0;
  this.trig1=trig1;
  this.notrig=notrig;
  this.duration=0;
  this.func="";
  this.phase=0;
  this.nparams=0;
  this.params=new Array();
}

defmode=new Array();
defmode[0]=new DEFMODE("c","","","");
defmode[1]=new DEFMODE("p","","","");
defmode[2]=new DEFMODE("w",""," "," ");
defmode[3]=new DEFMODE("l","","\n","");
defmode[4]=new DEFMODE("b",".:?!","","");
defmode[5]=new DEFMODE("s",".:?!,;()","","");

var maxmode=defmode.length;

function FUNCS(tag,f){
  this.tag=tag;
  this.f=f;
}

var funcs=new Array();


funcs[0]=new FUNCS('S',  'if (defmode[funcmod].nparams>=3){\n'+

  '  s=Math.sin(2.0*Math.PI*now/defmode[funcmod].params[2]);\n'+

  '  defmode[funcmod].duration=s*defmode[funcmod].params[1]+defmode[funcmod].params[0];\n'+

  '}' );



funcs[1]=new FUNCS('R',   'if (defmode[funcmod].nparams>=2){\n'+

  '  r=Math.random()*2.0-1.0;\n'+

  '  defmode[funcmod].duration=r*defmode[funcmod].params[1]+defmode[funcmod].params[0];\n'+

  '}' );



funcs[2]=new FUNCS('E',   'if (defmode[funcmod].nparams>=2){\n'+

  '  r=Math.random()*2.0-1.0;\n'+

  '  defmode[funcmod].duration=defmode[funcmod].params[defmode[funcmod].phase++%defmode[funcmod].nparams];\n'+

  '}' );



var maxfunc=funcs.length;





function parsetag() {

  var modabout=-1;

  var funcabout=-1;

  var charnow;

  var strvalue="";

  var m,f;

  var newmod=0;





  for (m=0;m<maxmode;m++)

    defmode[m].reactiv=false;



  do{ 

    possrc++;

    charnow=source.charAt(possrc);

      if (charnow>="0" && charnow<="9")

        strvalue+=charnow;

      else{

        if (modabout>=0 && modabout<maxmode){

          if (funcabout>=0 && funcabout<maxfunc){

            if (strvalue.length){

              v=parseInt(strvalue);

              defmode[modabout].params[defmode[modabout].nparams]=v;

            }

            defmode[modabout].nparams++;

            strvalue="";

          }

          else{

            if (strvalue.length){

              v=parseInt(strvalue);

              defmode[modabout].duration=v;

              defmode[modabout].params[0]=v;

            }

            defmode[modabout].nparams=1;

            strvalue="";

          }

        }

        

        for (m=0;m<maxmode;m++)

          if (charnow==defmode[m].tag){

            modabout=m;

            defmode[m].reactiv=true;

            if (m!=1) newmod=1;

            funcabout=-1;

            defmode[m].nparams=0;

            defmode[m].func="";

            break;

          }



        for (f=0;f<maxfunc;f++)

          if (charnow==funcs[f].tag){

            funcabout=f;

            if (modabout>=0 && modabout<maxmode)

              defmode[modabout].func=funcs[f].f;

            break;

          }

      }

  } while( charnow!=tagend )





  for (m=0;m<maxmode;m++)

    defmode[m].activ = defmode[m].reactiv  ||  !newmod && defmode[m].activ ;





  possrc++;



}



function calc_mod_time(m){

  if (defmode[m].func.length){

    funcmod=m;

    eval(defmode[m].func);

  }

  return defmode[m].duration;

}



function condchar(chr,m,pat,nopat){



  nnotoken=nopat.length;

  if (nnotoken>0){

    for (t=0;t<nnotoken;t++){

      if (chr==nopat.charAt(t))

        return false;

    }

  }



  ntoken=pat.length;

  if (ntoken==0)

    return true;

  else{

    for (t=0;t<ntoken;t++){

      if (chr==pat.charAt(t))

        return true;

    }

  }



  return false;

}



function calc_tot_time(chr0,chr1){

  var p=0;



  for (m=0;m<maxmode;m++){

    if (defmode[m].activ 

         && condchar(chr0,m,defmode[m].trig0,defmode[m].notrig) 

         && condchar(chr1,m,defmode[m].trig1,"") ){

      p+=calc_mod_time(m);

    }

  }



  if (defmode[1].activ)

    defmode[1].activ=false;



  if (p<0)

    p=0;

  return p;

}



var charlast;

var charnow;



function play() {

  var pausetotal;



  do {



    replic+=charnow;

    posout++;



    charlast=charnow;

    

    while (true){

      charnow=source.charAt(possrc);

      if (charnow!=tagstart)

        break;

      parsetag();

    }

    

    pausetotal=calc_tot_time(charlast,charnow);



    possrc++;

  }

  while (pausetotal==0 && possrc<=lsrc);
    
  document.interf.txtout.value=replic.substring(posouthead,posout);

  scrollTextarea();

/*
    if (navigator.appName == 'Microsoft Internet Explorer' && navigator.appVersion.indexOf('Mac') == -1){

        var the_text = document.interf.txtout.createTextRange();

        the_text.scrollIntoView(false); 

    }


    if (navigator.appName == 'Netscape'){

      //document.interf.txtout.select();
 
      //document.interf.txtout.value = document.interf.txtout.value;

      //document.interf.txtout.blur();

    }
*/


  if(possrc<=lsrc){

    now+=pausetotal;

    lasttimeout=setTimeout("play()", pausetotal);  //faire une pause

  }


  //BOUCLER ICI

  if (possrc>lsrc)

    //alert('ok');
    ended();

}



function reset(){

  replic="";

  lsrc=source.length;;

  possrc=0;

  posout=0;

  posouthead=0;

  now=0;

  charlast="";

  charnow="";

  document.interf.txtout.value="";


}



// API (Application Programming Interface)
function ended(){
  clearTimeout(lasttimeout);
  starttimeout=setTimeout("start()",1000);
}

function stop(){
  clearTimeout(lasttimeout);
  clearTimeout(starttimeout);
}

function start(){
  reset();
  play();
}

function restart(){   
  play(); // old  
}

function recorder(){
  var i=0;
  tempo = document.code.personnal.value;

    while(i<tempo.length) {
      source += '[c'+timer[i]+']'+tempo.charAt(i);
      i++;
    }

  start();
}

function ressource(){
  document.code.personnal.value=source;
}
  /**************************************
    Record keyboard typing velocity
  **************************************/

  var tempo = "";
  var t = 0;
  var now = new Date();
  var timer= new Array();
  var starttime = now.getTime();

  function record(){
    now2 = new Date();
    totaltime = now2.getTime() - starttime;
    starttime = starttime+totaltime;
    timer[t] = totaltime/2;
    t++;
  }

function ressource(){
  document.code.personnal.value=source;
}

  /************************************
   add tag to code textarea
  ************************************/

function addtxt(tag) {
        var newmessage;
        var lastmsg = document.code.personnal.value;
        newmessage = lastmsg+tag;
        document.code.personnal.value=newmessage;
        return;
        }


function editor(){
  source=document.code.personnal.value;
  //replace('[',source,'(');
  
  //replace (']',source,')');

  start();

  //alert(source);

}

function clean(){
    document.code.personnal.value="";
}



  /************************************************
    SCROLL TEXTAREA CROSS-BROWSER 
  ************************************************/

function scrollTextarea(){
var obj=document.forms.interf.elements.txtout; 
var gradual=false; // true to scroll slowly, false to jump 
obj.focus(); 
  if (document.layers){
    obj.select(); 
    obj.blur(); 
  } 
  else if (gradual){
    var top=-1 
  while (top<obj.scrollTop){
    top=obj.scrollTop++;} 
  } 
  else {
    obj.scrollTop=obj.scrollHeight-obj.offsetHeight;
  } 
} 
  /************************************************
   show / hide elements
  ************************************************/
function hideshow(item) {
	if (document.getElementById(item).style.display=="none") document.getElementById(item).style.display="block"; 
														else document.getElementById(item).style.display="none"; 
}


