var layers_visible = [];
var top_interface = '0';
var copy_from_formid = "";
var moz = ! document.all;

function addEvent (el, event, func) {
 if (moz)
  el.addEventListener(event, func, false);
 else
  el.attachEvent("on"+event, func);

}

function removeEvent (el, event, func) {
 if (moz)
  el.removeEventListener(event, func, false);
 else
  el.detachEvent("on"+event, func);
}

//
// Armazena uma lista com o formado "<id do elemento>@<URL>" informando quais URL foram lidas em quais elementos
// Essa lista eh utilizada pela funcao requestURL() para evitar requisicoes desnecessarias sejam feitas quando a parametro
// 'once' eh especificado verdadeiro.
//
var requestURLdone = [];
var requestURLold  = [];


addScript(
 "QueryString",
 "prototype",
 "Key",
 "Array.contains",
 "getElements",
 "toQString",
 "Ajax",
 "Mask",
 "calendar",
 "myCalendar",
 "calendar-br",
 "String.char",
 "ContextMenu"
);

// docs???
function getSession () {
 return String(Math.random()).substr(2, 10).split("").join("/");
}

// docs???
function popUp (querystring, popup, properties, session) {
 if (!session)
  session = getSession();
 if (!properties)
  properties = "toolbar=no,titlebar=no,status=yes,scrollbars=yes,menubar=yes,location=no,resizable=yes,width=640,height=480";

 url = "/Ultra/"+session+"/Class.cgi?"+querystring;

 return window.open(url, popup, properties);
}

// docs???
function DebugTask (Package, Class, Field) {
 var q = {
  PackageId : Package,
  ClassId   : Class,
  FieldId   : Field
 };

 var QueryString = "_ClassId=ClassDebugTask&_ClassDebugTask.Method=Browse&_ClassDebugTask.OK=1&_ClassDebugTask.Order=DataFim&_ClassDebugTask.OrderDesc=1&_ClassDebugTask.XMethod=Docs";

 for (var k in q) {
  if (q[k])
   QueryString += "&ClassDebugTask."+k+"="+q[k];
 }

 popUp(QueryString, "ClassDebugTask" + String(Math.random()).substr(2,10) );

 return false;
}

// docs???
function splitQueryString (QueryString) {
 var Pair = QueryString.split(/&|\?/gi);
 var Hash = {};

 for (var i = 0; i < Pair.length; i ++) {
  var KeyValue = Pair[i].split("=");
  Hash[KeyValue[0]] = KeyValue[1];
 }

 return Hash;
}

//
// Converte um Browse com Group By para uma busca simples, sem group by.
//
// @param FormId
//        ARRAY  Array de pares 'FieldId', 'Valor'
//
function BrowseG2S ( FormId, Fields ) {
 var myform = document.forms[FormId];

 // Alimenta busca
 for ( var ii = 0; ii < Fields.length; ii += 2 ) {
  myform.elements[ myform.elements['_ClassId'].value + '.' + Fields[ii] ].value = Fields[ii+1];
 }

 // Elimina group by
 for ( var i = 0; i < myform.elements.length; i++ ) {
  if ( myform.elements[i].name == '_' + myform.elements['_ClassId'].value + '.GroupBy' ) {
   myform.elements[i].disabled = true;
  }
 }


 myform.onsubmit();
 myform.submit();
}

//
// Funï¿½o para substituir tecla TAB por ENTER nos forms.
// Deve ser chamada/retornada no evento onkeypress da tag form.
//
// <form onkeypress="return nextField(event)" />
//
// @param e event
//
function nextField (e) {
 var Element = document.all ? e.srcElement : e.target;
 if ( Element.form != null && Element == Element.form.elements[Element.form.elements.length-1] ) return false;

 if (KeyCode(e) == 13 && Element.type != "textarea") {
  with (Element.form) {
   for (var i = 0; i < elements.length; i ++) {
    if (elements[i] == Element) {
     elements[i+1].focus();
     break;
    }
   }
  }

  return false;
 }
}

//
// Mascara para valor monetï¿½io
//
// @param Field    campo/input
//        Size     tamanho mï¿½imo. Diferente de Field.length, que considera pontos e virgula, Size considera apenas os nmeros,
//                 mantendo sempre o tamanho mï¿½imo estipulado pela mascara
//        Decimals nmero de casas apï¿½ a virgula
// @see   String.prototype.pad      (String.char.js)
//        String.prototype.reverse        ""
//        String.prototype.separate       ""
//
function MaskMoney (Field, Size, Decimals, Null) {
// Retira tudo que nï¿½ for nmero e possiveis zeros na frente do valor
 var Value = Field.value.replace(/\D/g, "").replace(/^0+/, "").substr(0, Size);
// Pega a parte do nmero antes da virgula e faz o tratamento da mascara, adicionando os pontos
 var Value1 = Value.substr(0, Value.length - Decimals).reverse().separate(3).join(".").reverse();
// Pega a parte do nmero apï¿½ a virgula
 var Value2 = Value.substr(Value.length - Decimals, Value.length);

// Atribui 0 ao nmero antes da virgula, caso este esteja nulo e existam nmeros apï¿½ a virgula
 if (Value2 && !Value1) Value1 = 0;
// Completa com zeros a esquerda do nmero apï¿½ a virgula caso ele seja maior do que zero
 if (Number(Value2) > 0) Value2 = Value2.pad(0, Decimals);

 Field.value = [Value1, Value2].grep(/.+/);

 if (Null && !Field.value) Field.value = 0;
}

//
// Funï¿½o(Expressï¿½ Regular) para validar Emails
//
// @param Email string
//
function checkEmail (Email) {
 return /^\w+([.-]?\w+)*@\w+([.-]?\w+)*$/.test(Email);
}

//
// Funï¿½o(Expressï¿½ Regular) para validar datas.
// Diferente de checkDate, esta funï¿½o permite o usuï¿½io
// inserir os seguintes formatos de data/hora:
//
// FORMATO              DESCRIï¿½O               EXEMPLO
// 99/99/9999           somete data             06/11/1985
// 99/99/9999 99:99     data/hora               06/11/1985 23:45
// 99/99/9999 99:99:99  data/hora (minutos)     06/11/1985 23:45:59
//
// @param Timestamp string
//
function checkDate (date) {
 return /^\d{2}\/\d{2}\/\d{4}( \d{2}:\d{2}(:\d{2})?)?$/.test(date);
}

