// Programador: Flávio Cruz de Souza
// Última Atualização: 31/07/2007

var isFF = navigator.appName == "Netscape";


//Retorna uma string com a data no formato informado
//format: qualquer combinação das strings abaixo. Ex objDate.getValue("DD/MM HH:MI");
//DDD - dia da semana
//DD - dia
//MM - mês
//MMM - mês (por extenso)
//YYYY - ano
//HH - hora
//MI - minuto
//SS - segundos
Date.prototype.getValue = function(format){
  weekDay = new Array("domingo", "segunda-feira", "terça-feira", "quarta-feira", "quinta-feira", "sexta-feira", "sábado");
  month = new Array("janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro");

  return format.replace("DDD", weekDay[this.getDay()])
                .replace("DD", this.getDate() > 9 ? this.getDate() : "0" + this.getDate())
                .replace("MMM", month[this.getMonth()])
                .replace("MM", parseInt(this.getMonth()) + 1 > 9 ? parseInt(this.getMonth()) + 1 : "0" + (parseInt(this.getMonth()) + 1))
                .replace("YYYY", this.getYear() > 99 ? this.getYear() : "19" + this.getYear())
                .replace("[H]", this.getTotalHours())
                .replace("HH", this.getHours() > 9 ? this.getHours() : "0" + this.getHours())
                .replace("MI", this.getMinutes() > 9 ? this.getMinutes() : "0" + this.getMinutes())
                .replace("SS", this.getSeconds() > 9 ? this.getSeconds() : "0" + this.getSeconds());
}


//Insere a data no formato informado
//value = string contendo a data no formato informado
//format (opcional): qualquer combinação das strings abaixo. Ex objDate.setValue("01/01 23:59", "DD/MM HH:MI");
//DD - dia
//MM - mês
//YYYY - ano
//HH - hora
//MI - minuto
//SS - segundos
Date.prototype.setValue = function(value){
  argv = Date.prototype.setValue.arguments;
  argc = argv.length;
  format = argc > 1 ? argv[1] : "DD/MM/YYYY";

  var day, mounth, year, hour, minute, second, pos;
  
  pos = format.indexOf("DD");
  day = pos == -1 ? 1 : value.substr(pos, 2);
  this.setDate(day);
  
  pos = format.indexOf("MM");
  mounth = pos == -1 ? 1 : value.substr(pos, 2);
  this.setMonth(mounth - 1);
    
  pos = format.indexOf("YYYY");
  year = pos == -1 ? 1970 : value.substr(pos, 4);
  this.setYear(year);
    
  pos = format.indexOf("HH");
  hour = pos == -1 ? 0 : value.substr(pos, 2);
  this.setHours(hour);  
  
  pos = format.indexOf("MI");
  minute = pos == -1 ? 0 : value.substr(pos, 2);
  this.setMinutes(minute);
    
  pos = format.indexOf("SS");
  second = pos == -1 ? 0 : value.substr(pos, 2);
  this.setSeconds(second);
}


Date.prototype.toString = function(){
  return this.getValue("DDD, DD de MMM de YYYY, HH:MI:SS.");
}



Date.prototype.getTotalHours = function(){
  return parseInt((((this.valueOf() / 1000) / 60) - this.getTimezoneOffset()) / 60);
}



//Verifica se um objeto select está selecionado
function isSelected(obj){
  var i;
  var isValid = false;
  
  for (i = 0; i < obj.length; i++){
    if (obj.options[i].selected){
      isValid = true;
      break;
    }
  }
  
  return isValid;
}



// Seleciona uma Option em um Select com o valor que eu informei
function selectOption(obj, value){
  for(var i = 0; i < obj.length; i++)
    if(obj.options[i].value == value){
      obj.selectedIndex = i;
      break;
    }
}



// Insere Options em um Select
function insertOption(obj, value, text){
  var argv = insertOption.arguments;
  var argc = argv.length;
  var insertBefore = (argc > 3) ? argv[1] : null;

  var op = new Option(text, value, false, false);

  if(insertBefore)
    try {
      obj.add(op, obj.options[insertBefore]); // standards compliant
    }
    catch(ex){
      obj.add(op, insertBefore); // IE only
    }
  else
    try {
      obj.add(op, null); // standards compliant
    }
    catch(ex){
      obj.add(op); // IE only
    }
}



