//      basico2 1.0.3 - 2008-08-01
//
//      por diego nunes - dn[em]dnunes.com
//  (cc) Conteúdo sob licença Creative Commons
//http://creativecommons.org/licenses/by-sa/3.0/

function insertBefore(tN, nN) { /* tNode, newNode */ return tN.parentNode.insertBefore(nN, tN); }
function insertAfter(tN, nN) { /* tNode, newNode */ var tP=tN.parentNode;
  do { tN=tN.nextSibling; } while (tN && tN.nodeType != 1);
  if (tN) { tP.insertBefore(nN, tN); } else { tP.appendChild(nN); } return tP.childNodes.length;
}
function childsOfType(tO, tT) { /* object, <string/arr tTag(s)> */ var i, n, tCs, tR=[]; if (!tO) { return false; }
  tT=new RegExp( (tT instanceof Array) ? tT.join('|') : tT , 'i'); tCs=tO.childNodes; if (!tCs) { return []; }
  for (i=0, n=tCs.length; i<n; i++) {
    if (tCs[i].nodeType==1 && tT.test(tCs[i].nodeName.toLowerCase())) { tR[tR.length]=tCs[i]; }
  } return tR;
}
function firstParentOfType(tO, tT) { /* <node tObject>, <string/arr tTag(s)> */
  tT=new RegExp( (tT instanceof Array) ? tT.join('|') : tT , 'i');
  while (tO && (tO.nodeType != 1 || !tT.test(tO.nodeName.toLowerCase()))) { tO=tO.parentNode; }
  return tO || false;
}
function isDescendantOf(tO, tT) { while ((tO=tO.parentNode)) { if (tO == tT) { return true; } } return false; }