function checkOnlyDate (date) {
 var parse = date.split("/"),
     day   = parseInt(Number(parse[0])),
     month = parseInt(Number(parse[1])),
     year  = parseInt(Number(parse[2]));

 if ( isNaN( day ) || isNaN( month ) || isNaN( year ) )
  return false;

 var last =
   month < 8     // se mês é menor que 8 (janeiro - julho)
 ? month == 2    // se mês é 2 (fevereiro)
 ? !(year % 100) // se ano é divisivel por 100
 ? !(year % 400) // se ano é divisivel por 400
 ? 29            // então ano é bissexto
 : 28            // se não, ano não é bissexto
 : !(year % 4)   // se ano é divisivel por 4
 ? 29            // então ano é bissexto
 : 28            // se não, ano não é bissexto
 : month % 2     // se mês é impar
 ? 31            // então último dia é 31
 : 30            // se não, último dia é 30
 : month % 2     // se mês é maior que 7 (agosto - dezembro) e é impar
 ? 30            // então último dia é 30
 : 31;           // se não, último dia é 31

 return day && day <= last && month && month <= 12
}

//
// Funï¿½o utilizada quando um form de insert eh submetido em outra pagina e tem de
// alterar o valor de um combo em outra janela
//
// @param ParentFormId Nome do FORM onde o valor sera inserido
//        FieldId      Nome do input onde o valor sera inserido
//        Value        Valor a ser inserido (value do option)
//        Description  Descricao do valor inserido (conteudo da option visivel)
//
function changeParentSelect( ParentFormId, FieldId, Value, Description ) {
// alert( ParentFormId + ' - ' + FieldId + ' - ' + Value + ' - ' + Description );
 var thisOption = window.opener.document.createElement('OPTION');
 thisOption.value = Value;
 thisOption.text  = Description;

 /*
 with ( opener.document.forms[ParentFormId].elements[FieldId] ) {
  value = Value;
  if ( value != Value ) {
   options.add( thisOption );
   value = Value;
  }
  onchange();
//  fireEvent('onChange');
 }
 */
 var combo = opener.document.forms[ParentFormId].elements[FieldId];
 combo.value = Value;
  if ( combo.value != Value ) {
   combo.options.add( thisOption );
   combo.value = Value;
  }

//  combo.onchange();
  combo.fireEvent('onChange');

 window.close();
}

//
// Funï¿½o para limitar e contar(opcional) os caracteres de um textarea
//
// @param event
//        Field     input
//        MaxLength tamanho mï¿½imo de caracteres
//        Counter   id do ojeto contador ou o prï¿½rio objeto
//
function TextLimit (event, Field, MaxLength, Counter) {
 var vSize = Field.value.length + 1;

 if(!Field.onkeyup){
  Field.onkeyup = function () {
   if (this.value.length > MaxLength) this.value = this.value.substr(0, MaxLength);
   if (typeof Counter == "string") {
    document.getElementById(Counter).innerHTML = MaxLength - Field.value.length;
   } else if (typeof Counter == "object") {
    Counter.innerHTML = MaxLength - Field.value.length;
   }
  }
 }

 if (vSize > MaxLength && ![ 0, 8 ].contains(KeyCode(event))) {
  return false;
 }
}

//
// Funï¿½o para travar o teclado apenas para digitaï¿½o de nmeros
//
// @param  event
// @return boolean
// @see    Array.prototype.contains (Array.contains.js)
//         KeyCode/KeyChar          (Key.js)
//
function NumberOnly(e) {
 // Se usuï¿½io nï¿½ apertar as teclas backspace, enter ou setas,
 // retorna true caso tenha apertado tecla numerica.
 if (![0, 8, 13].contains(KeyCode(e))) return KeyCode(e) != 32 && !isNaN(KeyChar(e));
}

//
// Em desenvolvimento, para tipos inet.
//
function inetOnly (string) {
// if ( /^\w+([.-]?\w+)*@\w+([.-]?\w+)*$/.test(string) ) {
// } else {
//  return false;
// }
// return true;
}

// DOCS?
function addNumber ( Field, Num, Flag ) {
 var x = Number( Field.value );
 var y = Number( Num );
 Field.value = ( x + y );
 if (!Flag && Number(Field.value) < 0) Field.value = 0;
}

//
// Funcao usada pelo Html::SuperInterface para exibir/ocultar suas layers
//
// @param layClass ID da SuperInterface
//        layName  Nome da layers
//        on_off   Boolean, se verdadeiro, exibe, se falso, oculta
//
function SuperInterfaceShow(layClass,layName,on) {
 if ( layName == null ) layName = 0;
 if (on) {
  SuperInterfaceShow(layClass,layers_visible[layClass],0);
  layers_visible[layClass] = layName;
  document.getElementById('layers-'+layClass+'-'+layName).style.display = "";
  document.getElementById('b-'+'layers-'+layClass+'-'+layName).className="SuperInterfaceAba";
 } else {
  document.getElementById('layers-'+layClass+'-'+layName).style.display = "none";
  document.getElementById('b-'+'layers-'+layClass+'-'+layName).className="SuperInterfaceAbaOff";
 }
}

//
// Exibe a promixa aba da layer e oculta a atual.
//
// @param  layClass ID da SuperInterface
// @return boolean  verdadeiro de teve sucesso, falso se era a ultima layer ou id nï¿½ existe
//
function SuperInterfaceShowNext( layClass, i ) {
 var nextLayer;
 if ( i == null || i == 0 ) i = 1;
 if ( layers_visible[layClass] == 0 ||
      layers_visible[layClass] == null ) {
  nextLayer = 1;
 } else {
  nextLayer = layers_visible[layClass] + i;
 }
 if ( nextLayer > 0 && document.getElementById('layers-'+layClass+'-'+nextLayer) != null ) {
  SuperInterfaceShow( layClass, nextLayer, 1 );
  if ( document.getElementById('layers-'+layClass+'-'+nextLayer).offsetTop < 300 ) {
   window.scrollTo( 0, 0 );
  } else {
   window.scrollTo( 0, document.getElementById('layers-'+layClass+'-'+nextLayer).offsetTop );
  }
  return true;
 } else {
  return false;
 }
}

//
// Funcao usada pelo Html::SuperInterface::Vert para exibir/ocultar suas layers
//
// @param layClass ID da SuperInterface
//        layName  Nome da layers
//        on_off   Boolean, se verdadeiro, exibe, se falso, oculta
//
function SuperInterfaceVertShow(layClass,layName,on) {
 if ( layName == null ) layName = 0;
 if (on) {
  SuperInterfaceShow(layClass,layers_visible[layClass],0);
  layers_visible[layClass] = layName;
  document.getElementById('layers-'+layClass+'-'+layName).style.display = "";
  document.getElementById('b-'+'layers-'+layClass+'-'+layName).className="SuperInterfaceVertAba";
 } else {
  document.getElementById('layers-'+layClass+'-'+layName).style.display = "none";
  document.getElementById('b-'+'layers-'+layClass+'-'+layName).className="SuperInterfaceVertAbaOff";
 }
}

// Em desuso. Html::input::integer#formatDataForSQL estï¿½fazendo isso de forma genï¿½ica.
// function formatCEP (Field) {
//  var cValue = Field.value.replace( /\D/g, "" );
//
//  Field.value = cValue;
//  return true;
// }