// Deleta os Options de um Select
function deleteAllOption(obj) {
  obj.length = 0;

  if(!isFF) insertOption(obj, "", "");
}



function checkRadioButton(obj, value){
  if(obj.length)
    for(var i = 0; i < obj.length; i++)
      obj[i].checked = obj[i].value == value;
  else
    obj.checked = obj.value == value;
}



function mostraDiv(obj, show){
  document.getElementById(obj).style.display = show ? "block" : "none";
}



function validaCampo(campo, nomeCampo){
  if(!campo.value){
    alert("O campo \"" + nomeCampo + "\" é de preenchimento obrigatório.");
    campo.focus();
    return false;
  }
  return true;
}




// Funções de validação de dados
function isValidUnsignedInteger(pStr) {
  var reUnsignedInteger = /^\d+$/;
  
  return reUnsignedInteger.test(pStr);
} // isValidUnsignedInteger



function isValidInteger(pStr) {
  var reInteger = /^[+-]?\d+$/;  
  
  return reInteger.test(pStr);
} // isValidInteger



function isValidFloat(pStr){
  var argv = isValidFloat.arguments;
  var argc = argv.length; 
  var pLang = (argc > 1) ? argv[1] : "Pt";   

  var reFloat;
  var reFloatPt = /^[+-]?((\d+|\d{1,3}(\.\d{3})+)(\,\d*)?|\,\d+)$/; //Portugues
  var reFloatEn = /^[+-]?((\d+|\d{1,3}(\,\d{3})+)(\.\d*)?|\.\d+)$/; //Ingles
  
  eval("reFloat = reFloat" + pLang);
  return reFloat.test(pStr);
} // isValidFloat



function isValidDate(pStr){
  var argv = isValidDate.arguments;
  var argc = argv.length; 
  var pFmt = (argc > 1) ? argv[1] : "DDMMAAAA";

  var reDate;
  var reDateDMAA = /^((0?[1-9]|[12]\d)\/(0?[1-9]|1[0-2])|30\/(0?[13-9]|1[0-2])|31\/(0?[13578]|1[02]))\/(19|20)?\d{2}$/; // dd ou d/mm ou m/aaaa ou aa
  var reDateDDMMAAAA = /^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2])|31\/(0[13578]|1[02]))\/(19|20)\d{2}$/; // dd/mm/aaaa

  eval("reDate = reDate" + pFmt);

  if(pStr.split("/").length != 3)
    return false;

  if(pStr.split("/")[1] == 2) {
    //Valido ano que nao e bissexto
    if(pStr.split("/")[0] > 28 && (pStr.split("/")[2] % 4) != 0)
      return false;
    //Valido ano bissexto
    if(pStr.split("/")[0] > 29 && (pStr.split("/")[2] % 4) == 0)
      return false;
  }
  
  return reDate.test(pStr);
} // isValidDate



function isValidTime(pStr){
  var reTime;

  var argv = isValidTime.arguments;
  var argc = argv.length; 
  var pFmt = (argc > 1) ? argv[1] : "HH24:MI";

  H3 = '\\d+';   //  \\ = \
  HH24 = '([0-1]\\d|2[0-3])';
  HH12 = '(0[1-9]|1[0-2])';
  MI = '[0-5]\\d';
  M3 = '\\d+';
  SS = '[0-5]\\d';

  pFmt = pFmt.replace("H3", H3)
             .replace("HH24", HH24)
             .replace("HH12", HH12)
             .replace("MI", MI)
             .replace("M3", M3)
             .replace("SS", SS);

  eval("reTime = /^" + pFmt + "$/");
  
  return reTime.test(pStr);
} // isValidTime



