var tms = new Array()
var winDim = {
  screenWidth:  function() { return window.screen.availWidth },
  screenHeight: function() { return window.screen.availHeight },
  offsetTop:    function() { return window.pageYOffset == null ? document.body.scrollTop : window.pageYOffset }
}

var mouseinfo = {
    mouse: {x: 0, y: 0},
    grab: {x: 0, y: 0},
    ori: {x: 0, y: 0},
    ele: {x: 0, y: 0},
    setOri: function(x,y) { 
        mouseinfo.ori.x = mouseinfo.ele.x = parseInt(x);
        mouseinfo.ori.y = mouseinfo.ele.y = parseInt(y); 
    },
    toString: function() {
        var str = '';
        for (var k in mouseinfo) {
            if (typeof mouseinfo[k] == 'object') {
                str += k + ": ";
                str += "X:" + mouseinfo[k].x + "; ";
                str += "Y:" + mouseinfo[k].y;
                str += "\n";
            }
        }
        return str;
            
    }
}

function byId(nodeID) {
  return (typeof nodeID == 'string') ? document.getElementById(nodeID) : nodeID;
}

function byName(nodeName, getArray) {
  if (typeof getArray == "undefined") 
    getArray = false;

  var node = document.getElementsByName(nodeName);
  if (getArray)
    return node;
  else
    return node[0];
}

function go(url) {
  window.location.href = url;
}

/**
 * Função de associação de multiplos eventos a objetos
 * addEvent(object: Object, event: String, handler: Function(e: Event): Boolean, [scope: Object = object]): Boolean
 * Adiciona uma função que será disparada quando ocorrer determinado evento no objeto.
 * @param {Object} o Objeto que receberá o listener
 * @param {String} e Nome do evento sem o prefixo "on" (click, mouseover, ...)
 * @param {Object} f Função que será chamada quando o evento ocorrer, será enviado como argumento
 *                   para esta função o objeto de evento, que além das propriedades normais, *sempre* irá conter:
 *                   - target: Objeto que gerou o evento
 *                   - key: Código do caractere em eventos de teclado
 *                   - stopPropagation: Método para evitar a propagação do evento
 *                   - preventDefault: Método para evitar que a ação default ocorra
 *                     O preventDefault pode ser emulado retornando "false" na função
 * @param {Object} s Escopo (quem o "this" irá referenciar dentro do handler) que será usado quando a função for chamada, o default
 *                   é o objeto no primeiro argumento
 *                   
 */
addEvent = function(o, e, f, s) {
  var r = o[r = "_" + (e = "on" + e)] = o[r] || (o[e] ? [[o[e], o]] : []), a, c, d;
  r[r.length] = [f, s || o], o[e] = function(e){
    try{
      (e = e || event).preventDefault || (e.preventDefault = function(){e.returnValue = false;});
      e.stopPropagation || (e.stopPropagation = function(){e.cancelBubble = true;});
      e.target || (e.target = e.srcElement || null);
      e.key = (e.which + 1 || e.keyCode + 1) - 1 || 0;
    }catch(f){}
    for(d = 1, f = r.length; f; r[--f] && (a = r[f][0], o = r[f][1], a.call ? c = a.call(o, e) : (o._ = a, c = o._(e), o._ = null), d &= c !== false));
    return e = null, !!d;
    }
}
  
/**
 * Função de desassociação de múltiplos eventos a objetos
 * removeEvent(object: Object, event: String, handler: function(e: Event): Boolean, [scope: Object = object]): Boolean
 * Remove um listener previamente adicionado em um objeto e retorna true em caso de sucesso.
 * @param {Object} o Objeto que recebeu o listener
 * @param {String} e Nome do evento sem o prefixo "on" (click, mouseover, ...)
 * @param {Object} f Mesma função que foi atribuida no addEvent
 * @param {Object} s Escopo em que a função foi adicionada, caso você tenha fornecido um escopo diferente no addEvent, é necessário 
 *                   que você passe como parâmetro o mesmo objeto, caso contrário a remoção do evento não será realizada.
 */