function gE(tI, tDoc) { var d=tDoc || document, r=[], n, i;
  if (tI instanceof Array) { for (n=tI.length, i=0; i<n; i++) { r[r.length]=gE(tI[i]); } return r; }
  else { return (d.getElementById && d.getElementById(tI)) || (d.all && d.all[tI]); }
}
function makeArray(collection, forceNumeric) { var i=0, v, r=[];
  for (v in collection) { if (forceNumeric && (v=='length' || v=='item' || v=='namedItem')) { continue; }
    r[((forceNumeric)?i++:v)]=collection[v];
  } return r;
}
function gFETN(tTn, tFs, isER, rE, justChilds) {
  //getFilteredElements[by]TagName: <str TagName> [, str/arr theFilters [, bool isERFilter [, object rootElement]]]
  //Se o quarto parâmetro for enviado, a função só retornará elementos descendentes de _rootElement_.
  //O quinto parâmetro, _justChilds_, faz a função só retornar filhos diretos do elemento estabelecido em _rootElement_.
  var tEs, i, n, ii, nn, passed, tF, tER, tR=[];
  if (rE && justChilds) { tEs=childsOfType(rE, tTn); } else { tEs=(rE || document).getElementsByTagName(tTn); }
  if (!tFs) { return tEs.length ? makeArray(tEs, 1) : false; } if (typeof(tFs) == 'string') { tFs=[tFs]; }
  for (n=tEs.length, i=0; i<n; i++) { passed=1;
    for (nn=tFs.length, ii=0; ii<nn; ii++) { tF=tFs[ii].split('=');
      if (isER) { tER=new RegExp(tF[1], 'g'); if (!tER.test(tEs[i][tF[0]])) { passed=0; } }
      else { if (tEs[i][tF[0]] != tF[1]) { passed=0; } }
    } if (passed) { tR[tR.length]=tEs[i]; /* compatÃ­vel com IE5.1 */ }
  }
  return tR.length ? tR : false;
}
var createNamedElement=function (){}; //Cria elemento com "name" -- cross-browser
(function () {
  try {
    var nE=document.createElement('<div name="foo">'); //Jeito esquisitão do IE criar objetos com "name"
    if (nE.tagName != 'DIV' || nE.name != 'foo') { /* força o "catch" */ throw 'create element error'; }
    //Se passou do passo acima, estamos em um navegador que usa o "jeito IE", então criamos a função de acordo
    createNamedElement = function (tT, tN) {
      return document.createElement('<'+ tT +' name="'+ tN +'"></'+ tT +'>');
    };
  } catch (e) { //Forma bonita e funcional, como deveria sempre ser
    createNamedElement = function (tT, tN) { var newEl;
      return ((newEl=document.createElement(tT)) && (newEl.name=tN) && newEl);
    };
  }
})();
function cTN(tV) { return (tV && document.createTextNode && document.createTextNode(tV)); }
function cE(tN, tPs, tC) { // createElement 3.3 -- <str tagName> [, str/arr tProperties] [, str/obj conteúdo]
  //Essa função, se chamada com 2 parâmetros, os assumirá como "tN" e "tC", e não "tN" e "tPs".
  if (!document.createElement) { return false; } var nE, tER, i, n, tP; nE=document.createElement(tN);
  if (arguments.length > 1) { if (arguments.length == 2) { tC=tPs; tPs=[]; } if (typeof(tPs) == 'string') { tPs=[tPs]; }
    if (tPs && tPs.length > 0) { //Caso tenha propriedades, procurar por "name".
      var tNA=0; for (n=tPs.length, i=0; i<n; i++) { tP=tPs[i].split('=');
        if (tP.shift().toLowerCase() == 'name') { tNA=tP.join('='); tPs.splice(i--, 1); n--; }
      } //Para criar um elemento com "name" é preciso um tratamento devido a um bug no IE
      if (tNA) { nE=createNamedElement(tN, tNA); } //Ver "createNamedElement".
    }
    for (n=tPs.length, i=0; i<n; i++) { tP=tPs[i].split('='); //O atributo "class" tem diferenças de interpretação, então
      if (tP[0] == 'class' || tP[0] == 'className') { tP.shift(); nE.className=tP.join('='); } //uso a propriedade "className"
      else { nE.setAttribute(tP.shift(), tP.join('=')); } //Todos os outros são definidos com o "setAttribute" do DOM.
    }
    if (tC) { i=0;
      if (tC instanceof Array) { for (n=tC.length; i<n; i++) {
        nE.appendChild( (typeof(tC[i])=='string') ? cTN(tC[i]) : tC[i] );
      } } else { nE.appendChild( (typeof(tC)=='string') ? cTN(tC) : tC ); }
    }
  } return nE;
}
function rEs(tO) { var i, n; if (!tO) { return false; } //RemoveElements
  if (!tO.nodeName) { if (!tO.length) { return false; }
    for (n=tO.length; n--;) { if (!rEs(tO[n])) { return false; } } return true;
  } else { tO.parentNode.removeChild(tO); return true; }
}

function basicBinding(tM, tO, tPs) { return (function () { return tM.apply(tO, tPs); }); }
function bindAsEventListener(tM, tO) { return (function (e) { return tM.call(tO, e); }); }

