window.onload = window.onload.andThen( 
  function () {
    var tablas = nodeCollection( 
      document.getElementsByTagName('TABLE') 
    ).filter(
      function (node) { return ( node.className == 'listaPropiedades' ); }
    ).map(
      function (tabla) {
        var t = new collapsableTable(tabla);
        t.showSelectSize = true;
        t.show();
      }
    );
  } 
);




// Objeto de tablas colapsables
function collapsableTable( tableDom ) {

  // Referencia a this
  if ( !window['_collapsableTable'] ) window._collapsableTable = {};
  this._uniqueId = 'table'+ nodeCollection (window._collapsableTable).length ;
  window._collapsableTable[this._uniqueId] = this;

  this.DOM = tableDom;
  
  // Busco TBODY en caso de que haya
  this.TBODY = ( tableDom.getElementsByTagName('TBODY').length>0 ) ? tableDom.getElementsByTagName('TBODY')[0] : tableDom;

  // Se asume el primer row como título
  this.total_items = this.TBODY.getElementsByTagName('TR').length-1;

  this.currentPage = 1;
  this.navs = [];
  this.rowsBuffer = [];
  this.unbufferedPage = -1;
  // Muestra el control para cambiar de tamaño
  this.showSelectSize = false;
  this.selectSizeStep = 10;
  
  // Define la cantidad por página de acuerdo al URL#...sizeN
  var i = document.location.hash.after('size')*1; 
  if ( typeof(i) != 'number' ) i = 10; 
  this.itemXpage = i = (i<this.selectSizeStep)?this.selectSizeStep: ( (i>this.total_items)?this.total_items:i );
}


collapsableTable.prototype.changePage = function (page) {
  this.drawPagination( page );
  this.hideRows();
}


collapsableTable.prototype.pageName = function ( pageNumber ) {
  return '#'+ this._uniqueId +'page'+ pageNumber +'size' + this.itemXpage ;
}


collapsableTable.prototype.drawPagination = function ( currentPage ) {

  var total_pags = Math.ceil(this.total_items/this.itemXpage);

  //currentPage = currentPage<1 ? 1 : currentPage;
  //currentPage = currentPage>total_pags ? total_pags : currentPage;
  
  var currentPage = currentPage<1 ? 1 : (currentPage>total_pags ? total_pags : currentPage) ;

  this.currentPage = currentPage;

  // Borra navegación anterior
  this.navs.map( function (node) { node.parentNode.removeChild(node); } );
  this.navs = [];
  if ( total_pags == 1 ) return true;
  
  var thisObj = this;
  var makeNav = function (nav, i, txt) {
    i = (i<1)?1: ( (i>total_pags)?total_pags:i );
    if ( i==currentPage) var a = _TEXT(txt);
    else {
      var a = _A( { href: thisObj.pageName(i) }, txt ).DOM;
      a.onclick = function () { thisObj.changePage(i); };
    }
    nav.appendChild ( a );
    nav.appendChild ( _TEXT(' ') );
  };

  var navSup = _P( {id: this._uniqueId+'navSup', 'class': 'tableNav tableNavSup' } ).DOM;
  makeNav(navSup, currentPage-1, '<');
  for (var i=1; i<= total_pags; i++) makeNav(navSup, i, i);
  makeNav(navSup, currentPage+1, '>');

  var navBot = _P( {id: this._uniqueId+'navBot', 'class': 'tableNav tableNavBot' } ).DOM;
  makeNav(navBot, currentPage-1, '<');
  for (var i=1; i<= total_pags; i++) makeNav(navBot, i, i);
  makeNav(navBot, currentPage+1, '>');

  // Guardo referencia a esta navegacion
  this.navs = [navSup, navBot];
  
  this.DOM.parentNode.insertBefore( navSup , this.DOM);
  this.DOM.parentNode.insertBefore( navBot , this.DOM);
  this.DOM.parentNode.insertBefore( this.DOM, navBot);
}



collapsableTable.prototype.show = function () {
  //this.itemXpage = itemXpage;
  this.currentPage = 1;
  
  this.makeRowsBuffer();
  
  if (this.showSelectSize) this.drawSelectSize();
  this.changePage( document.location.hash.after(this._uniqueId+'page').before('size') );

}

collapsableTable.prototype.makeRowsBuffer = function () {
  // Estrategia: traspaso mi tabla a una cosa vacía
  this.rowsBuffer = [];
  var j=0, index, TR, TRs=this.DOM.getElementsByTagName('TR');
  while ( TR = TRs[1] ) {
    index = 1+Math.floor(j/this.itemXpage); j++;
    if( typeof(this.rowsBuffer[index])=='undefined' ) {
      this.rowsBuffer[index] = _TABLE().DOM;
    }
    this.rowsBuffer[index].appendChild(TR);
  }
}


collapsableTable.prototype.hideRows = function () {

  // Si ya hay mostrados, ocultelos primero
  if ( this.unbufferedPage > 0) {
    this.moveTRs( this.TBODY, this.rowsBuffer[this.unbufferedPage], 1 );
  }

  // Mostrar los correctos
  this.moveTRs( this.rowsBuffer[this.currentPage], this.TBODY, 0 );

  // Recorda qué estoy mostrando  
  this.unbufferedPage = this.currentPage;
};


// Mueve filas de una tabla a otra
collapsableTable.prototype.moveTRs = function (fromTable, toTable, fromIndex) {
  var TRs = fromTable.getElementsByTagName('TR');
  var TR; while (TR = TRs[fromIndex]) { toTable.appendChild(TR); }
}


// Devuelve la tabla a su estado original
collapsableTable.prototype.restoreTable = function () {
  if ( this.unbufferedPage > 0) {
    this.moveTRs( this.TBODY, this.rowsBuffer[this.unbufferedPage], 1 );
  }
  for (var i=1; i<this.rowsBuffer.length; i++)
    this.moveTRs( this.rowsBuffer[i], this.TBODY, 0 );
  this.unbufferedPage = -1;
};


collapsableTable.prototype.drawSelectSize = function() {

  // Oculta si no hay más posibles paginaciones
  if (this.total_items < this.itemXpage) return false;

  var select = _SELECT().DOM;
  var thisObj = this;
  select.onchange = function () { 
    thisObj.restoreTable();
    thisObj.itemXpage = this.value;
    thisObj.show();
    document.location.href = document.location.href.before('#') + thisObj.pageName(1);
  };
  
  for (var option, i=this.selectSizeStep; i<this.total_items+this.selectSizeStep; i+=this.selectSizeStep) {
    option = _OPTION( {value:i}, i ).DOM;
    if (i==this.itemXpage) { option.selected = 'selected'; }
    select.appendChild(option);
  }

  var form = _FORM( { 'class': 'tableSelectSize'}, 'Mostrar ', select ).DOM ;
  form.onsubmit = function() { return false; }

  this.DOM.parentNode.insertBefore(form, this.DOM);
  this.showSelectSize = false;
}