removeEvent = function(o, e, f, s){
  for(var i = (e = o["_on" + e] || []).length; i;)
    if(e[--i] && e[i][0] == f && (s || o) == e[i][1])
      return delete e[i];
  return false;
}

String.prototype.trim = function() { return this.replace(/(?:^\s*|\s*$)/g,'') };
String.prototype.empty= function() { return this.trim() == "" };
function trim(str) { return str.trim() };
/**
** Prototipo "pad"
** @return String
** Modo de uso: stringa.pad(<largura>, <caracter>[, {direcao=<left|right>}{default=left}])
** Exemplos:
** str = "55"; str.pad(7, "0"); saída => 0000055
** str.pad(5, "-", "right");
*/
String.prototype.pad  = function(slen, ch, direction) {
  var str = this;
  while (str.length < slen) {
    if (typeof direction == "undefined") direction = "left";
    str = (direction == "left" ? ch+""+str : str+""+ch);
  }
  return str;
};

function highlight(obj, flag) {
  var cor = "#BABACA";

  if (typeof flag == "undefined")
    flag = true;
    
  if (flag) {
    obj.lastBg = obj.style.backgroundColor;
    obj.style.backgroundColor = cor;
  } else {
    if (typeof obj.lastBg != "undefined")
      obj.style.backgroundColor = obj.lastBg;
  }
}

/**
 * Abilita ou desabilita o fundo da página
 * @param {boolean} abilita True reabilita o fundo da página ao modo normal  
 */
function fundo(abilita) {
  var divFundo = $('desativaFundo');
  if (!abilita) { //MOSTRA O FUNDO PRETO TRANSPARENTE
    // Cria uma div para o fundo (se não existir)
    if (!divFundo) {
      divFundo = document.body.appendChild(document.createElement('DIV'));
      divFundo.id = 'desativaFundo';
    }
    var w,h,s = window.screen;
    w = s.availWidth;
    h = s.availHeight;
    if (navigator.appVersion.indexOf('MSIE 6') != -1) {
      w = document.documentElement.clientWidth;
      h = document.body.scrollHeight;
      if (document.documentElement.clientHeight > h) {
        h = document.documentElement.clientHeight;
      }
    }
    divFundo.style.width = w + 'px';
    divFundo.style.height = h + 'px';
    
    if (document.all) {
      var s = document.getElementsByTagName('SELECT');
      for (i=0; i<s.length; i++) {
        s[i].style.visibility = 'hidden';
      }
    }
  } else {
    if (divFundo) {
      divFundo.parentNode.removeChild(divFundo);
    }
    if (document.all) {
      var s = document.getElementsByTagName('SELECT');
      for (i=0; i<s.length; i++) {
        s[i].style.visibility = "visible";
      }
    }
  }
}


function alignAjaxWindow() {
  var wAjax = $('wAjax');
  wAjax.style.marginLeft = -(wAjax.offsetWidth / 2) + 'px';
  if (navigator.appVersion.indexOf('MSIE 6') != -1) {
    wAjax.style.marginTop = (document.documentElement.scrollTop - ((wAjax.offsetHeight) / 2)) + 'px';
  } else 
    wAjax.style.marginTop = -(wAjax.offsetHeight / 2) + 'px';
}

/**
 * Cria uma janela para procedimentos AJAX
 * @param {Boolean} abilitado Mostra ou não a janela 
 * @param {String}  titulo    Título da janela
 * @param {Boolean} showClose Mostra o botão de fechar "X". Padrão True.
 */