var tEvs={ //0.0.0.1.0 beta3 build38743
  'uniqueObjID': 1,
  'evs': {'byEvID': []},
  'add': function (tO, tE, tF) { if (!tO) { return false; }
    //Como o JS não tem um XOR, usei essa lógica esquisita pra emular
    if (!(tO instanceof Array) != !(tE instanceof Array)) { //Aceitar múltiplos objetos e/ou múltiplos eventos
      if (!(tO instanceof Array)) { tO=[tO]; } else { tE=[tE]; }
    }
    if (tO instanceof Array) { var n, nn, returnArr=[];
      for (n=tO.length; (n--)>0; n) { for (nn=tE.length; (nn--)>0; ) {
        if (!(returnArr[returnArr.length]=tEvs.add(tO[n], tE[nn], tF))) { return false; }
      } }
      return returnArr;
    }
    //Armazenar referência ao evento de duas formas: com base no ID ou com base no objeto + nome do evento
    var objID=((tO.evsID) ? tO.evsID : (tO.evsID=(tEvs.uniqueObjID++))), curID, curN;
    if (!tEvs.evs[objID]) { tEvs.evs[objID]=[]; } if (!tEvs.evs[objID][tE]) { tEvs.evs[objID][tE]=[]; }
    curID=tEvs.evs['byEvID'].length; curN=tEvs.evs[objID][tE].length;
    tEvs.evs[objID][tE][curN]=tEvs.evs['byEvID'][curID]={'tO': tO, 'tE': tE, 'tF': tF, 'n': curN };

    //Adicionar o evento, efetivamente
    if (tO.addEventListener) { tO.addEventListener(tE, tF, false); }
    else if (tO.attachEvent) { tO.attachEvent('on'+tE, tF); }
    else { tO['on'+ tE]=tF; return false; }
    return curID;
  },

  'remove': function (tO, tE, tF) { if (arguments.length > 1 && !tO) { return false; }
    //Enviando ID(s)
    if (arguments.length == 1) { var tIDs=tO, n, i, tEv;
      if (!(tIDs instanceof Array)) { tIDs=[tIDs]; } //Suporte a múltiplos IDs de uma vez
      for (n=tIDs.length, i=0; i<n; i++) { tEv=tEvs.evs['byEvID'][tIDs[i]];
        if (!tEv) { continue; } //Evento inexistente
        tO=tEv['tO']; tE=tEv['tE']; tEvs.remove(tO, tEv['tE'], tEv['tF']);
        //Caso as referências ao evento estejam na lista do "evs", apagá-las
        if (tO.evsID && tEvs.evs[tO.evsID] && tEvs.evs[tO.evsID][tE] && tEvs.evs[tO.evsID][tE][tEv['n']]) {
          try { delete(tEvs.evs[tO.evsID][tE][tEv['n']]); delete(tEvs.evs['byEvID'][tIDs[i]]); }
          catch(e) { tEvs.evs[tO.evsID][tE][tEv['n']]=null; tEvs.evs['byEvID'][tIDs[i]]=null; }
        }
      }
      return true;
    }
    //Remover o evento (finalmente...)
    if (tO.removeEventListener) { tO.removeEventListener(tE, tF, false); }
    else if (document.detachEvent) { tO.detachEvent('on'+ tE, tF); }
    else { tO["on"+ tE] = null; }
    return true;
  }
};

function getEv(e) { return e || (window.event ? window.event : false); }
function getSrc(e) { var ev=getEv(e); if (!ev) { return false; }
  return ev.target || ev.srcElement;
}
function getKeyCode(e) { var ev=getEv(e); return ev && (ev.which || ev.keyCode || false); }
function getMouseButton(e) { var ev=getEv(e); var z=0, keymap=[];
  if (typeof(ev.which) != 'undefined') { z=ev.which; //KMOS
    keymap[1]='left'; keymap[2]='middle'; keymap[3]='right'; }
  else if (typeof(ev.button) != 'undefined') { z=ev.button; //M$
    keymap[1]='left'; keymap[4]='middle'; keymap[2]='right'; }
  else { return false; } return keymap[z];
}
function poin(e) { var ev=getEv(e); if (!ev) { return false; }
  if (ev.preventDefault) { ev.preventDefault(); } ev.returnValue=false; return false;
}
function poinplus(e) { var ev=getEv(e); if (!ev) { return false; }
  if (ev.stopPropagation) { ev.stopPropagation(); } ev.cancelBubble = true; return poin(e);
}
function valorValido(tV) { /* theValue */ return new RegExp('[a-z0-9]','gi').test(tV); }
function RETest(tER, tV, tFs) { /* tRegExp, tValue, tFlags */ return new RegExp(tER, tFs || '').test(tV); }

