
/**
 *  timeloop.js -> executa um loop com um tempo de espera entre as voltas
 *  -------------------------
 *  Autor: Cau Guanabara
 *  Email: caugb@ibest.com.br
 *  Data:  2005-11-07
 *  -------------------------

   Referência
	 ----------
	 
   timeLoop(string LOOP_STR, string COMMAND, integer DELAY [, string END_COMMAND])
   
   Parâmetros
   ----------
   LOOP_STR -> string contendo os parâmetros para o loop, como se fosse para um FOR,
               com algumas restrições. A string, deve conter 3 partes, divididas por ';'.
               1ª parte (inicialização da variável): 'nome_var = valor_numérico'
               2ª parte (condição para o loop): 'nome_var [< , > , <= ou >=] valor_numérico'
               3ª parte (incremento/decremento - há 3 possibilidades):
                    a. 'nome_var++' ou 'nome_var--'
									  b. 'nome_var += valor_numérico' ou 'nome_var -= valor_numérico'
                    c. 'nome_var = nome_var [+ ou -] valor_numérico'
						
							 Exemplos válidos
							 ----------------
							 'i = 0; i <= 11; i++' , 'inc = 90; inc > 50; inc -= 2' ou 'x = 100; x >= 0; x = x - 5'
						
   COMMAND -> string contendo os comandos a serem executados em cada volta do loop.
   DELAY -> intervalo de tempo (em milisegundos) entre as voltas e após o término do loop.
	 END_COMMAND -> string contendo os comandos a serem executados ao final do loop. Esse 
	                parâmetro é fundamental se queremos executar algo quando o loop terminar. 
									Se timeLoop for chamada e na sequência chamarmos outra função, ela será 
									executada no meio do loop, não no fim. Resolva isso criando uma função para 
									continuar o processamento e mande uma chamada para ela como o 4º parâmetro.

*/

function timeLoop(loopstr,cmd,delay,doatend) {
this.cmd = cmd;
this.delay = delay;
this.endCmd = doatend;
this.tout = null;
this.parseStr = tl_parseStr;
this.proceed = tl_proceed;
this.execute = tl_execute;
  if(this.parseStr(loopstr)) {
    this.loopFunction = new Function(this.cmd);
    this.execute();
  }
}

function tl_parseStr(loopstr) {
var arr = loopstr.split(/\s*;\s*/);
  if(arr.length != 3) return false; 
	
	if(/^([$a-zA-Z_][$\w]*)\s*=\s*(\-?\d+)$/.test(arr[0])) {
	this.varname = RegExp.$1; this.iniloop = parseInt(RegExp.$2);
	} else return false;
	
	if(/^[$a-zA-Z_][$\w]*\s*([<>]=?)\s*(\-?\d+)$/.test(arr[1])) {
	this.operator = RegExp.$1; this.endloop = parseInt(RegExp.$2); 
	} else return false;
	
  if(/((\+)\+|(\-)\-)/.test(arr[2])) {
	this.increment = parseInt((RegExp.$1 == '-' ? '-' : '')+'1'); 
	} else if(/^(.+(\+|\-)=\s*(\d+)|[$\w]+\s*=\s*[$\w]+\s*(\+|\-)\s*(\d+))$/.test(arr[2])) {
  this.increment = parseInt((RegExp.$2 == '-' ? '-' : '')+RegExp.$3);
  } else return false;

eval(this.varname+' = '+this.iniloop+';');
return true;
}

function tl_proceed() { 
eval("var ret = ("+this.iniloop + this.operator + this.endloop+");"); 
return ret;
}

function tl_execute() {
	if(this.tout) clearTimeout(this.tout);
  if(this.proceed()) {
  this.loopFunction();
  this.iniloop += this.increment;
  eval(this.varname+' = '+this.iniloop+';');
  this.tout = setTimeout('this.execute()', this.delay);
  } else eval(this.endCmd);
}