function ajaxWindow(abilitado, titulo, showClose, w, h) {
  var wAjax = $('wAjax');
  var conteudo = $('wAjaxConteudo');
  
  if (typeof showClose == 'undefined' || showClose === null) showClose = true;
  
  // Título padrão da nova janela
  if  (titulo == null) titulo = "Nova Janela";
  
  if (abilitado) {
    fundo(false); // Desabilita o fundo
    if (!wAjax) {
      // Janela principal
      if ($('main')) {
        wAjax = $('main').appendChild(document.createElement('DIV'));
      } else {
        wAjax = document.body.appendChild(document.createElement('DIV'));
      }
      wAjax.id = 'wAjax';
      wAjax.onkeypress = function(e) { 
        var e = e || event;
        e.cancelBubble = true;
        try {
          e.stopPropagation();
        } catch(ept) {}
        if (e.keyCode == 27) ajaxWindow(0) 
      };
      
      if (typeof w != 'undefined') 
        wAjax.style.width = w + 'px';
        
      if (typeof h != 'undefined')
        wAjax.style.height = h + 'px';
      
      alignAjaxWindow();
      
      // Título
      var wTitle = wAjax.appendChild(document.createElement('H1'));
      wTitle.innerHTML = '<div style="float:left;clear:none">'+titulo+'</div>';
      
      if (showClose) { // Botão de fechar
        wTitle.innerHTML += '<img align="right" style="margin:0;cursor:pointer" src="/fw/img/x.jpg" alt="Fechar" onclick="ajaxWindow(false)" />';
      }
      
      // Conteúdo
      conteudo = wAjax.appendChild(document.createElement('DIV'));
      conteudo.id = 'wAjaxConteudo';
      
      // Adiciona eventos à janela do navegador
      addEvent(window, 'resize', alignAjaxWindow);
      addEvent(window, 'scroll', alignAjaxWindow);
      wTitle.onmousedown = function(e){ grab(this.parentNode, e) };
    }
    return conteudo;
  } else {
    if (wAjax) {
      // Remove o evento à janela
      removeEvent(window, 'resize', alignAjaxWindow);
      removeEvent(window, 'scroll', alignAjaxWindow);
      
      // Elimina a janela e volta tudo ao normal
      wAjax.parentNode.removeChild(wAjax);
    }
    fundo(true);
  }
}

function grab(obj,e)
{
  getMousePosition(e);
  obj.className = 'moving';
  document.onmousedown = new Function('return false'); // in NS this prevents cascading of events, thus disabling text selection
  document.onmousemove = drag;
  document.onmouseup = drop;
  mouseinfo.dragobj = obj;
  mouseinfo.grab.x = mouseinfo.mouse.x;
  mouseinfo.grab.y = mouseinfo.mouse.y;
  mouseinfo.setOri(mouseinfo.dragobj.style.marginLeft, mouseinfo.dragobj.style.marginTop);
  getMousePosition();
}

function drag(e) // parameter passing is important for NS family 
{
  if (mouseinfo.dragobj)
  {
    mouseinfo.ele.x = mouseinfo.ori.x + (mouseinfo.mouse.x - mouseinfo.grab.x);
    mouseinfo.ele.y = mouseinfo.ori.y + (mouseinfo.mouse.y - mouseinfo.grab.y);
    
    mouseinfo.dragobj.style.marginLeft = (mouseinfo.ele.x).toString(10) + 'px';
    mouseinfo.dragobj.style.marginTop  = (mouseinfo.ele.y).toString(10) + 'px';
  }
  getMousePosition(e);
  return false; // in IE this prevents cascading of events, thus text selection is disabled
}

function drop()
{
  if (mouseinfo.dragobj)
  {
    mouseinfo.dragobj.className = '';
    mouseinfo.dragobj = null;
  }
  document.onmouseup = null;
  document.onmousedown = null;   // re-enables text selection on NS
}

function getMousePosition(e)
{
    if (!e) e = window.event;
        
    if (e) {
        mouseinfo.mouse.x = e.pageX ? e.pageX : e.clientX;
        mouseinfo.mouse.y = e.pageY ? e.pageY : e.clientY;
    }
}

function rowEvent(obj, e) {
  var cor = "#BABACA";
  
  if (obj.onmouseout == null)
    obj.onmouseout = function(e) { obj.style.backgroundColor = "" }

  obj.style.backgroundColor = cor;
}