function sW(tS, sS) { /* (Bool) startsWith: theString, subString */
  return (tS && sS && tS.substring(0,sS.toString().length) == sS.toString()) ? true : false;
}
function hasTok(tokList, tTok, tDiv) { var n, i, tToks=tokList.split(tDiv || ' ');
  for (n=tToks.length; n--; ) { if (tToks[n] == tTok) { return true; } } return false;
}
function addTok(tokList, tTok, tDiv, duplicate) { tDiv=tDiv || ' ';
  if (hasTok(tokList, tTok, tDiv) && !duplicate) { return tokList; }
  return ((tokList) ? (tokList + tDiv) : '') + tTok;
}
function remTok(tokList, tTok, tDiv) { if (!tokList) { return ''; } var n, i, tRs=[]; tDiv=tDiv || ' ';
  var tToks=tokList.split(tDiv);
  for (n=tToks.length, i=0; i<n; i++) { if (tToks[i] != tTok) { tRs[tRs.length] = tToks[i]; } }
  return tRs.length ? tRs.join(tDiv) : '';
}
function getStyle(tO, tS) { /* tObject, tStylename */
  if (window.getComputedStyle) { return window.getComputedStyle(tO, null).getPropertyValue(tS); }
  else if (tO.currentStyle) { var tER=new RegExp('^([^\-]+)\-([a-z])(.*)$');
    tS=tS.replace(tER, '$1') + tS.replace(tER, '$2').toUpperCase() + tS.replace(tER, '$3');
    return tO.currentStyle[tS];
  }
  return false;
}
function round(tN, n) { var tP=Math.pow(10, n); return Math.round(tN * tP) /tP; }
function getElementPos(tE) { if (!tE) { return false; } var tR={x: 0, y: 0};
  do { tR.x+=tE.offsetLeft; tR.y+=tE.offsetTop; tE=tE.offsetParent; }
  while (tE && tE.nodeName.toLowerCase() != 'body'); return tR;
}
function getScrollPos(tE) {
  return (typeof(tE.scrollTop) == 'undefined') ? false : {'x': tE.scrollLeft, 'y': tE.scrollTop};
}
function setScrollPos(pos, tE) {
  if (!tE) { tE=document;
    if (tE.documentElement && tE.documentElement.scrollTop) { tE=tE.documentElement; }
    else if (tE.body) { tE=tE.body; }
  }
  if (tE && typeof(tE.scrollLeft) != 'undefined') {
    if (typeof(pos.x) != 'undefined') { tE.scrollLeft=pos.x; }
    if (typeof(pos.y) != 'undefined') { tE.scrollTop=pos.y; }
    return true;
  } else { return false; }
}
function getPageSize() { var size1=document.body.scrollHeight; var size2=document.body.offsetHeight;
  if (size1 > size2) { return {'x': document.body.scrollWidth, 'y': document.body.scrollHeight}; /* all but Explorer Mac */ }
  else { return {'x': document.body.offsetWidth, 'y': document.body.offsetHeight}; /* Explorer Mac */ }
}
function getViewportSize(tW) { var ret=[]; tW=tW || window;
  if (tW.innerWidth) { return {'x': tW.innerWidth, 'y': tW.innerHeight}; }
  else if (tW.document.documentElement && tW.document.documentElement.clientWidth) {
    return {'x': tW.document.documentElement.clientWidth, 'y': tW.document.documentElement.clientHeight};
  }
  else if (tW.document.body) { return {'x': tW.document.body.clientWidth, 'y': tW.document.body.clientHeight}; }
  else { return false; }
}
function getEventXY(e) { // Retornar a posição X/Y da ocorrência de um evento
  if (e.pageX && e.pageY) { return {'x': e.pageX, 'y': e.pageY }; }
  else if (e.clientX && e.clientY)  {
    var posx=e.clientX +document.body.scrollLeft +document.documentElement.scrollLeft;
    var posy=e.clientY +document.body.scrollTop  +document.documentElement.scrollTop;
    return {'x': posx, 'y': posy };
  } return false;
}