//
// Valida CNPJ/CPF
//
// @see CPF
//      CNPJ
//
function checkCNPJ_CPF (Document) {
 var Value = Document.replace( /\D/g, "");

 if (Value.length > 0) {
  if (Value.length == 11) {
   return checkCPF(Value);
  } else if (Value.length == 14) {
   return checkCNPJ(Value);
  } else {
   return false;
  }
 }

 return true;
}

//
// Valida CPF
//
function checkCPF(cValue){

 cValue = cValue.replace(/\D/g, '');

 var i;
 var c = cValue.substr(0,9);
 var dv = cValue.substr(9,2);

 var d1 = 0;
 for (i = 0; i < 9; i++)
 {
  d1 += c.charAt(i)*(10-i);
 }


 if (d1 == 0) return false;
 d1 = 11 - (d1 % 11);


 if (d1 > 9) d1 = 0;

 if (dv.charAt(0) != d1)
 {
  return false;
 }

 d1 *= 2;
 for (i = 0; i < 9; i++)
 {
  d1 += c.charAt(i)*(11-i);
 }
 d1 = 11 - (d1 % 11);
 if (d1 > 9) d1 = 0;

 if (dv.charAt(1) != d1)
 {
  return false;
 }
 return true;
}

//
// Valida CNPJ
//
function checkCNPJ (cValue) {
 cValue = cValue.replace(/\D/g, '');
 var i;
 var c = cValue.substr(0,12);
 var dv = cValue.substr(12,2);

 var cont = 0;
 var d1 = 0;
 for (i = 0; i < 12; i++)
 {
  d1 += c.charAt(11-i)*(2+(i % 8));
 }



        if (d1 == 0) return false;
        d1 = 11 - (d1 % 11);

 if (d1 > 9) d1 = 0;

 if (dv.charAt(0) != d1)
 {
  return false;
 }

 d1 *= 2;
 for (i = 0; i < 12; i++)
 {
  d1 += c.charAt(11-i)*(2+((i+1) % 8));
 }


 d1 = 11 - (d1 % 11);


 if (d1 > 9) d1 = 0;

 if (dv.charAt(1) != d1)
 {
  return false;
 }
 return true;
}

//
// Mascara para CNPJ/CPF
//
// @see Mask
//
function maskCNPJ_CPF(Field, e) {
 var vSize = Field.value.length;

 if (vSize <= 14 || (KeyCode(e) == 8 && vSize == 14)) {
  Mask( Field, "999.999.999-99", e );
 }

 if (vSize > 14) {
  Mask( Field, "99.999.999/9999-99", e );
 }
}

//
// Usada pela classe Html::input::ForeignKey::ValueInput
//
function checkValueInput ( Field, Combo ) {
 for (var i = 0; i < Combo.childNodes.length; i ++) {
  if (Field.value.toUpperCase() == Combo.childNodes[i].value.toUpperCase()) {
   Combo.childNodes[i].selected = true;
   Field.value = Combo.childNodes[i].value;
   Combo.onchange();
   break;
  }
 }
}
/*// DOCS?
function checkValueInput ( Field, Combo ) {
 var Status = false;
 var val    = Field.value;

 for ( var t = 0; t < 2; t++ ) {
  for ( var i = 0; i < Combo.childNodes.length; i ++ ) {
   if ( val == Combo.childNodes[i].value ||
        ( t == 1 && Combo.childNodes[i].value && val.toUpperCase() == Combo.childNodes[i].value.toUpperCase() ) ) {
    Combo.value = Combo.childNodes[i].value;
    Field.value = Combo.childNodes[i].value;
    Status = true;
    Combo.onchange();
    return;
   }
  }
 }
// if ( !Status ) Combo.value = Combo.childNodes[0].value;
}*/

//
// Metodo utilizado pela onblur do Html::input::ForeignKey::ValueInput
//
function checkValueInputOnBlur ( Field, Combo ){
 var Status = false;

 for ( var i = 0; i < Combo.childNodes.length; i ++ ) {
  if ( Field.value.toUpperCase() == Combo.childNodes[i].value.toUpperCase() ) {
   Status = true;
  }
 }

 if ( Field.value != '' && !Status ) {
  alert( 'Valor digitado nï¿½ ï¿½uma opï¿½o vï¿½ida.' );
//  Field.focus();
 }
}


//
// Abre janela de Browse Avanï¿½do (quele quando se clica no "Mais").
//
// O FormId necessario como parametro indica o Form normal de origem. Este form de origem deve ser tambem um FormId
// de Browse, o qual sera submetido para a janela externa que apresentara o Form avanï¿½do importando os valores do Form de Origem.
//
// @param FormId ID do FORM de origem
//
function showBrowseForm ( FormId ) {
 var myform = document.forms[FormId];

 // Abre a nova janela
 window.open('',FormId,'width=380,height=530,left=0,top=0,scrollbars=yes,menubar=no,status=no,toolbar=no,titlebar=no,resizable=yes,location=no,directories=no');

 myform.target = FormId;
 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'BrowseForm';
 myform.submit();

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'Browse';
 myform.target='';
}

//
// Semelhanto ao SaveReport, mas sobreescreve um report ja existente.
//
function SaveReportAs ( FormId, el, ClassReportId ) {
 var myform = document.forms[FormId];

 if ( ! confirm('Deseja mesmo sobreescrever este relatï¿½io com as configuraï¿½es da consulta atual?') ) {
  return;
 }

 myform.elements['_' + myform.elements['_ClassId'].value + '.ClassReportId'].value = ClassReportId;
 myform.elements['_' + myform.elements['_ClassId'].value + '.XMethod'].value       = 'Save';

 submitReport( FormId, el );

 myform.elements['_' + myform.elements['_ClassId'].value + '.ClassReportId'].value = '';
}

//
// Exlui um ClassReport
//
function DeleteReport ( FormId, el, ClassReportId ) {
 var myform = document.forms[FormId];

 if ( ! confirm('Deseja realmente excluir definitivamente este relatï¿½io?') ) {
  return;
 }

 myform.elements['_' + myform.elements['_ClassId'].value + '.ClassReportId'].value = ClassReportId;
 myform.elements['_' + myform.elements['_ClassId'].value + '.XMethod'].value       = 'Delete';

 submitReport( FormId, el );

 myform.elements['_' + myform.elements['_ClassId'].value + '.ClassReportId'].value = '';
}


function SaveReport ( FormId, el ) {
 var myform = document.forms[FormId];
 myform.elements['_' + myform.elements['_ClassId'].value + '.XMethod'].value = 'Save';
 submitReport( FormId, el );
}

//
// Salva ClassReport
//
function submitReport ( FormId, el ) {
 var myform = document.forms[FormId];

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value  = 'AjaxReport';

 requestURL( 'POST', 'Class.cgi', myform, el, 0 );

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'Browse';
 myform.target='';
}

//
// Carrega ClassReport
//
function LoadReport ( FormId, ReportId ) {
 var myform = document.forms[FormId];

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value        = 'BrowseForm';
 myform.elements['_' + myform.elements['_ClassId'].value + '.ClassReportId'].value = ReportId;
 myform.target = '_self';

 myform.submit();
}