function eNomeCompleto(str) {
  str = trim(str);
  return str.match(/[a-zA-Z]+\s+[a-zA-Z]+/);
}

function abrePopup(url, name, w, h, extras) {
  var left = (screen.width - w) / 2; // Calcula a posição central de X
  var top  = (screen.height - h) / 2; // Calcula a posição central de Y
  return window.open(url, name, 'left='+left+',top='+top+',width='+w+',height='+h+','+extras);
}

function mOver(n) {
  /*if ((navigator.appName == "Microsoft Internet Explorer") && (navigator.appName == "Mozilla Firefox") && (document.forms.length > 0) && (document.forms[0] != 'undefined'))
    for (var i = 0; i < document.forms[0].elements.length; i++)
      if (document.forms[0].elements[i].type == 'select-one')
    	document.forms[0].elements[i].style.visibility = 'hidden';*/

  if (typeof(tms[n]) != "undefined") clearTimeout(tms[n]);
  document.getElementById(n).style.visibility = "visible";
}
function mOut(n){
  if ((navigator.appName == "Microsoft Internet Explorer") && (document.forms.length > 0) && (document.forms[0] != 'undefined'))
    for (var i = 0; i < document.forms[0].elements.length; i++)
      if (document.forms[0].elements[i].type == 'select-one')
        document.forms[0].elements[i].style.visibility = 'visible';

    tms[n]=setTimeout('document.getElementById("'+n+'").style.visibility="hidden"', 100);
}    

function boletosCheckAll(f) {
  for (var i=0; i<f.length; i++)
    if (f[i].type == 'checkbox') 
      f[i].checked = (f[i].checked == false?true:false);
    else if ((f[i].type == 'text') && (f[i].className == 'data'))
      f[i].disabled = (f[i].disabled == false?true:false);
}

function checkAll(f) {
  for (var i=0; i<f.length; i++)
    if (f[i].type == 'checkbox') 
      f[i].checked = (f[i].checked == false?true:false);
}

function enterForm(tecla, url) {
  var key;
  
  if (navigator.userAgent.indexOf("MSIE") > 0)  key = tecla.keyCode;
  if (navigator.userAgent.indexOf("Gecko") > 0) key = tecla.which;
  if (key == 13) location.href = url;
  else return true;
}

function getDados(secao, id, nome) {
  window.opener.document.getElementById(secao).value        = nome;
  window.opener.document.getElementById(secao + "ID").value = id;
  window.close();
}

function getTutor(id, nome) {
  window.opener.document.getElementById("Tutor").value   = nome;
  window.opener.document.getElementById("TutorID").value = id;
  window.close();
}

function getData(tipo, id, nome) {
  window.opener.document.getElementById(tipo).value        = nome;
  window.opener.document.getElementById(tipo + "ID").value = id;
  window.close();
}

function getCurso(id, nome) {
  window.opener.document.getElementById("Curso").value   = nome;
  window.opener.document.getElementById("CursoID").value = id;
  window.close();
}
function getPOP(id, nome,estado) {
  window.opener.document.getElementById("Cliente").value    = nome + ' - ' + estado;
  window.opener.document.getElementById("ClienteID").value  = id ;
  //window.opener.document.getElementById("Estado").value   = uf;
  window.close();
}
function getTurma(id, nome, estado) {
  window.opener.document.getElementById("Turma").value    = nome ;
  window.opener.document.getElementById("TurmaID").value  = id ;
  //window.opener.document.getElementById("Estado").value = uf;
  window.close();
}

function getCidade(obj, id, cid, uf) {
  window.opener.document.getElementById(obj).value        = cid + ' - ' + uf;
  window.opener.document.getElementById(obj + "ID").value = id;
  window.close();
}

