var Table = {
  view: {'current':'all', 'previous':null, 'start':0, 'display':null },
  
  initialize: function(element, options)
  {
    this.options    = options || {};
    this.element    = element;
    this.rows       = this.element.select('tr');
    //this.datarows   = this.rows.findAll(function(r){ return (!Element.hasClassName(r, 'head') && !Element.hasClassName(r, 'filter')) });
    
    this.columns    = [];
    this.range      = this.options.range || 4;
    this.form       = $(element.id+'_filter');
    this.filtered   = false;
    this.style      = this.options.style || 'wide';
    this.bNext      = $(element.id+'_button_next');
    this.bPrev      = $(element.id+'_button_previous');
    this.info       = $(element.id+'_info');
    
    if(this.form)
    {
      this.fProperty  = $(this.form.id+'_property');
      this.fValue     = $(this.form.id+'_property_value');
      this.properties = this.options.properties;
      this.profiles   = this.options.profiles;
      this.bReset     = $(element.id+'_button_reset');
      
      this.fProperty.selectedIndex = 0;
    }
    
    $A(this.element.getElementsByTagName('tr')[0].getElementsByTagName('td')).each(function(e,i){
      Table.columns.push({ 'index':i, 'excluded':false, 'filtered':false });
    });
    this.parents    = $$('#' + element.id + ' tr.parent');
    this.children   = $$('#' + element.id + ' tr.child');
    this.parents.each(function(e)
    {
      var t = document.createElement('span');
      t.className = 'triangle';
      t.onclick = function(){ Table.toggleParent(this.parentNode.parentNode) };
      var b = e.getElementsByTagName('th')[0];
      if(b) b.insertBefore(t, b.firstChild);
    });
    this.children.each(function(e){ Element.hide(e) });
    /*
    this.datarows.each(function(e){
      if(!Element.hasClassName(e, 'head')){
        e.onmouseover = Table.highlightRow;
        e.onmouseout  = Table.dehighlightRow;
      }
    });
    */
    $$('tr.head.brand td sup a').each(function(e)
    {
      e.onclick = markAnchor;
    });
    document.observe("dom:loaded", Table.populate);
//    this.populate();
  },
  populate: function()
  {
    var v = Table.view;
    
    //if(!this.filtered || v.current=='all') v.current = $R(0,this.columns.length-1).toArray();
    //if(!this.filtered || v.current=='all')
    v.current  = Table.columns;
    v.current  = v.current.select(function(e){ return (!e.excluded && !e.filtered) });
    v.previous = v.display;
    v.display  = (Table.style=='wide') ? v.current : v.current.slice(v.start, Table.range+v.start);
    //console.log('columns'); console.log(this.columns)
    //console.log('current'); console.log(v.current)
    //console.log('display'); console.log(v.display)
    var disp_indexes = v.display.pluck('index');
    var prev_indexes = (v.previous) ? v.previous.pluck('index') : [];
    Table.element.select('td').each(function(e)
    {
      Element.hide(e);
    });
    
    Table.element.className = 'testtable display' + v.display.length;
    
    if(v.display.length == 0)
    {
      var v = 0;
      if(Table.view.start > Table.range) v = Table.view.start - Table.range;
      Table.slideTo(v);
    }
    else
    {
      Table.rows.each(function(tr, i)
      {
        var tds = tr.select('td');
        disp_indexes.each(function(e)
        {
          Element.show(tds[e]);
          //console.log(tds[e].innerHTML)
          //if(i>0 && !prev_indexes.member(e)) new Effect.Highlight(tds[e]);
        });
      });
      Table.updateMenu();
    }
  },
  loadProperties: function()
  {
    var property = $F(Table.fProperty);
    Table.fValue.options.length = 0;
    if(property != '*')
    {
      var values = this.properties[property];
      if(values)
      {
        var opts = [];
        values.each(function(e,i){ opts.push(new Option(e,i)) } );
        //opts.each(function(e){ Table.fValue.appendChild(e) });
        opts.each(function(e,i){ Table.fValue.options[i] = e });
        this.fValue.selectedIndex = 0;
        Element.show(Table.fValue);
      }
      Table.applyFilter(property, $F(Table.fValue));
    }
    else
    {
      Table.resetFilter();
    }
  },
  applyFilter: function(property, value)
  {
    //console.log('applyFilter')
    //console.log('p='+property+', v='+value)
    this.profiles.each(function(e,i){
      Table.columns[i].filtered = (e[property] == value)? false:true;
    });
    this.start    = 0;
    this.filtered = true;
    this.includeAllColumns();
    this.populate();
  },
  resetFilter: function()
  {
    Table.view.start    = 0;
    //this.view.previous = this.view.current;
    //this.view.current  = 'all';
    Table.filtered      = false;
    Table.fProperty.selectedIndex = 0;
    Table.fValue.selectedIndex    = -1;
    Element.hide(Table.fValue);
    Table.columns.each(function(e){ e.filtered = false });
    Table.includeAllColumns();
    Table.populate();
  },
  excludeColumn: function(index)
  {
    Table.columns[index].excluded = true;
    Table.populate();
  },
  includeAllColumns: function()
  {
    Table.columns.each(function(e)
    {
      e.excluded = false;
    });
  },
  resetExclusion: function()
  {
    Table.includeAllColumns();
    Table.populate();
  },
  toggleParent: function(element)
  {
    element.toggleClassName('expanded');
    var nodes = element.nextSiblings();
    for(var i=0, l = nodes.length; i < l; i++)
    {
      var node = nodes[i];
      if(!node.hasClassName('child')) break;
      node.toggle();
    }
  },
  slide: function(element, dir)
  {
    if(element.hasClassName('disabled')) return;
    Table.view.start += (dir == 'left') ? -1 * Table.range : Table.range;
    Table.populate();
  },
  slideTo: function(v)
  {
    if(Table.view.start != v)
    {
      Table.view.start = v;
      Table.populate();
    }
    else
    {
      Table.updateMenu();
    }
  },
  updateMenu: function()
  {
    if(Table.style != 'narrow') return;
    
    var v    = Table.view;
    var t    = v.current.length;
    var e    = Table.columns.findAll(function(e){ return e.excluded });
    var el   = e.length;
    var info = '';
    
    if(t > Table.range)
    {
      if(v.start > 0)
        Element.removeClassName(Table.bPrev, 'disabled');
      else
        Element.addClassName(Table.bPrev, 'disabled');
      
      if(v.display.last() == v.current.last())
        Element.addClassName(Table.bNext, 'disabled');
      else
        Element.removeClassName(Table.bNext, 'disabled');
    }
    else
    {
      Element.addClassName(Table.bNext, 'disabled');
      Element.addClassName(Table.bPrev, 'disabled');
    }
    //this.bReset.disabled = (el>0) ? false:true;
    if(Table.bReset)
      Table.bReset.disabled = (Table.filtered || el > 0) ? false:true;
    
    var v2 = ((v.start + Table.range) > t) ? t : v.start+Table.range;
    var v1 = (v2 > 0) ? v.start+1 : 0;
    
    //var total = (e>0) ? t+' ('+e+' ausgeblendet)': t;
    
    if(t>0)
    {
      if(v1 != v2) info += ((v2 > 1) ? 'Eintrag <b>' + v1 + ' bis ' + v2 + '</b>' : '<b>1</b> Eintrag');
      else info += 'Eintrag <b>' + v1 + '</b>';
      if(t > 1) info += ' von <b>' + t + '</b>';
    }
    else
    {
      info = 'Keine Einträge';
    }
    if(el>0)
    {
      info += ' (' + el + ' versteckte';
      if(el == 1) info += 'n';
      info += ' <a href="javascript:Table.resetExclusion();">anzeigen</a>)';
    }
    
    Table.info.innerHTML = '<span>' + info + '</span>';
  },
  highlightRow: function(event)
  {
    var element = Event.findElement(event,'tr');
    alert(element)
    Element.addClassName(element, 'hover');
  },
  dehighlightRow: function(event)
  {
    var element = Event.findElement(event,'tr');
    alert(element)
    if(element) Element.removeClassName(element, 'hover');
  }
};

