  window.onload = function() {
   Tabela.inicia(); 
  }

  /**
  * Funcoes de ordenacao e selecionamento de tabelas
  * Parametros da tabela:
  * a tabela já possui o parametro sort por padrao
  *
  * Parametros da td do cabecalho:
  *
  *    abbr = "string" // abbr de dados string, este dado será default caso não haja o abbr definido.
  *    abbr = "date"  // abbr data.
  *    abbr = "number" // abbr número
  *    abbr = "float" // abbr ponto flutuante
  *    abbr = "img" // abbr imagem
  *
  * Funcao que retorna as tr's selecionadas: getselect
  *
  * Exemplo da tabela:
  *  <table id="listagem">
  *  <thead>
  *    <tr><th abbr="string">Cabeçalho</th></tr>
  *  </thead>
  *  <tbody>
  *    <tr><td>hohohoho</td></tr>
  *  </tbody>
  *  </table>
  *
  * Alexandre Gans - alexandregans@gmail.com - 2005/02/10
  * Implementado por Alessandro Hegler - hegler87@gmail.com - 2005/10/06
  */


  var reverse   = false; // Variavel global
  // dd/mm/yyyy
  var regDia = /(\d{2,2})(?:\/)/;
  var regMes = /(?:\/)(\d{2,2})(?:\/)/;
  var regAno = /(?:\/)(\d{4,4})/;
  var tableFocus = null; // Id da tabela que obtem o focus ao clicar

  /*Construtor do objeto Tabela*/
  Tabela = new Object;

  /**
  * Inicializador das tabelas. Verifica a existencia das tabelas e se existe o parametro sort.
  */
  Tabela.inicia = function()
  {
      var tbls   = document.getElementsByTagName('table');
      var tables = new Array();

      for(var x = 0; x < tbls.length; x++)
          if(tbls[x].id.toLowerCase() == 'listagem') tables[tables.length] = tbls[x];

      if(tables.length != 0)
      {
          for (var t = 0; t < tables.length; t++)
          {
              tables[t].setAttribute('reverse', false);
              tables[t].setAttribute('lastclick', -1);

               /* Sort */
               var tbody   = tables[t].getElementsByTagName('tbody')[0];

               thead = tables[t].getElementsByTagName('thead')[0];
               if (thead)
               {
                   theadrow = thead.getElementsByTagName('tr')[0]; //Assume que o THEAD possui somente uma row

                   if (theadrow.tagName.toLowerCase() == 'tr')
                   {
                       var l, clickCell, colCount;
                       clickCell = theadrow.getElementsByTagName('th');
                       colCount  = clickCell.length;

                       for (var i = 0; i < colCount; i++) // Cria a imagem transparente
                       {
                           if ((clickCell[i].tagName.toLowerCase() == 'th')&&(clickCell[i].getAttribute('abbr') == 'disable')) null;
                           else
                           {
                               span           = document.createElement('span');
                               span.innerHTML = '&nbsp;';
                               clickCell[i].setAttribute('selectIndex', i);
                               clickCell[i].style.cursor = 'pointer';
                               clickCell[i].appendChild(span);
                               if(window.attachEvent) 
                                   clickCell[i].attachEvent("onclick", doClick); //IE
                               else if (window.addEventListener) 
                                   clickCell[i].addEventListener("click", doClick, false);
                           }
                       }
                   }
               }
          }
      }
  }


  /**
  * Pega o evento onclick da tabela e seleciona
  *
  * @param e: evento onclick
  * @type: objeto
  */
  function doClick(e)
  {
      if (!e) return;
      var clickObject = false;
      if (e.srcElement)  clickObject = e.srcElement; // IE
      else if (e.target) clickObject = e.target;
      else if (e.tagName) clickObject = e;

      if (!clickObject) return;

      /*
       * Eu verifico se o objeto atingido é um SPAN, com
       * isso eu pega o pai no SPAN, que no caso é uma TH, 
       * que é o objeto que deve ser trabalhado.
       */
      var th = clickObject;

      if (th.tagName.toLowerCase() == 'span') th = th.parentNode;

      while (clickObject.tagName.toLowerCase() != 'table') clickObject = clickObject.parentNode;
      while (th.tagName.toLowerCase() != 'th') th = th.parentNode;

      var abbr = th.getAttribute('abbr');
      abbr = abbr ? abbr:'string';
      
      var thIndex  = restoreImg(clickObject, th); // chama a funcao que muda o sort.
      thead        = clickObject.getElementsByTagName('thead')[0];
      tbody        = clickObject.getElementsByTagName('tbody')[0];
      
      var sortedTr = new Array(); // Os valores da td em cada tr com seus valores já sorteados.
      var sortTr   = new Array(); // Os valores originais das td's.
      var resultTr = new Array(); // Guarda os index's do sort.
      var copyTr   = new Array();
      
      var ths = thead.getElementsByTagName('th')
      var trs = tbody.getElementsByTagName('tr')

      for (var i = 0; i < ths.length; i++)
      {
          if (ths[i].getAttribute('abbr') != 'disable')
          { 
              if (ths[i].cellIndex == thIndex) ths[i].className = 'selecionado';
              else ths[i].className = '';
          }
          else null;
      }
      
      for (var i=0; i < trs.length; i++)
          copyTr[copyTr.length] = trs[i] //.cloneNode(true); // Copia das Tr's da tabela.

      var totalTr  = copyTr.length;
      var text;

      for (var i=0; i < totalTr; i++) // Inicializa o sortedTr e sortTr
      {
          text = copyTr[i].getElementsByTagName('td')[thIndex].innerHTML;
          sortedTr[i] = text;
          sortTr[i]   = text;
      }


      if (abbr == 'date') sortedTr.sort(dateOrder); // Ordenação de data aceita 'dd/mm/yyyy' e 'yyyy/mm/dd'.
      else if (abbr == 'number') sortedTr.sort(numberOrder);
      else if (abbr == 'img') sortedTr.sort(imgOrder);
      else if (abbr == 'float') sortedTr.sort(floatOrder);
      else sortedTr.sort(textOrder);

      for (var i=0; i < totalTr; i++)
      {
          for (var e=0; e < totalTr; e++)
          {
              if (sortedTr[i] == sortTr[e])
              {
                  resultTr[i] = e;
                  sortTr[e]   = null;
                  break;
              }
          }
      }

      var trs = tbody.getElementsByTagName('tr');
      
      for (var i = 0; i < trs.length; i++)
      {
          tds = trs[i].getElementsByTagName('td');
          for (var d = 0; d < tds.length; d++)
          {            
            if ((tds[d].cellIndex == thIndex) || (clickObject.tagName == 'span'))
                tds[d].className = "selecionado";
            else
                tds[d].className = "";
          }
      }

      for (var i=0; i < resultTr.length; i++)
      {
          tr = copyTr[ resultTr[i] ];
          tbody.appendChild( tr );
      }
  }


  /**
  * Mudas as imagens do head para a ordernacao, reverse ou nao
  *
  * @param table: objeto da tabela
  * @type: objeto
  * @param td: td do head que houve o evento
  * @type  td: objeto
  */
  function restoreImg(table, th)
  {

      var lastclick = table.getAttribute('lastclick');
      var reverse_  = eval(table.getAttribute('reverse'));
      var spancol    = table.getElementsByTagName('thead')[0].getElementsByTagName('span'); // Coloca as imagens no head como transparente
      for(var i=0; i < spancol.length; i++) 
      {
        spancol[i].innerHTML = '';
        spancol[i].innerHTML = '&nbsp;';
      }

      var index = th.getAttribute('selectIndex');
      if(lastclick == index)
      {
          if(reverse_ == false)
          {
              th.getElementsByTagName('span')[0].innerHTML = '';
              th.getElementsByTagName('span')[0].innerHTML = '&nbsp;&#9660;';
              table.setAttribute('reverse', true);
              reverse = true;
          } else {
              th.getElementsByTagName('span')[0].innerHTML = '';
              th.getElementsByTagName('span')[0].innerHTML = '&nbsp;&#9650;';
              table.setAttribute('reverse', false);
              reverse = false;
          }
      } else {
          table.setAttribute('reverse', false);
          reverse = false;
          table.setAttribute('lastclick', index);
          th.getElementsByTagName('span')[0].innerHTML = '';
          th.getElementsByTagName('span')[0].innerHTML = '&nbsp;&#9650;';
      }
      
      return index;
  }


  /**
   * 
   */
  function imgOrder(a, b)
  {     
     if (a.match(/^.*<(IMG|img).*$/)==null) rVal = reverse ? -1 : 1;
     else rVal = reverse ? 1 : -1;
     return rVal;
  } 
   
  /**
  * Verifica a ordem de dois numeros
  *
  * @param a,b: Numeros a serem verificado a ordem
  * @type: inteiro
  */
  function numberOrder(a,b)
  {
      reverse ? rVal = b - a : rVal = a - b;
      return rVal;
  }

  
  /**
  * Verifica a ordem de dois numeros float
  *
  * @param a,b: Numeros a serem verificado a ordem
  * @type: inteiro
  */
  function floatOrder(a,b)
  {
      a = a.replace( '.' , '' );
      b = b.replace( '.' , '' );
      a = a.replace( ',' , '.' );
      b = b.replace( ',' , '.' );
      reverse ? rVal = b - a : rVal = a - b;
      return parseFloat(rVal);
  }


  /**
  * Verifica a ordem de duas datas
  *
  * @param a,b: datas a serem ordenadas
  * @type  a,b: string
  */
  function dateOrder(a,b)
  {
      dia = a.match(regDia)[1];
      mes = a.match(regMes)[1];
      ano = a.match(regAno)[1];
      a = parseFloat(ano+mes+dia);

      dia = b.match(regDia)[1];
      mes = b.match(regMes)[1];
      ano = b.match(regAno)[1];
      b = parseFloat(ano+mes+dia);

      reverse ? rVal = a - b : rVal = b - a;
      //reverse ? rVal = Date.parse(a) - Date.parse(b) : rVal = Date.parse(b) - Date.parse(a);

      return rVal;
  }


  /**
  * Verifica a ordem alfabetica de duas strings
  *
  * @param a,b: string a serem ordenadas
  * @type a,b: string
  */
  function textOrder(a,b)
  {
      // Códigos html são retirados para não atrapalhar no sort;
      a = a.toString().replace( /<.+?>/gi, '' ).toLowerCase();
      b = b.toString().replace( /<.+?>/gi, '' ).toLowerCase();
      var rVal = -1;

      try {
          if (a < b) reverse ? rVal = -1 : rVal = 1;
          else reverse ? rVal = 1 : rVal = -1;
      } catch (e) {}

      return rVal;
  }