//
// Abre janela de seleï¿½o avanï¿½da de apenas um campo para browse - quando eh clicado o botao direito do mouse sobre um input de browse.
//
// @param Field   Elemento do input do campo
//        FieldId Id do campo (SEM o ClassId)
//        type    Tipo: 1 = avanï¿½do, 0 - simples (padrao)
//
function showBrowseFormField ( Field, FieldId, type, Check ) {
 var myform       = Field.form;
 var old_level    = myform.elements['_Level'].value;
 var old_classid  = myform.elements['_ClassId'].value;
 var old_formid   = myform.elements['_ParentFormId'].value;
 var old_method   = myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value;
 var old_fieldid  = myform.elements['_ParentFieldId'].value;

 // Checa depenndencias se requisitado
 if ( Check != undefined ) {
  for (var i = 0; i < Check.length; i++) {
   if ( myform.elements[Check[i]].tagName == "INPUT" ) {
    myform.elements[Check[i]].oncontextmenu();
    return false;
   }
  }
 }

 if ( myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value == 'BrowseCombo' ) myform.elements['_ClassId'].value = myform.elements['_ParentClassId'].value;
 var old_newmethod = myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value;

 myform.target = myform.name;
 myform.elements['_Level'].value = 0;
 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'AjaxBrowseFormField';
 myform.elements['_ParentFormId'].value = myform.name;
 myform.elements['_ParentFieldId'].value = FieldId;
 myform.elements['_BrowseFormFieldType'].value = type;

 requestURL( 'POST', 'Class.cgi', myform, Field.parentNode, 0 );

 myform.elements['_Level'].value = old_level;
 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = old_newmethod;
 myform.elements['_ClassId'].value = old_classid;
 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = old_method;
 myform.elements['_ParentFormId'].value = old_formid;
 myform.elements['_ParentFieldId'].value = old_fieldid;
 myform.target='';

 return false;
}

//
// Requisita form de export especifico do formato requisitado
//
function showBrowseFormOptions ( myform, el ) {
 var old_method = myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value;

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'AjaxBrowseFormOptions';

 requestURL( 'POST', 'Class.cgi', myform, el, 0 );

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = old_method;
}

//
// Faz requisiï¿½o do AjaxInputEvent. Esses eventos sao definidos diretamente nas classes Html::input
// dos campos e sao muito flexiveis. A requisicao eh feita atraves da aï¿½o C::AjaxInputEvent, que submete
// o form inteiro especificando no campo _ParentFieldId o nome do campo.
//
// @param FormId
//        FieldId
//        Element  (opcional) Caso voce espera uma resposta em html e nao JavaScript. Eh recomendavel esperar sempre respostas em HTML, para padronizar.
//        hash     (opcional) Uma hash contendo valores para serem alimentados no form (input devem preexistir).
//        evaluate (opcional) true para requestURLeval().
//
function doAjaxInputEvent ( FormId, FieldId, el, hash, evaluate ) {
 var myform = document.forms[FormId];
 var old_method   = myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value;
 var old_pfieldid = myform.elements['_ParentFieldId'].value;
 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = 'AjaxInputEvent';
 myform.elements['_ParentFieldId'].value = FieldId;

 // Alimenta o from se necessario
 if ( hash != undefined ) setValue( FormId, hash, false );

 // Faz requisiï¿½o
 if ( !evaluate ) {
  requestURL( 'POST', 'Class.cgi', myform, el, 0 );
 } else {
  requestURLeval( 'POST', 'Class.cgi', myform, el );
 }

 myform.elements['_' + myform.elements['_ClassId'].value + '.Method'].value = old_method;
 myform.elements['_ParentFieldId'].value = old_pfieldid;
}

//
// Este metodo eh responsavel por a janela com a lista de opcoe do BrowseCombo.
//
// @param newTarget Nome da nova janela
//        Form      Elemento Form (nao apenas o seu id) onde esta a combo de origem
//        ClassId   ClassId de origem
//        FieldId   FieldId de origem
//        ForeignFieldId FieldId da tabela referenciada, de onde o valor sera exportado para o Field deste form
//
function popupBrowseCombo ( newTarget, Form, ClassId, FieldId, ForeignFieldId ) {
  // Guarda todos os valores antigos
  oldMethod         = Form.elements['_'+ClassId+'.Method'].value;
  oldParentFormId   = Form.elements['_ParentFormId'      ].value;
  oldParentClassId  = Form.elements['_ParentClassId'     ].value;
  oldParentFieldId  = Form.elements['_ParentFieldId'     ].value;
  oldForeignFieldId = Form.elements['_ForeignFieldId'    ].value;

  // Abre a janela
  window.open('',newTarget,'width=680,height=330,scrollbars=yes,menubar=no,status=yes,toolbar=no,titlebar=no,resizable=yes,location=no');

  // Seta valores novos
  Form.target = newTarget;
  Form.elements['_'+ClassId+'.Method'      ].value = 'BrowseCombo';
  Form.elements['_'+ClassId+'.ComboFieldId'].value = FieldId;
  Form.elements['_ParentFormId'            ].value = Form.name;
  Form.elements['_ParentClassId'           ].value = ClassId;
  Form.elements['_ParentFieldId'           ].value = FieldId;
  Form.elements['_ForeignFieldId'          ].value = ForeignFieldId;

  // Submete o from com os valores novos
  Form.submit();

  // Restaura os antigos (como se nada tivesse acontecido)
  Form.elements['_ForeignFieldId'          ].value = oldForeignFieldId;
  Form.elements['_ParentFieldId'           ].value = oldParentFieldId;
  Form.elements['_ParentClassId'           ].value = oldParentClassId;
  Form.elements['_ParentFormId'            ].value = oldParentFormId;
  Form.target = '_self';
  Form.elements['_'+ClassId+'.Method'      ].value = Form.elements['_'+ClassId+'.RealMethod'].value;
}