function formataCampo(tecla, obj, tipo) {
  var key;
  
  if (navigator.userAgent.indexOf("MSIE") > 0)  key = tecla.keyCode;
  if (navigator.userAgent.indexOf("Gecko") > 0) key = tecla.which;
  if ((key == 8) || (key == 0) || (key == 13)) return true;
  key = String.fromCharCode(key);

  var erNum  = /[0-9]/i;
  var erReal = /[0-9,]/i;

  if ((erReal.test(key)) && (tipo == 'real')) {
    if (tipo == 'real') {
      if ((key == ',') && ((obj.value.indexOf(',') + 1) < obj.value.length) && (obj.value.indexOf(',') == "-1"))
        return true;
      else if (erNum.test(key))
        return true;
      else
        return false;
    }
    
  } else if (tipo == 'login') {
    if (erNum.test(obj.value.substr(0,1))) {
      if ((obj.value.length == 2) || (obj.value.length == 6)) { obj.value = obj.value + key + '.'; return false; }
      else if (obj.value.length == 10) { obj.value = obj.value + key + '-'; return false; }
      else if (obj.value.length > 13) { return false }
    } else return true;
    
  } else if (erNum.test(key)) {
    /**** CEP ****/
    if (tipo == 'cep') {
      if (obj.value.length == 1) { obj.value = obj.value + key + '.'; return false; }
      else if (obj.value.length == 5) { obj.value = obj.value + key + '-'; return false; }
      else return true;

    /**** num ****/
    } else if (tipo == 'num') {
      return true;
    
    /**** CNPJ ****/
    } else if (tipo == 'cnpj') {
      // 012345678901234567
      // 80.637.838/0005-65
      if ((obj.value.length == 1) || (obj.value.length == 5)) { obj.value = obj.value + key + '.'; return false; }
      else if (obj.value.length == 9) { obj.value = obj.value + key + '/'; return false; }
      else if (obj.value.length == 14) { obj.value = obj.value + key + '-'; return false; }
      else if (obj.value.length > 17) { return false }
      else return true;

    /**** CPF ****/
    } else if (tipo == 'cpf') {
      if ((obj.value.length == 2) || (obj.value.length == 6)) { obj.value = obj.value + key + '.'; return false; }
      else if (obj.value.length == 10) { obj.value = obj.value + key + '-'; return false; }
      else if (obj.value.length > 13) { return false }
      else return true;

    /**** CNPJ ****/
    } else if (tipo == 'cnpj') {
      if ((obj.value.length == 1) || (obj.value.length == 5)) { obj.value = obj.value + key + '.'; return false; }
      else if (obj.value.length == 9) { obj.value = obj.value + key + '/'; return false; }
      else if (obj.value.length == 14) { obj.value = obj.value + key + '-'; return false; }
      else return true;

    /**** DATA ****/
    } else if (tipo == 'data') {
      if ((obj.value.length == 1) || (obj.value.length == 4)) { obj.value = obj.value + key + '/'; return false; }
      else return true;
    /**** DV PARA AGENCIA E CC ****/
    } else if (tipo == 'dv') {
      if (obj.value.length == 3)  { obj.value = obj.value + key + '-'; return false; }
      else return true;
 
       /****   TELEFONE ****/
  }else if (tipo == 'telefone') {
      if (obj.value.length == 0) { obj.value =  '(' + key + obj.value ; return false; }
      else if (obj.value.length == 2) { obj.value = obj.value + key + ') '; return false; }
      else if (obj.value.length == 8) { obj.value = obj.value + key + '-'; return false; }
      else return true;

    } else { return false; }
  }
  else return false;
}

/**
 * Funde tags "P" com a classe "msg" em uma só tag.
 * @author Patrick S. de Palma
 * @version 1.0
 */
function mergeMsg() {
  var p = document.body.getElementsByTagName('p');
  var msg = [];
  if (p) {
    for (var i=0,c=p.length; i<c; i++) {
      if (p[i].className == 'msg') {
        msg[msg.length] = p[i];
      }
    }
    if (msg.length > 1) {
      msg[0].innerHTML = "-&nbsp;" + msg[0].innerHTML;
      for (var i=1,c=msg.length;i<c;i++) {
        msg[0].innerHTML += "<br />-&nbsp;" + msg[i].innerHTML;
        msg[i].style.display = "none";
      }
    }
  }
}

