/**
 * Class JRow for render div's like a rows of table
 * 
 * @autor Grover Campos <gcampos@teravisiontech.com>
 * @param container string
 * @param properties Array
 */
var JRow = Class.create({
  initialize: function (container, properties)
  {
    this.container = $(container);
    this.hijos     = new Array();
    
    if(!$(container))
    {
      throw 'No existe container' + container;
    }
    
    // get this divs
    childs_ = $(container).childElements();
    for ( i = 0; i < childs_.length; i++)
    {
      hijo_ = childs_[i];
      if(hijo_.tagName.toLowerCase() == 'div')
      {
        this.hijos[this.hijos.length] = hijo_;
      }
    };
    //this.hijos     = $(container).select('div');
    
    if (properties == null)
    {
      width_ = Math.floor( this.container.getWidth() / this.hijos.length );
      for ( i = 0; i < this.hijos.length; i++)
      {
        hijo = this.hijos[i];
        $(hijo).setStyle({
          position: 'relative',
          top: '0px',
          float: 'left',
          width: width_ + 'px',
          height: '100%'
        });
      }
    }
    else 
    {
      if (properties instanceof Array)
      {
        widths     = new Array(this.hijos.length);
        ancho_disp = this.container.getWidth();
        for ( i = 0; i < properties.length; i++)
        {
          propiedad = properties[i];
          if (typeof propiedad == 'object')
          {
            if (propiedad.width)
            {
              if (propiedad.width.lastIndexOf('%') != -1)
              {
                width_    = parseInt(propiedad.width);
                widths[i] = Math.floor( this.container.getWidth() * width_ / 100 );
              }
              else if (propiedad.width.lastIndexOf('px') != -1)
              {
                width_    = parseInt(propiedad.width);
                widths[i] = width_;
              }
              else 
              {
                throw 'Ancho de propiedad no es valido: ' + propiedad.width;
              }
              if(widths[i] < ancho_disp)
              {
                ancho_disp -= widths[i];
              }
              else
              {
                widths[i]  = ancho_disp;
                ancho_disp = 0;
              }
            }
          }
          else
          {
            throw 'Propiedad ' + i + ' no es valida: ' + propiedad;
          }
        }
        // verifico que esten establecidos todos los anchos, si es que
        // hay ancho disponible
        if (ancho_disp > 0)
        {
          cont = 0;
          for ( j = 0; j < widths.length; j++)
          {
            foo = widths[j];
            if (foo == null)
            {
              cont++;
            }
          }
          if (cont > 0)
          {
            // si hay algun ancho que falte, calculo cuanto debe corresponder
            // a cada uno que le falte y le otorgo ancho proporcional
            // el algoritmo ira estableciendo conforme haya ancho disponible
            ancho_prop = Math.floor(ancho_disp / cont );
            for ( j = 0; j < widths.length; j++)
            {
              foo = widths[j];
              if (foo == null)
              {
                widths[j] = ancho_prop;
                ancho_disp -= widths[j];
              }
            }
          }
        }
        for ( i = 0; i < this.hijos.length; i++)
        {
          hijo = this.hijos[i];
          $(hijo).setStyle({
            position: 'relative',
            top: '0px',
            float: 'left',
            width: widths[i] + 'px',
            height: (properties[i] && properties[i].height) ? (properties[i].height) : ('100%')
          });
        }
      }
      else
      {
        throw 'Propiedades de la fila debe ser un array';
      }
    }
  }
});

/**
 * Class JTable for render div's like a tables.
 * table_properties is optional
 *  
 * table_properties = {
 *   properties : row_properties,
 *   make_rows  : boolean,
 *   column_properties : jrow_properties
 * }
 * 
 * or 
 * 
 * table_properties = row_properties  // assuming make_rows = true
 *  
 * row_properties = Array(
 *   {
 *     height: string,
 *     make_row: boolean,
 *     row_properties: jrow_properties @see JRow
 *   }
 * ) 
 * 
 * @author Grover Campos <gcampos@teravisiontech.com>
 * @param container string
 * @param properties Array
 */