//
// Essa funcao eh invocada quando a combo eh alterada e precisa alterar outras combos
// Ela usa a aï¿½o AjaxCombo para pegar as opï¿½es disponï¿½eis para cada combo que serï¿½alterado
//
function FormComboReload ( FormId, ClassId, FieldId ) {
 var myform = document.forms[FormId];

 var old_method = myform.elements['_'+ClassId+'.Method'].value;
 var old_btn    = myform.elements['_'+ClassId+'.Submit'].value;

 myform.elements['_'+ClassId+'.OK'].value = 'Fake';
 myform.elements['_'+ClassId+'.ReloadFieldId'].value = FieldId;
 myform.elements['_'+ClassId+'.Submit'].value = 'Aguarde...';
 myform.elements['_'+ClassId+'.Method'].value = 'AjaxCombo';

 var ajax = new Ajax( "POST", "Class.cgi", myform );

 var el;

 ajax.xmlhttp.onreadystatechange = function () {
  if ( ajax.ready() ) {
   try {
    var response = eval( ajax.request() );
    // Combo by combo
    for ( var i = 0; i < response.length; i += 2 ) {

     var Combo  = myform.elements[ response[i] ];
     var vCombo = myform.elements[ '_v.' + response[i] ];

     // Se combo for realmente um combo
     if ( Combo.type == "select-one" ) {
      Combo.options.length = 0;

      // The options of the combo
      for ( var ii = 2; ii < response[i+1].length; ii += 2 ) {
       var Option = document.createElement( "Option" );
       Option.value = response[i+1][ii];
       Option.text  = response[i+1][ii+1];
       Combo.options.add( Option );
      }

      // Selecionar valor anterior no atual se hï¿½alteraï¿½o e se ï¿½o ltimo nï¿½el...
      var lastVal = Combo.value;
      if ( response[i+1][0] != null &&
           Combo.value != response[i+1][0] &&
           i == response.length-2 ) Combo.value = response[i+1][0];
      if ( Combo.value == '' ) Combo.value = lastVal;
     // Se for um text
     } else if ( Combo.type == "text" ) {
      Combo.value = response[i+1][0];
     }

     // # Se houver um ValueInput
     if ( vCombo && vCombo.type == "text" ) {
      vCombo.value = Combo.value;
     }

    }
    myform.elements[ClassId+'.'+FieldId].disabled = false;
    if ( el.oldSrc != null ) {
     el.src = el.oldSrc;
    } else {
     el.style.display = 'none';
    }
   } catch ( e ) {
    alert( "FormComboReload: " + e );
   }
  }
 }

 if ( myform.elements[ClassId+'.'+FieldId].nextSibling != null && myform.elements[ClassId+'.'+FieldId].nextSibling.tagName == "IMG" ) {
  el = myform.elements[ClassId+'.'+FieldId].nextSibling;
  el.oldSrc = el.src;
 } else {
  el = document.createElement("IMG");
  myform.elements[ClassId+'.'+FieldId].parentNode.appendChild(el);
 }
 el.src = '/img/loading.gif';
 myform.elements[ClassId+'.'+FieldId].disabled = true;

 ajax.start();

 // Restore Form values
 myform.elements['_'+ClassId+'.OK'].value = '1';
 myform.elements['_'+ClassId+'.ReloadFieldId'].value = '';
 myform.elements['_'+ClassId+'.Submit'].value = old_btn;
 myform.elements['_'+ClassId+'.Method'].value = old_method;

}

//
// Adiciona uma imagem de 'loading' apos o elemento. Isso normalmente em botoes de submit, quando eh dado um submit.
// Se o elemento for um botao de submit, adicionalmente eh alterado o valor dele para 'Aguarde...'.
//
// @param Element DHTML Element a usar como base.
//
function appendLoadingImg (el) {
 var img = document.createElement("IMG");
 img.src = '/img/loading.gif';

 el.parentNode.appendChild(img);

 if ( el.type == 'submit' ) el.value = 'Aguarde...';

 return img;
}

//
// Essa eh uma funï¿½o generica para fazer uma requisiï¿½o HTTP e simplesmente
// executï¿½la como cï¿½igo javascript
//
// @param Metodo GET ou POST
//        myURL  URL a ser requisitada (POST)
//        params Parametros a serem passados (pode ser um form, array ou uma string)
//        el     (Opcional) elemento status
//
function requestURLeval( meth, myURL, params, el ) {
 var ajax = new Ajax( meth, myURL, params );

 ajax.xmlhttp.onreadystatechange = function () {
  if( ajax.ready() ){
   try {
    if (el)
     el.innerHTML = "";

    return eval( ajax.request() );
   } catch (e) {
    alert((moz ? e : e.description)+"\n\n"+ajax.request());
    return false;
   }
  }
 }

 if (el)
  el.innerHTML = el.clientWidth > 200 ?
   "<p class=loading><img src=/img/loading.gif> Carregando...</p>" :
   "<b class=loading_small><img src=/img/loading.gif></b>";

 ajax.start();
}

//
// Essa eh uma funï¿½o generica para fazer uma requisiï¿½o HTTP e simplesmente
// imprimila para o elemento especificado
//
// @param Metodo GET ou POST
//        myURL  URL a ser requisitada (POST)
//        params Parametros a serem passados (pode ser um form, array ou uma string)
//        Elem   Elemento DOM a ser utilizado (ï¿½o elemento, objeto, nï¿½ apenas o ID dele)
//        Once   Se verdadeiro, so faz a requisicao se o elemento de destino estiver vazio
//
function requestURL ( meth, myURL, params, el, once ) {

 var unique   = el.id + '@' + myURL;

 if ( el.nodeName == "TR" ) {
  el = el.childNodes[0];
 }

 if ( once && requestURLdone.contains( unique ) ) {
  return;
 } else {
  requestURLdone.push( unique );
 }

 var ajax = new Ajax( meth, myURL, params );
 var response;

 ajax.xmlhttp.onreadystatechange = function () {
  if ( ajax.ready() ) {
   el.innerHTML = ajax.request();

//
// Os elementos script nï¿½ sï¿½ interpretados pelo AJAX quando jogados no innerHTML
// de um outro elemento. A soluï¿½o encontrada forï¿½ essa interpretaï¿½o, retirando
// os elementos e inserindo um outro novo com o contedo do antigo.
//
// @author matheus cruz
// @date   2006-06-14
//

/*
  var script = el.getElementsByTagName("SCRIPT");

  for (var i = 0; i < script.length; i ++) {
//    alert( script[i].src + "\n" + script[i].text);
   var child    = script[i],
       _parent  = child.parentNode,
       oldchild = _parent.removeChild(child),
       newchild = document.createElement("SCRIPT");

   newchild.src  = oldchild.src;
   newchild.text = oldchild.text;
   _parent.appendChild(newchild);
  }*/

   for (var i = 0; i < el.childNodes.length; i ++) {
    var child = el.childNodes[i];

    if (child.nodeName != "SCRIPT") continue;

    var oldchild = el.removeChild(child);
    var newchild = document.createElement("SCRIPT");

    newchild.text = oldchild.text;
    el.appendChild(newchild);
   }

  }
 }

 // Se elemento for grande o suficiente...
 if ( el.clientWidth > 200 ) {
  el.innerHTML = "<p class=loading><img src=/img/loading.gif> Carregando...</p>";
 // Se elemento for pequeno...
 } else {
  el.innerHTML = "<b class=loading_small><img src=/img/loading.gif></b>";
 }

 ajax.start();
}

//
// Funcao utilizada pelo Form de Browse avanï¿½do, para trocar a ascendencia do ordenamento.
//
function BrowseFormOrderChange ( FormId, image ) {
 var myform = document.forms[FormId];

 if ( myform.elements['_' +  myform.elements['_ClassId'].value + '.OrderDesc'].value == 1 ) {
  myform.elements['_' + myform.elements['_ClassId'].value + '.OrderDesc'].value = 0;
  image.src = '/img/OrderDesc.gif';
 } else {
  myform.elements['_' + myform.elements['_ClassId'].value + '.OrderDesc'].value = 1;
  image.src = '/img/Order.gif';
 }
}