var iTable = {
  
  initialize: function(segments, items, ratings)
  {
    this.overlay  = $('mytest-overlay');
    this.segments = segments;
    this.ratings  = ratings;
    this.ranges   = [$R(80,100), $R(60,79), $R(40,59), $R(20,39), $R(0,19)]
    this.items    = items;
    
    // initialize configuration UI
    
    $$('#mytest-categories dd').each(function(row, i)
    {
      var segment   = iTable.segments[i];
      var range     = iTable.ranges.find(function(r){ return r.include(segment.customWeight) });
      var setup     = iTable.ranges.indexOf(range);
      segment.setup = setup;
      //console.log('segment:'+segment+', setup: '+setup+', range: '+range)
      row.select('span').each(function(button, value)
      {
        if(value <= setup) Element.addClassName(button, 'active');
        
        button.onclick = function()
        {
          button.previousSiblings().concat([button]).invoke('addClassName', 'active');
          button.nextSiblings().invoke('removeClassName', 'active');
          segment.setup = value;
          $('button_mytest-update').down('button').disabled = false;
        };
      });
    });
  },
  start: function()
  {
    if(!document.getElementById) return;
    var screen = this.getPageSize();
    var scroll = document.viewport.getScrollOffsets();
    var y = scroll[1] + (document.viewport.getHeight() / 20);
    var x = scroll[0];
    
    $$('select', 'object', 'embed').each(function(node)
    {
      node.style.visibility = 'hidden';
    });
    
    this.overlay.setStyle({ width:screen[0]+'px', height:screen[1]+'px' });
    
    new Effect.Appear(this.overlay,
    { duration:1
    , from:0.0
    , to:0.8
    , afterFinish:function(){
        $('mytest').setStyle({top:y+'px', left:x+'px'}).show() }
    });
    
    this.load();
  },
  end: function()
  {
    Element.hide('mytest');
    new Effect.Fade(this.overlay, { duration:1 });
    $$('select', 'object', 'embed').each(function(node)
    {
      node.style.visibility = 'visible';
    });
  },
  load: function()
  {
    this.items.each(function(item)
    {
      item.customResult  = iTable.calculateResult(item, 'custom');
      item.defaultResult = iTable.calculateResult(item, 'default');
    });
    this.sort();
  },
  sort: function()
  {
    this.items = this.items.sortBy(function(e){ return e.customResult });
    this.items.reverse();
    this.populate();
  },
  calculateWeight: function()
  {
    var dividend = 0;
    this.segments.collect(function(segment)
    {
      dividend += segment.setup*1;
    });
    if(dividend == 0) dividend = 1;
    this.segments.each(function(segment)
    {
      segment.customWeight = Math.round((segment.setup/dividend)*100);
    });
  },
  calculateResult: function(item, type)
  {
    var result = 0;
    item.segmentResults.each(function(n,i)
    {
      result += n * iTable.segments[i][type+'Weight'];
    });
    return Math.round(result / 100);
  },
  getRating: function(result)
  {
    var range = this.ranges.find(function(range){ return range.include(result) });
    //console.log('result: '+result+', range: '+this.ranges.indexOf(range))
    return this.ratings[this.ranges.indexOf(range)];
  },
  update: function()
  {
    this.calculateWeight();
    this.load();
  },
  populate: function()
  {
    var rows = '';
    var row  = new Template('<tr class="#{css}"><td class="rank">#{rank}</td><td>#{vendor}</td><td>#{modell}</td><td class="result">#{customRating}</td><td>#{defaultRating}</td><td>#{price}</td></tr>');
    this.items.each(function(item, i)
    {
      item.customRating  = iTable.getRating(item.customResult);
      item.defaultRating = iTable.getRating(item.defaultResult);
      item.rank = i+1;
      //item.css  = (i<3) ? 'best':'';
      item.css = '';
      rows += row.evaluate(item);
    });
    $('mytest-entries').update(rows);
    $('button_mytest-update').down('button').disabled = true;
  },
  getPageSize: function()
  {
    var xScroll, yScroll;
    if(window.innerHeight && window.scrollMaxY)
    {
      xScroll = window.innerWidth + window.scrollMaxX;
      yScroll = window.innerHeight + window.scrollMaxY;
    }
    else if(document.body.scrollHeight > document.body.offsetHeight)
    { // all but Explorer Mac
      xScroll = document.body.scrollWidth;
      yScroll = document.body.scrollHeight;
    }
    else
    { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
      xScroll = document.body.offsetWidth;
      yScroll = document.body.offsetHeight;
    }
    var windowWidth, windowHeight;
    if(self.innerHeight)
    { // all except Explorer
      if(document.documentElement.clientWidth)
      {
        windowWidth = document.documentElement.clientWidth; 
      }
      else
      {
        windowWidth = self.innerWidth;
      }
      windowHeight = self.innerHeight;
    }
    else if(document.documentElement && document.documentElement.clientHeight)
    { // Explorer 6 Strict Mode
      windowWidth = document.documentElement.clientWidth;
      windowHeight = document.documentElement.clientHeight;
    }
    else if(document.body)
    { // other Explorers
      windowWidth = document.body.clientWidth;
      windowHeight = document.body.clientHeight;
    }
    // for small pages with total height less then height of the viewport
    if(yScroll < windowHeight)
    {
      pageHeight = windowHeight;
    }
    else
    { 
      pageHeight = yScroll;
    }
    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth)
    {
      pageWidth = xScroll;
    }
    else
    {
      pageWidth = windowWidth;
    }
    return [pageWidth, pageHeight];
  }
}