function isValidEmail(pStr){
  var argv = isValidEmail.arguments;
  var argc = argv.length; 
  var pFmt = (argc > 1) ? argv[1] : "2";

  var reEmail1 = /^[\w!#$%&'*+\/=?^`{|}~-]+(\.[\w!#$%&'*+\/=?^`{|}~-]+)*@(([\w-]+\.)+[A-Za-z]{2,6}|\[\d{1,3}(\.\d{1,3}){3}\])$/;
  var reEmail2 = /^[\w-]+(\.[\w-]+)*@(([\w-]{2,63}\.)+[A-Za-z]{2,6}|\[\d{1,3}(\.\d{1,3}){3}\])$/;
  var reEmail3 = /^[\w-]+(\.[\w-]+)*@(([A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d]\.)+[A-Za-z]{2,6}|\[\d{1,3}(\.\d{1,3}){3}\])$/;

  eval("reEmail = reEmail" + pFmt);
  
  return reEmail.test(pStr);
  
  /*

  Livre — ReEmail1 aceita nome-local com todos os caracteres permitidos na RFC 2822:
  [\w!#$%&'*+/=?^`{|}~-]; e o domínio tem definição bem livre, por nome basicamente 
  fixando apenas que o TLD deve ter entre 2 e 6 caracteres: [A-Za-z]{2,6}; 
  ou por número IP entre colchetes: \[\d{1,3}(\.\d{1,3}){3}\]. 

  Compacto — ReEmail2 limita os caracteres permitidos no nome-local de forma mais
  compacta e restritiva, porém cobre os casos mais comuns. Aceita como nome-local
  uma ou mais palavras separadas por ponto ([\w-]+(\.[\w-]+)*), onde cada palavra 
  é definida por [\w-]+ permitindo assim letra, dígito, sublinhado e hífen.
  Também limita o tamanho de nomes de domínio entre 2 e 63 caracteres apenas 
  com letras, dígitos, sublinhado e hífen: [\w-]{2,63}. 

  Restrito — ReEmail3 é uma variação da ReEmail2, mas força nomes de domínio entre
  2 e 63 caracteres, deixa de usar a seqüência \w para não permitir o sublinhado e 
  garante que não há hífen nem na primeira nem na última posição, conforme 
  RFC 1034/1035. O resultado é o seguinte para representar um nome de domínio: 
  [A-Za-z\d][A-Za-z\d-]{0,61}[A-Za-z\d]. 

  */
}



function isValidCNPJ(pStr){
  if(!pStr)
    return false;

  pStr = pStr.replace(/[./-]/g,"");
   //alert(pStr);
  //Valida 1º dígito verificador
  if(!isValidDv(pStr, [5,4,3,2,9,8,7,6,5,4,3,2]))
    return false;

  //Valida 2º dígito verificador
  if(!isValidDv(pStr, [6,5,4,3,2,9,8,7,6,5,4,3,2]))
    return false;

  return true;
}



function isValidCPF(pStr){
  if(!pStr)
    return false;

  pStr = pStr.replace(/[.-]/g,"");
  
  //testa se os algarismos são iguais
  valid = false;
  for(i = 1; i < pStr.length; i++)
    if(pStr.charAt(i) != pStr.charAt(i - 1)){
      valid = true;
      break;
    }

  if(!valid)
    return false;

  //Valida 1º dígito verificador
  if(!isValidDv(pStr, [10,9,8,7,6,5,4,3,2]))
    return false;

  //Valida 2º dígito verificador
  if(!isValidDv(pStr, [11,10,9,8,7,6,5,4,3,2]))
    return false;

  return true;
}



function isValidDv(pStr, pArray){
  sum = 0;
  pos = pArray.length;
  for (i = 0; i < pos; i ++)
    sum += parseInt(pStr.charAt(i)) * pArray[i];
    
  dv = 11 - (sum % 11);
  if (dv == 10 || dv == 11)
    dv = 0;

  if (dv != parseInt(pStr.charAt(pos)))
    return false;
    
  return true;
}


function isValidContent(obj, type){
  if(type == "date")
    return isValidDate(obj.value);
      
  if(type == "time")
    return isValidTime(obj.value);
      
  if(type == "integer")
    return isValidInteger(obj.value);
      
  if(type == "unsignedinteger")
    return isValidUnsignedInteger(obj.value);

  if(type == "email")
    return isValidEmail(obj.value);
    
  if(type == "cpf")
    return isValidCPF(obj.value);
}



//Valida se uma quantidade de checkbox/radio foi selecionado
function isChecked(obj){
  var argv = isChecked.arguments;
  var argc = argv.length;
  var msg = (argc > 1) ? argv[1] : null;
  var init = (argc > 2) ? argv[2] : 1;
  var end = (argc > 3) ? argv[3] : 1;
  
  var f = obj.form;
  var contChecked = 0;
  var i;
  var e;
  
  for(i = 0; i < f.length; i++){
    e = f.elements[i];
    
    if(e.type == obj.type && e.name == obj.name && e.checked)
      contChecked++;
  }

  if(contChecked < init || contChecked > fin){
    if(msg) alert(msg);
    return false;
  }
}



function between(num, numIni, numEnd){
  return (num >= numIni && num <= numEnd);
}



function trim(value){
  var returnValue;
  var argv = trim.arguments;
  var argc = argv.length;
  var removeDoubleSpace = argc > 1 ? argv[1] : false;
    
  //Elimina os espaços antes e depois da string
  var returnValue = value.replace(/(^\s+)|(\s+$)/g, '');
    
  //Elimina espaços duplicados
  if(removeDoubleSpace)
    returnValue = returnValue.replace(/\s{2,}/g, ' ');
      
  return returnValue;
}

// seta o foco de um campo (criada pois no mozilla tem bug)
var vObj;

function setFocus(obj){
  vObj = obj;
  setTimeout('execSetFocus()',1);
}

function execSetFocus(){
  vObj.focus(); 
}


//Funções para posicionamento do cursor
function getCursorPos(obj) {
  //Mozilla
  if (typeof obj.selectionStart != "undefined")
    return obj.selectionStart;
  //IE
  else if (document.selection)
    return Math.abs(document.selection.createRange().moveStart("character", -1000000));
  //Outros
  else
    return obj.value.length;
}


function setCursorPos(obj, pos) {
  //IE
  if(obj.createTextRange) {
    var range = obj.createTextRange();
    range.move("character", pos);
    range.select();
  }
  //Mozilla
  else if(obj.selectionStart) {
    obj.focus();
    obj.setSelectionRange(pos, pos);
  }
}


//Função genérica de mascara
//Recebe o objeto text e uma das funções abaixo
var vFunction;
var vObject;
var vParameters = new Array();
// Inteiros - onKeyPress="mask(event, mUnsignedInteger)"
// CPF - onKeyPress="mask(event, mCpf)"
// CNPJ - onKeyPress="mask(event, mCnpj)"
// CEP - onKeyPress="mask(event, mCep)"
// Telefone - onKeyPress="mask(event, mTelephone)"
// Alfanumericos - onKeyPress="mask(event, mAlphaNumeric, 'U')" o terceiro parametro é opcional 'U'pperCase ou 'L'owerCase
// Alfabeticos - onKeyPress="mask(event, mAlpha, 'U')" o terceiro parametro é opcional 'U'pperCase ou 'L'owerCase
// Email - onKeyPress="mask(event, mEmail)"
// Data - onKeyPress="mask(event, mDate)"
function mask(e, func){
  vObject = e.srcElement || e.target; // pega o objeto que recebeu o evento
  vKey = e.keyCode || e.which;
  vFunction = func;
  vParameters = mask.arguments;

  if(vKey != 9) // Não executa a mascara se for pressionado o TAB
    setTimeout("execMask()", 1);
}

function execMask(){
  //guarda a posição do cursor
  var vPosition = getCursorPos(vObject);
  //guarda o valor anterior a posição do cursor, do valor antigo
  var valueBeforePosOld = vObject.value.substr(0,vPosition);
  //guarda o tamanho do valor antigo
  var vLengthOld = vObject.value.length;

  //Executa a função de mascara passada
  vObject.value = vFunction(vObject.value);

  //pegua o valor anterior a posição do cursor, do valor novo
  var valueBeforePosNew = vObject.value.substr(0, vPosition);
  //pegua o tamanho do valor novo
  var vLengthNew = vObject.value.length;

  var vDiff = vLengthNew - vLengthOld;

  if(valueBeforePosOld.toUpperCase() == valueBeforePosNew.toUpperCase())
    vDiff = 0;
  else if (vDiff == 0) //a posição do caracter mudou pois a mascara inseriu um caracter antes
    vDiff++;

  //coloca o cursor na posição original
  setCursorPos(vObject, vPosition + vDiff);
}


//Funções a serem passadas para mask
function mAlphaNumeric(value){
  return mAux(value, /[^a-záàãâéèêíìîóòõôúùûüçA-ZÁÀÃÂÉÈÊÍÌÎÓÒÕÔÚÙÛÜÇ0-9\s´().:;,-]/g);
}


function mAlpha(value){
  return mAux(value, /[^a-záàãâéèêíìîóòõôúùûüçA-ZÁÀÃÂÉÈÊÍÌÎÓÒÕÔÚÙÛÜÇ\s´().:;,-]/g);
}


// auxiliar para as mascaras de letras
function mAux(value, reReplace){
  if(vParameters.length > 2)
    var vCase = vParameters[2].toUpperCase();
  else
    var vCase = "N";

  switch(vCase){
    case "U" : return value.replace(reReplace,"").toUpperCase();
    case "L" : return value.replace(reReplace,"").toLowerCase();

    default  : return value.replace(reReplace,"");
  }
}

function mUnsignedInteger(value){
  return value.replace(/\D/g,"");
}


function mTelephone(value){
  value = mUnsignedInteger(value);                 //Remove tudo o que não é dígito
  value = value.replace(/^(\d\d)(\d)/g,"($1) $2"); //Coloca parênteses em volta dos dois primeiros dígitos
  value = value.replace(/(\d{4})(\d)/,"$1-$2");    //Coloca hífen entre o quarto e o quinto dígitos

  return value;
}


function mCpf(value){
  value = mUnsignedInteger(value);                    //Remove tudo o que não é dígito
  value = value.replace(/(\d{3})(\d)/,"$1.$2");       //Coloca um ponto entre o terceiro e o quarto dígitos
  value = value.replace(/(\d{3})(\d)/,"$1.$2");       //Coloca um ponto entre o terceiro e o quarto dígitos
                                                      //de novo (para o segundo bloco de números)
  value = value.replace(/(\d{3})(\d{1,2})$/,"$1-$2"); //Coloca um hífen entre o terceiro e o quarto dígitos
  return value;
}


function mRG(value){
  return value.replace(/[^\w\s.-]/g, "").toUpperCase();
}


function mCep(value){
  value = mUnsignedInteger(value);               //Remove tudo o que não é dígito
  value = value.replace(/^(\d{5})(\d)/,"$1-$2"); //Esse é tão fácil que não merece explicações
  return value;
}


function mDate(value){
  if(vParameters.length > 2)
    var vType = vParameters[2].toUpperCase();
  else
    var vType = "DD/MM/YYYY";

  value = mUnsignedInteger(value);
  value = value.replace(/^(\d{2})(\d)/,"$1/$2");

  if(vType == "DD/MM/YYYY")
    value = value.replace(/(\d{2})(\d)/,"$1/$2");

  return value;
}

function mCnpj(value){
  value = mUnsignedInteger(value);                           //Remove tudo o que não é dígito
  value = value.replace(/^(\d{2})(\d)/,"$1.$2");             //Coloca ponto entre o segundo e o terceiro dígitos
  value = value.replace(/^(\d{2})\.(\d{3})(\d)/,"$1.$2.$3"); //Coloca ponto entre o quinto e o sexto dígitos
  value = value.replace(/\.(\d{3})(\d)/,".$1/$2");           //Coloca uma barra entre o oitavo e o nono dígitos
  value = value.replace(/(\d{4})(\d)/,"$1-$2");              //Coloca um hífen depois do bloco de quatro dígitos
  return value;
}

function mEmail(value){
  return value.replace(/[^a-zA-Z0-9@._-]/g, "").toLowerCase();
}


function Form(f){
  //Atributos
  //  oForm = new Form(document.form);
  this.f = f;
  /*this.a = f.elements;
  this.t = f.length;*/

  //Métodos
  this.getField = function(name){
                    return eval("document." + f.name + "." + name);
                  }
  /*this.haveRequiredContent = function(){
    var e;

    for(var i = 0; i < this.t; i++){
      e = this.a[i];

      if(e.required)
        if(e.type == "text" || e.type == "password" || e.type == "")
          if(!e.value)
            return false;
    }
  }

  this.haveValidContent = function(){
    var e;

    for(var i = 0; i < f.length; i++){
      e = f.elements[i];

      if();
    }
  }
  */
/*
  dontCheck = new Array('hidden', 'submit', 'reset', 'button', 'image', 'radio', 'select-one', 'select-multiple', 'checkbox');

  for (e = 0; e < f.elements.length; e++){
    skip = false;
    fType = f.elements[e].type;

    for (d = 0; d < dontCheck.length; d++){
      if (fType == dontCheck[d]){
        skip = true;
      }
    }

    if (fType && !skip){
*/
}


function addEvent(obj, evType, fn){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, false);
    return true;
  }
  else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  }
  else{
    return false;
  }
}
/*
addEvent(window, 'load', foo);
addEvent(window, 'load', bar);
*/