//
// Funï¿½o utilizada pelo Form de Browse avanï¿½do, para marcar ou desmarcar todos os checkbox
// conforme o checkbox superior.
//
// @param Element  checkbox superior.
//
function old______________check(Element){
 var vForm = Element.form;

 for( var x=0; x < vForm.elements.length; x++ ){
  if (vForm.elements[x].name == "_" + vForm.elements['_ClassId'].value + ".BrowseSequence"){
   vForm.elements[x].checked = Element.checked;
  }
 }
}

//
// Checa/uncheca todos os checkboxes com o nome especificado baseado em outro chackbox. Ambos devem estar no mesmo form.
//
// @param SrcChecbocElement Elemento/Objeto de origem (em geral eh um 'this')
//        InputName         Nome do Input escravo
//        Check             Opcional, verdadeiro ou falso
//
function slaveCheck( Element, InputName, ch ){
 if (Element.item) Element = Element[0];

 var vForm = Element.form;

 if ( ch == undefined ) ch = Element.checked;

 for( var x=0; x < vForm.elements.length; x++ ){
  if (vForm.elements[x].name == InputName ){
   vForm.elements[x].checked = ch;
  }
 }
}

//
// Verifica se a checkbox esta marcada ou nao (suporta multiplas ckeckboxes)
//
// @param  Element Elemento ou array de elementos
// @return BOOLEAN
//
function isChecked ( Element ) {

 if ( Element != undefined ) {
  if ( Element.nodeName == "INPUT" ) {
   return Element.checked;
  } else {
   try {
    for ( var x=0; x < Element.length; x++ ) {
     if ( Element[x].checked ) return true;
    }
   } catch (e) {}
  }
 }
 return false;
}

//
// Funï¿½o ultilizada no form de browse avanï¿½do.
// Desmarca todos os checkbox da coluna "G".
//
function uncheck(){
 vForm = document.body.firstChild;

 for( var x=0; x < vForm.elements.length; x++ ){
  if (vForm.elements[x].name == "_" + vForm.elements['_ClassId'].value + ".GroupBy"){
   vForm.elements[x].checked = false;
  }
 }

}

//
// Essa funï¿½o ï¿½chamada no mï¿½odo Browse, no contextmenu de qualquer campo do tipo date.
// Ela gera dois inputs com os labels "De" e "Atï¿½ para fazer a pesquisa no intervalo determinado nos campos.
// Os dois inputs gerados possuem mï¿½cara de data, limite de caracteres e o calendï¿½io que pode ser chamado
// clicando na imagem ao lado do input.
//
function createInputs(Field, pattern, mask) {
 Field.style.display = "none";
 pattern = pattern || '%d/%m/%Y';
 mask    = mask    || '99/99/9999';

 var vForm = Field.form;
 var Cell = Field.parentNode;
 var DataInicio = document.createElement("input");
 var DataFim = document.createElement("input");
 var NOBRDe = document.createElement("nobr");
 var NOBRAte = document.createElement("nobr");
 var ImgCalendarDe = document.createElement("img");
 var ImgCalendarAte = document.createElement("img");

 Cell.appendChild( NOBRDe );
 NOBRDe.appendChild( document.createTextNode( "De: " ) );
 NOBRDe.appendChild( DataInicio );
 NOBRDe.appendChild( ImgCalendarDe );
 Cell.appendChild( NOBRAte );
 NOBRAte.appendChild( document.createTextNode( " Até: " ) );
 NOBRAte.appendChild( DataFim );
 NOBRAte.appendChild( ImgCalendarAte );

 ImgCalendarDe.src = "/img/Interface/Calendar.gif";
 ImgCalendarDe.onclick = function() { return showCalendar(this.previousSibling, pattern) };
 ImgCalendarAte.src = "/img/Interface/Calendar.gif";
 ImgCalendarAte.onclick = function() { return showCalendar(this.previousSibling, pattern) };

 with( DataInicio ){
  id = Field.name +".Inicio";
  name = Field.name + ".Inicio";
  className = "btn";
  style.width = "80px";
 }
  DataInicio.onkeypress = function(e) {
   e = document.all ? window.event : e;
   return NumberOnly(e);
  };
  DataInicio.onkeyup = function(e) { return Mask(this, mask, e); };

 with( DataFim ){
  id = Field.name + ".Fim";
  name = Field.name + ".Fim";
  className = "btn";
  style.width = "80px";
 }
 DataFim.onkeypress = function(e) {
  e = document.all ? window.event : e;
  return NumberOnly(e);
 };
 DataFim.onkeyup = function(e) { return Mask(this, mask, e); };

 return false
}

//
// Cria uma string com um perï¿½do de datas, caso sejam informadas as 2 datas.
// Utilizada pela funï¿½o createInputs no mï¿½odo browse.
//
// @param dateOne Primeira data (ex.: data inï¿½io).
//        dateTwo Segunda data (ex.: data fim).
// @return dateOne + " - " + dateTwo As datas concatenadas, no caso de ter sido informado as duas datas.
//         dateOne + dateTwo         A data que foi informada, caso somente uma tenha sido.
//
function returnDate( dateOne, dateTwo ){
 if ( dateOne.length >= 1 && dateTwo.length >= 1) {
  return dateOne + " - " + dateTwo;
 } else {
  return dateOne + dateTwo;
 }
}

//
// Esta funï¿½o completa os campos Estado, Cidade, Bairro e Logradouro quando o CEP ï¿½informado.
// @param myForm      Nome do formulï¿½io.
//        CEP         Nome do campo CEP.
//        State       Nome do campo onde deve ser preenchido o estado.
//        City        Nome do campo onde deve ser preenchida a cidade.
//        Bairro      Nome do campo onde deve ser preenchido o bairro.
//        Logradouro  Nome do campo onde deve ser preenchido o logradouro.
//        Element     O elemento que estï¿½chamando a funï¿½o (this).
//
function completeAddress(myForm, CEP, Country, State, City, Bairro, Logradouro){
 Element = document.forms[myForm].elements[CEP];
 Element.Count = Element.Count == undefined ? 0 : (Number(Element.Count) + 1);

 var vCountry = document.forms[myForm].elements[Country].value;
 var vCEP = document.forms[myForm].elements[CEP].value.replace(/\D/g, '');

 requestURLeval('POST','/Html/Ajax/CEP.cgi',[ ['myForm','CEP','vCEP','Country','vCountry','State','City','Bairro','Logradouro','Count'],[myForm,CEP,vCEP,Country,vCountry,State,City,Bairro,Logradouro,Element.Count] ]);

}