String.prototype.isCpf = function(){
    var c = this;
    if((c = c.replace(/[^\d]/g,"").split("")).length != 11) return false;
    if(new RegExp("^" + c[0] + "{11}$").test(c.join(""))) return false;
    for(var s = 10, n = 0, i = 0; s >= 2; n += c[i++] * s--);
    if(c[9] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    for(var s = 11, n = 0, i = 0; s >= 2; n += c[i++] * s--);
    if(c[10] != (((n %= 11) < 2) ? 0 : 11 - n)) return false;
    return true;
};

/**
 * Seleciona o primeiro campo da página que ESTEJA DENTRO de um FORM
 */
function selectFirstField() {
  if (document.forms.length>0) {
    var input = document.forms[0].getElementsByTagName('*');
    for (var i=0,c=input.length; i<c; i++) {
      if (input[i].disabled || input[i].readOnly) continue;
      // Caso se deseje selecionar também o primeiro select, adicione junto ao TEXTAREA separado por um | (pipe)
      if (/^(?:TEXTAREA)$/.test(input[i].nodeName) || (input[i].nodeName=='INPUT' && (input[i].type == 'text' || input[i].type == 'password' || input[i].type == 'file'))) {
        try {
          input[i].focus();
        } catch(e) {
          return;
        }
        break;
      }
    }
  }
}

/**
 * Guarda um valor em um cookie
 * @param {String} cookieName
 * @param {String} cookieValue
 * @param {Integer} nDays
 */
function setCookie(cookieName, cookieValue, nDays){
  var today = new Date();
  var expire = new Date();
  if (nDays == null || nDays == 0) nDays = 1;
  expire.setTime(today.getTime() + 3600000 * 24 * nDays);
  document.cookie = cookieName + "=" + escape(cookieValue) + ";expires=" + expire.toGMTString();
}

/**
 * Extrai um valor de um cookie
 * @param {String} cookieName
 * @return {String}
 */
function getCookie(cookieName){
  if (document.cookie.length > 0) {
    c_start = document.cookie.indexOf(cookieName + "=");
    if (c_start != -1) {
      c_start = c_start + cookieName.length + 1;
      c_end = document.cookie.indexOf(";", c_start);
      if (c_end == -1) c_end = document.cookie.length;
      return unescape(document.cookie.substring(c_start, c_end));
    }
  }
  return "";
}

function checkTableMail(f) {
  var e = f.elements;
  var ok = true;
  for (var i=0; i<e.length; i+=2) {
    try {
      var noEmptyEmail_1 = e[i] &&  e[i].type == 'text' && !e[i].value.empty();
      var noEmptyEmail_2 = e[i+1] && e[i+1].type == 'text' && !e[i+1].value.empty();
      var tr = e[i].parentNode.parentNode;
      tr.className = tr.className.replace(' error',''); // Limpa possíveis classes já inseridas no atributo
      if (noEmptyEmail_1 && noEmptyEmail_2 && e[i].value != e[i+1].value) {
        ok = false;
        e[i].parentNode.parentNode.className += ' error'; // Adiciona a classe "error"
      }
    } catch(e) {}
  }
  if (ok) {
    ok = confirm('Tem certeza que deseja atualizar o cadastro dos alunos?');
    if (ok) {
      f.action = window.location.href;
    }
  } else {
    alert("Os e-mails nas linhas marcadas da tabela não coincidem.\nPor favor, verifique antes de submeter novamente.");
  }
  
  return ok;
}

addEvent(window, "load", 
  function() {
    mergeMsg();
    selectFirstField();
    
    var cDebug = getCookie('debug'); 
    if (cDebug == 1 || cDebug == '0') {
      http('post', '/fw/plugins/debug/debug.php', showDebug);
    }
  }
)

function activateDebug(ativar) {
  setCookie('debug', ativar, 5);
  http('post', '/fw/plugins/debug/debug.php', showDebug, {debug: ativar});
}

function showDebug(ativar) {
  if (ativar === 0 && $('debug')) {
    $('debug').parentNode.removeChild($('debug'));
    return;
  } else if (ativar === 0) {
    return;
  }
  var div = {};
  if (!$('debug')) {
    div = document.body.appendChild(document.createElement("div"));
    div.id = "debug";
    div.style.position = 'absolute';
    div.style.right = "10px";
    div.style.top = "10px";
    div.style.width = "100px";
    div.style.lineHeight = "24px";
    div.style.textAlign = "center";
    div.style.border = "1px solid #000";
    div.style.cursor = "pointer";
  } else {
    div = $('debug');
  }
  div.style.backgroundColor = ativar == 1 ? "orange" : "lightgray";
  div.innerHTML = ativar == 1 ? 'DESAT. DEBUG' : 'ATIVAR DEBUG';
  div.onclick = function(){
    if (ativar == 1) {
      activateDebug(0);

    } else {
      activateDebug(1);
      var perg = 'Quer recarregar a página?\nAs querys só serão mostradas após recarregar a página (se existirem).';
      if (confirm(perg)) {
        window.location.reload(true);
      }   
    }
  }
}

/*************************************
 * Micro sistema de busca por chaves
 */
fieldFilter = {
  filterMap: {
    MatriculaID: "int",
    CPF: {
      "=": "cpf",
      "<>": "cpf"
    },
    TurmaID: "int",
    DtNascto: "data"
  },
  /**
   * Adiciona um campo de filtro
   * @param {Object} o
   */
  addFilter: function(o) {
    var filtro = $('filtro');
    var div = null;
    var a1 = null;
    var _div = null;
    
    if ((_div = o.parentNode.parentNode.getElementsByTagName('div')).length == 1) {
      a1 = _div[0].appendChild(document.createElement('A'));
      a1.className = 'lnkBtn';
      a1.innerHTML = '[-]';
      a1.href = 'javascript:void(0)';
      a1.onclick = new Function("fieldFilter.delFilter(this)");
      a1 = null;
    }
    
    // Cria container
    div = o.parentNode.parentNode.insertBefore(o.parentNode.cloneNode(true), o.parentNode.nextSibling);
    
    // Limpa input
    var i = div.getElementsByTagName('input');
    for (var n=0; n<i.length; n++){
      var input = i[n];
      input.value = '';
      input.filter = {active: true, label:'busca'};
      input.setAttribute("title", "Busca");
      input.removeAttribute("value");
      input.removeAttribute("style");
      input.removeAttribute("maxLength");
    }
    
    // Cria o link [-]
    if (div.lastChild.innerHTML == '[-]') {
      div.lastChild.onclick = new Function("fieldFilter.delFilter(this)");
    } else {
      a1 = div.appendChild(document.createElement('A'));
      a1.className = 'lnkBtn';
      a1.innerHTML = '[-]';
      a1.href = 'javascript:void(0)';
      a1.onclick = new Function("fieldFilter.delFilter(this)");
    }
    
    // Adiciona eventos
    var s = div.getElementsByTagName('select');
    s[0].onchange = new Function("fieldFilter.changeFieldParam(this)");
    s[1].onchange = new Function("fieldFilter.setClassFilter(this)");
    
    this.setClassFilter(i[0]);
    
  },
  delFilter: function(o) {
    var div = o.parentNode.parentNode.getElementsByTagName('div');
    o.parentNode.parentNode.removeChild(o.parentNode);
    
    if (div.length == 1) {
      if (div[0].lastChild.innerHTML == '[-]') {
        div[0].removeChild(div[0].lastChild);
      }
    }
  },
  changeFieldParam: function(o) {
    var s = o.parentNode.getElementsByTagName('select')[1];
    var i = o.parentNode.getElementsByTagName('input')[0];
    var dados = this.op_key[getOption(o)];
    populateSelect(null, s, dados, 0);
    this.setClassFilter(o);
    i.value = "";
    i.title = "Busca";
  },
  setClassFilter: function(o) {
    var s     = o.parentNode.getElementsByTagName('select');
    var i     = o.parentNode.getElementsByTagName('input')[0];
    var campo = getOption(s[0]);
    var op    = getOption(s[1]);
    
    i.title = "Busca";
    if (typeof this.filterMap[campo] == "undefined") {
      classfilter.setClass(i, '');
    } else if (typeof this.filterMap[campo] == "string") {
      classfilter.setClass(i, this.filterMap[campo]);
    } else if (typeof this.filterMap[campo][op] == "string") {
      classfilter.setClass(i, this.filterMap[campo][op]);
    } else {
      classfilter.setClass(i, '');
    }
  }
}

/**
 * Emula a função sprintf do C/php
 * @author Patrick S. de Palma
 * @param str {String} String a ser tratada
 * @param arg0,arg1,arg3... {mixed} Parâmetros utilizados conforme o número de substituições a serem inseridas em str
 * @return {String} String tratada 
 */
function sprintf(str) {
  var value, s, p;
  for (var i = 1, c = arguments.length; i < c; i++) {
    if ((p = str.indexOf('%')) != -1) {
      s = str.substring(p+1, p+2, 1);
      
      switch (s) {
        case 's': 
          value = String(arguments[i]);
        break;
        
        case 'd': 
          value = parseFloat(arguments[i]);
          if (isNaN(value)) value = 0;
        break;
        
        case 'i': 
          value = parseInt(arguments[i]);
          if (isNaN(value)) value = 0;
        break;
      }
      str = str.replace(/%(?:s|d|i)/, value);
    }
      
  }
  return str;
}

/**
 * Converte um número com vírgula para número com ponto
 * @param {mixed} value
 * @return {Number}
 */
function normalizeNumber(value) {
  if (isNaN(value)) {
    /* Elimina qualquer coisa que não pertence ao mundo dos números */
    value = value.replace(/[^-+0-9\.,]/g, '');
    /* Elimina possíveis pontos separados dos milhares */
    value = value.replace(/\.(?!=[0-9]{3})/g, '');
    /* Substitui a vírgula por ponto */ 
    value = value.replace(',', '.');
  }
  return Number(value);
}

/**
 * Formata um número (similar à função number_format do PHP)
 * @param {Object} value
 * @param {Object} dec            (Opcional) Quantidade de números decimais
 * @param {Object} decSeparator   (Opcional) Separador de decimais
 * @param {Object} grpSeparator   (Opcional) Separador de milhares
 * @return {String}
 */
function formatNumber(value, dec, decSeparator, grpSeparator) {
	/** Padrões **/
	if (typeof dec == 'undefined') dec = 0;
	if (typeof decSeparator == 'undefined') decSeparator = ",";
	if (typeof grpSeparator == 'undefined') grpSeparator = ".";
	if (isNaN(value)) {
		value = normalizeNumber(value);
	}
	var i, idx, n = String(Number(value).toFixed(dec)), str = '', c;
	
	/* Converte o ponto pelo decSeparator */
	if ((idx = n.indexOf('.')) != -1) {
		value = n.substr(0, idx);
		decimal = decSeparator + n.substr(idx + 1);
	} else {
		value = n;
		decimal = '';
	}
	
	// TODO: Melhorar algoritmo abaixo
	/*c = value.length - 1;
	
	for (i=c; i>=0; i--) {
	str += value[i];
	alert('char = ' + value[i]);
	}
	alert('string = ' + str);
	*/
		
	reMoeda = /^\d{1,3}(\.\d{3})*\,\d{2}$/;
	value = value.replace(reMoeda, '$1' + grpSeparator);
	//alert('int = ' + value + ' dec = ' + decimal);
	
	/*
	str = str.replace(reMoeda, '$1' + grpSeparator); //str.replace(/(\d{3})(?=\d)/g, '$1' + grpSeparator);
		
	c=str.length-1, value = '';
	for (i=c; i>=0; i--) {
		value += str[i];
	}
	*/
	value += decimal; 
	
	return value;
}