var JTable = Class.create({
  initialize : function(container, table_properties)
  {
    this.container  = $(container);
    this.hijos      = new Array();
    this.row_properties;
    this.make_rows  = true;
    this.column_properties;
    
    if (!$(container))
    {
      throw 'No existe container: ' + container;
    }
    
    // get this divs
    childs_ = $(container).childElements();
    for ( i = 0; i < childs_.length; i++)
    {
      hijo_ = childs_[i];
      if(hijo_.tagName.toLowerCase() == 'div')
      {
        this.hijos[this.hijos.length] = hijo_;
      }
    };
    // get the properties
    if(table_properties instanceof Array)
    {
      this.row_properties = table_properties;
      this.make_rows      = true;
    }
    else if (typeof table_properties == 'object') 
    {
      this.row_properties = table_properties.properties;
      if(table_properties.make_rows == null)
      {
        this.make_rows = true;
      }
      else
      {
        this.make_rows = table_properties.make_rows;
      }
      this.column_properties = table_properties.column_properties;
    }

    if (this.row_properties == null)
    {
      alto = Math.floor( this.container.getHeight() / this.hijos.length );
      for ( var i = 0; i < this.hijos.length; i++)
      {
        var hijo = this.hijos[i];
        $(hijo).setStyle({height: alto + 'px'});
        
        row_property = null;
        if(this.column_properties != null)
        {
          row_property = this.column_properties;
        }
        
        if(this.make_rows)
        {
          new JRow(hijo.id, row_property);
        }
      }
    }
    else 
    {
      altos     = new Array(this.hijos.length);
      alto_disp = this.container.getHeight();
      
      if (typeof this.row_properties == 'object' && this.row_properties.height) 
      {
        aux = this.row_properties.height;
        this.row_properties = altos;
        if (aux.lastIndexOf('%') != -1)
        {
          alto = parseInt(this.row_properties.height);
          alto = alto + 'px';
        }
        else if (aux.lastIndexOf('px') != -1)
        {
          alto = aux;
        }
        else 
        {
          throw 'Ancho de propiedad no es valido';
        }
        for(i=0; i < this.hijos.length; i++)
        {
          this.row_properties[i] = { height: alto};
        }
      }
      if (this.row_properties instanceof Array)
      {
        if (this.row_properties.length == this.hijos.length)
        {
          for ( i = 0; i < this.row_properties.length; i++)
          {
            propiedad = this.row_properties[i];
            if (typeof propiedad == 'object')
            {
              if (propiedad.height)
              {
                if (propiedad.height.lastIndexOf('%') != -1)
                {
                  alto = parseInt(propiedad.height);
                  altos[i] = this.container.getHeight() * alto / 100;
                }
                else if (propiedad.height.lastIndexOf('px') != -1)
                {
                  alto = parseInt(propiedad.height);
                  altos[i] = alto;
                }
                else 
                {
                  throw 'Ancho de propiedad no es valido';
                }
                if(altos[i] < alto_disp)
                {
                  alto_disp -= altos[i];
                }
                else
                {
                  altos[i]  = alto_disp;
                  alto_disp = 0;
                }
              }
            }
            else
            {
              throw 'Propiedad ' + i + ' no es valida';
            }
          }
          // verifico que esten establecidos todos los altos, si es que
          // hay altos disponible
          if (alto_disp > 0)
          {
            cont = 0;
            for ( j = 0; j < altos.length; j++)
            {
              foo = altos[j];
              if (foo == null)
              {
                cont++;
              }
            }
            if (cont > 0)
            {
              // si hay algun alto que falte, calculo cuanto debe corresponder
              // a cada uno que le falte y le otorgo alto proporcional
              // el algoritmo ira estableciendo conforme haya alto disponible
              alto_prop = Math.floor(alto_disp / cont );
              for ( j = 0; j < altos.length; j++)
              {
                foo = altos[j];
                if (foo == null)
                {
                  altos[j] = alto_prop;
                  alto_disp -= altos[j];
                }
              }
            }
          }
        }
        else
        {
          throw 'Las cantidad de propiedades debe ser igual a la cantidad de filas en la tabla.' + 
                'Se encontraron: '+this.hijos.length+' filas y hay ' + this.row_properties.length + ' propiedades en el container: ' + container;
        }
      }
      else
      {
        throw 'Propiedades de la tabla debe ser un array';
      }
      
      for ( i = 0; i < this.hijos.length; i++)
      {
        hijo = this.hijos[i];
        $(hijo).setStyle({
          height: altos[i] + 'px'
        });
        make_row     = this.make_rows;
        row_property = null;
        if(this.row_properties[i].make_row != null)
        {
          make_row = this.row_properties[i].make_row;
        }
        if (this.row_properties[i].row_properties != null)
        {
          row_property = this.row_properties[i].row_properties;
        }
        else if(this.column_properties != null)
        {
          row_property = this.column_properties;
        }
        if(make_row)
        {
          new JRow(hijo.id, row_property);
        }
      }
    };
  }
});