//
// Move as linhas de uma tabela para cima ou para baixo conforme o valor recebido.
// Funï¿½o usada no form avanï¿½do de Browse que trata se a classe da linha a ser movida
// for algum tipo de cabeï¿½lho, ele nï¿½ move.
// @param  Element  O elemento que estï¿½chamando a funï¿½o (this).
//         pos      A posiï¿½o para qual deve ser movido 1 = "para cima" 0 = "para baixo"
//
function move(Element, pos){
 var Row = Element.parentNode.parentNode;
 var cloneRow = Row.cloneNode(true);
 var Table = Row.parentNode;

 var rowAround = pos == 0 ? Row.nextSibling : ( pos == 1 ? Row.previousSibling : undefined );

 if( rowAround != undefined && rowAround.className != "row_mid" && rowAround.className != "row_top" ) {
  var cloneAround = rowAround.cloneNode(true);

  var RowOldChecked = Row.firstChild.firstChild.checked;
  var AroundOldChecked = rowAround.firstChild.firstChild.checked;

  with(Table){
   replaceChild( cloneRow, rowAround );
   replaceChild( cloneAround, Row );
  }

  cloneRow.firstChild.firstChild.checked = RowOldChecked;
  cloneAround.firstChild.firstChild.checked = AroundOldChecked;
 }

}

//
// Move row (ou row parente do elemento) para a primeira posicao da tabela.
//
// @see   findParentElement( Element, Name )
// @param Element Elemento (processado com o findElement(Element,'TR'))
//
function moveTop (Element) {
 var Row = findParentElement( Element, "TR" );

 var cloneRow = Row.cloneNode(true);
 var Table = Row.parentNode;

 var rowAround = Table.firstChild;

 if( rowAround != undefined && rowAround.className != "row_mid" && rowAround.className != "row_top" ) {
  var cloneAround = rowAround.cloneNode(true);

  var RowOldChecked = Row.firstChild.firstChild.checked;
  var AroundOldChecked = rowAround.firstChild.firstChild.checked;

  with(Table){
   insertBefore( Row, rowAround );
  }

  cloneRow.firstChild.firstChild.checked = RowOldChecked;
  cloneAround.firstChild.firstChild.checked = AroundOldChecked;
 }

}

//
// Processa recursivamente os parentNodes do elemento ate achar um elemento do tipo especificado.
// Este metodo eh extremamente util para encontrar, por exemplo, o TD ou TR onde determinado elementos
// esta contido. Alem disso, eh seguro tambem, devendo ser uma alternativa melhor que usar apenas o previousSibleng/parentNode
//
// @param  Elemento
//         Tipo do elemento: TR, TD, etc
// @return Elemento do tipo especificado ou undefined
//
function findParentElement ( Element, Name ) {
 if ( Element.parentNode != null ) {
  if ( Element.parentNode.nodeName == Name ) {
   return Element.parentNode;
  } else {
   return findParentElement( Element.parentNode, Name );
  }
 } else {
  return null;
 }
}

//
// Soma ou concatena ao valor do elemento o valor passado.
//
// @param Element
//        StringNumber
//
function sumAppend ( el, number ) {
 el.value = el.value*1 + number*1;
}

//
// Trata para que o campo sï¿½permita .(ponto), nmeros e teclas 0 do onkeypress (aï¿½es).
// Quando ï¿½digitado .(ponto), verifica se o ltimo caracater digitado nï¿½ foi um ponto ou se a string jï¿½contï¿½ 3 pontos,
// em caso verdadeiro retorna false (impede).
// Deve ser chamado no evento onkeypress...
//
// @param Field  O campo que deve receber o tratamento.
//        e      event.
//
function inetPress(Field, e){

 if( !/[.]/.test(String.fromCharCode(KeyCode(e))) &&
     !/[0-9]/.test(String.fromCharCode(KeyCode(e))) &&
     KeyCode(e) != 8 && KeyCode(e) != 0 ) {
  return false;
 } else if( /[.]/.test(String.fromCharCode(KeyCode(e))) &&
           ( Field.value.findChar(".") >= 3 || Field.value.charAt(Field.value.length-1) == "." ) ) {
  return false;
 }
}

//
// Faz a mï¿½cara do campo inet.
// Deve ser chamado no evento onkeyup
//
function inetUp(Field, e) {
 var pos = Field.value.split(".");

 if( KeyCode(e) != 8 && KeyCode(e) != 37 && KeyCode(e) != 38 && KeyCode(e) != 40 ) {

  for( var i=0; i < pos.length +1; i++ ) {
   if( pos[i] > 255 ) {
    pos[i] = pos[i].substr(0, pos[i].length-1);
   }
  }

  Field.value = pos.join(".");

  // Se a tecla for "->" e o timo caracter nï¿½ for um ponto e a string nï¿½ contï¿½ mais de 3 pontos, concatena um ponto.
  if( KeyCode(e) == 39 && Field.value.charAt(Field.value.length-1) != "." && Field.value.findChar(".") < 3 ) {
   Field.value = Field.value + ".";
  }
  // Se a ltima posiï¿½o do array tiver 3 caracteres e a string tiver menos de 3 pontos, concatena um ponto.
  if( pos[pos.length-1].length == 3 && Field.value.findChar(".") < 3 ) {
   Field.value += ".";
  }

 }
}

//
// Mostra no evento oncontextmenu de cada linha do browse uma div com opï¿½es referentes ao registro da linha.
// Ex.: Editar, Visualizar, Excluir...
// @param nameForm Nome do formulï¿½io
//        e        event
//        PKs      Uma hash com as primary keys da classe.
// @return False   retorna false para nï¿½ mostrar o menu padrï¿½ do browser.
//
function ShowMenuBrowse(nameForm, e, PKs) {
//  var DivForm = document.getElementById('Div' + nameForm);
 var Form    = document.forms[nameForm];
 var PForm   = document.forms['P'+nameForm];
 var Class   = Form.elements["_ClassId"].value;

 var k = [];
 var v = [];

 // Para operaï¿½es de Paste
 if ( copy_from_formid &&
      document.forms[copy_from_formid] != undefined &&
      ( parseInt(document.forms[copy_from_formid].elements['_Level'].value) == (parseInt(PForm.elements['_Level'].value)+1) ||
        ( document.forms[copy_from_formid].elements['_Level'].value == PForm.elements['_Level'].value && document.forms[copy_from_formid].elements['_ClassId'].value == PForm.elements['_ClassId'].value ) ) ) {
  var q = new QueryString(PKs);
  document.forms[copy_from_formid].elements['_copyTo'].value =
   '_ClassId=' + Class + '&' +
   '_Level='   + Form.elements['_Level'].value + '&' +
   q.toString();

   k.push( 'New' , 'Paste', 'Cancel', 'SelectAll', 'Copy', 'Move', 'Delete' );
   v.push( 'none' , '', '', 'none', 'none', 'none', 'none' );

 // Nao ha nenhum form de transferencia ou nao eh possivel fazer a transferencia
 } else {
   k.push( 'New' , 'Paste', 'Cancel', 'SelectAll' );
   v.push( '' , 'none', 'none', '' );

   // Se tiver alguma coisa chcada, permite aï¿½umas aï¿½es
   k.push( 'Move', 'Copy', 'Delete' );
   if ( isChecked( PForm.elements['_'+PForm.elements['_ClassId'].value+'.MSelect'] ) ) {
    v.push( '','','' );
   // Se nada estiver checado, oculta aï¿½es
   } else {
    v.push( 'none','none','none' );
   }
 }

 for ( var x = 0; x < k.length; x++ ) {
  try {
   if ( document.getElementById(k[x]+nameForm) != undefined ) document.getElementById(k[x]+nameForm).style.display = v[x];
  } catch (e) { }
 }


 for( var k in PKs ){
  Form.elements[Class + "." + k].value = PKs[k];
 }

//  alert( window.parent.frames("Top").document.body.clientHeight);
 var Y = document.all ? ( document.documentElement.scrollTop - 45 ) : window.scrollY;
 var X = document.all ? document.documentElement.scrollLeft : window.scrollX;

 /*DivForm.style['float'] = "left";

 try {
  with( DivForm.style ) {
   position   = "absolute";
   top        = (e.clientY + Y)+ "px";
   left       = (e.clientX + X)+ "px";
   display    = document.all ? "block" : "table";
   visibility = "visible";
  }
 } catch (e) {
  alert(e.description);
 }

 ControlerMenuPopUp(DivForm);*/
 ContextMenu._show("ContextMenu-"+nameForm, e);
 return false;
}


//
// Controla as aï¿½es principais de um menu PopUp.
// Percorre os elementos do menu a partir de onde foi clicado e se encontrar um link ele esconde o menu...
// @param Element O elemento que ï¿½o menu (div).
//
function ControlerMenuPopUp(Element) {
 document.currentPopUp = Element;

 if(!document.onclick)
  document.onclick = function(e) {
   e = document.all ? window.event : e;
   var Element = document.all ? e.srcElement : e.target;
   var flag    = true;

   while (Element.parentNode != null) {
    if( Element.tagName == "A" ) {
     this.currentPopUp.style.display = "none";
     break;
    } else {
     Element = Element.parentNode;

     if (Element == this.currentPopUp) {
      flag = false;
      break;
     } else if (Element == this.currentPopUp.parentNode) {
      break;
     }
    }
   }

   if (flag)
    this.currentPopUp.style.display = "none";
  }
}

//
// Seta value para campos de um formulï¿½io.
// @param Form   Nome do formulï¿½io
//        Hash   Uma hash com o nome e o value em cada chave e valor da hash (ex.: { Nome: 'Valor', Nome2: 'Valor2' } )
//        Submit boolean para submeter o formulï¿½io apï¿½ executar a funï¿½o... true submete, false nï¿½ submete.
//        target novo target somente para esta submissï¿½. Apï¿½ isso, o form adquire seu target antigo.
//               Util para enviar requisiï¿½es para outras janelas/pop-ups.
//
function setValue (Form, Hash, Submit, target) {
 var Form  = document.forms[Form], oldTarget;
 var hbval = {};

 // Guarda valores antigos
 for( var k in Hash ){
  hbval[k] = Form.elements[k].value;
 }

 // Seta valores novos
 for( var k in Hash ){
  Form.elements[k].value = Hash[k];
 }

 if (Submit) {
  if(target) {
   oldTarget   = Form.target;
   Form.target = target;
  }

  try { Form.onsubmit(); } catch (e) {};
  Form.submit();

  Form.target = oldTarget;
 }

 return hbval;
}


//
// Desloca as row de uma tabela para a posiï¿½o desejada e arrasta todas as outras junto - organizadamente.
//
// @param table      Objeto da tabela
//        rowIndex   Index original da rowAround
//        rowIndexTo Index de destino
//
function reorder ( table, rowIndex, rowIndexTo ) {
 var rows = table.rows;
 var skew = parseInt(parseInt(rowIndexTo) - parseInt(rowIndex));
 var newRows = [];

 for ( var i = 0; i < rows.length; i++ ) {
  if ( i + parseInt(skew) > rows.length-1 ) {
   newRows[i+parseInt(skew)-rows.length] = rows[i].innerHTML;
  } else {
   newRows[i+parseInt(skew)] = rows[i].innerHTML;
  }
 }document.all ? ( document.documentElement.scrollTop - 45 ) : window.scrollY;

 for ( var i = 0; i < rows.length; i++ ) {
  rows[i].innerHTML = newRows[i];
 }

}

/*
 Checa se o interval estÃ¡ em formato vÃ¡lido...
 @param Value Valor do campo interval
*/
function checkInterval(Value){
 return /^\d+:\d+(:\d+)?$/.test(Value);
}

/*
 FormataÃ§Ã£o para campos interval...  Permite somente nÃºmeros, 2 dois pontos (:) na string e teclas de navegaÃ§Ã£o...
 Deve ser chamado no onkeyup...
 @param Value Valor que estÃ¡ no campo.
        e     event
*/
function formatInterval(Value, e) {
 if( !/\d|[:]/.test(KeyChar(e)) && ![0,8,13].contains(KeyCode(e)) ){
  return false;
 } else if( /[:]/.test(KeyChar(e)) ) {
  if( Value.length == 0 || Value.charAt(Value.length-1) == ":" || Value.findChar(":") > 1 ) {
   return false;
  }
 }
}

/*
 FormataÃ§Ã£o para campos float... Permite somente nÃºmeros, 1 ponto (.) na string e teclas de navegaÃ§Ã£o...
 Deve ser invocado no onkeyup...
 @param Value Valor que estÃ¡ no campo.
        e     event
*/
function formatFloat( Value, e ){
 if( !/\d|[\.]/.test(KeyChar(e)) && ![0,8,13].contains(KeyCode(e)) ){
  return false;
 } else if( /[\.]/.test(KeyChar(e)) && Value.findChar(".") >=  1 ) {
  return false;
 }
}

function moveTHead (Table) {

 if( !Table.OSTop ){
  Table.OSTop = Table.rows[0].offsetTop;
 }
 var Y = moz ? window.scrollY : document.documentElement.scrollTop;

 var Ypos;
 if( document.documentElement.scrollTop != 0 ) {
  Ypos = moz ? ( Y - Table.OSTop ) + "px" : ( Y - Table.OSTop - 45 );
 } else {
  Ypos = Table.OSTop - 22;
 }

 Table.rows[0].style.top = Ypos;
 Table.rows[1].style.top = Ypos;

}

function popDoubleInsert () {
 var el = window.open('','_blank','');
// el.document.write('<body id=teste>TESTE!!!</body>');
 requestURL('GET','/Ultra/'+getSession()+'/Class.cgi','_ClassId=tbMovimentacaoFinanceira&_tbMovimentacaoFinanceira.Method=Insert',el.document,0);
}
