/*
  AjaxScrollObject: displays information in a scrollable list
    Inputs:
      searchForm:
         form that submits to an XML document.
              with these required elements
                 rowStart, rowCount, totalRows, rowXMLTag
              form must have the following inputs:
                  rowStart, rowCount   
      createRow(XMLObject): function which returns a single table body row (<tr>) based on the rowXMLTag object.
      maxRows: number of rows to display
      target:  id of tbody element to contain the list
    Methods:
      reload();  clear cache and display first maxRows records
      previous();
      next();
      previousPage();
      nextPage();
      first();
      last();
      jumpTo(start); move to a given index.
      resize(dx,dy);
      viewAll();
   Events:
     onMove(start,shown,total) called after 
     onComplete(sc,st,rt,rxml): optional function to parse aditional information from resulting XML file
*/




function AjaxScrollObject(searchForm,createRow, maxRows, target, statusBar){
  this.target=el(target);
  this.maxRows=maxRows;
  this.origMaxRows=maxRows;
  this.searchForm=searchForm;
  this.createRow=createRow;
  this.rowsShown=0;
  this.rowStart=0;
  this.totalRows=1;
  this.maxCache=500;
  this.cacheOffset=0;
  this.cache=new Array();
  this.loading=false;
  this.nav = new Object();
  this.nav.previousPage="";
  this.nav.previous="";
  this.nav.first="";
  this.nav.last="";
  this.nav.next="";
  this.nav.nextPage="";
  this.nav.viewAll="";
  this.nav.pageList="";
  this.nav.objectName="";
  
  // functions called by other objects
  var instance=this;    
  this.jumpTo=function(start){if(start>=0){ instance.rowStart=start; instance.showRows(); }}
  this.reload=function(){instance.maxRows=instance.origMaxRows;instance.totalRows=1; instance.cache=null; instance.cacheOffset=0; instance.cache=new Array();instance.showRows(); }
  this.resize=function(dx,dy){instance.resizeXY(dx,dy);}
}

function AjaxScroolObject_setNav(){
  if(this.rowStart==0){
    if(this.nav.first!="") hide(this.nav.first);
    if(this.nav.previousPage!="") hide(this.nav.previousPage);
    if(this.nav.previous!="") hide(this.nav.pervious);
  }else{
    if(this.nav.first!="") show(this.nav.first);
    if(this.nav.previousPage!="") show(this.nav.previousPage);
    if(this.nav.previous!="") show(this.nav.pervious);
  }
  if(this.rowsShown+this.rowStart>=this.totalRows){
     if(this.nav.last!="") hide(this.nav.last);
     if(this.nav.next!="") hide(this.nav.next);
     if(this.nav.nextPage!="") hide(this.nav.nextPage);
  }else{
     if(this.nav.last!="") show(this.nav.last);
     if(this.nav.next!="") show(this.nav.next);  
     if(this.nav.nextPage!="") show(this.nav.nextPage);
  }

  
  if(this.nav.viewAll!=""){
    if(this.rowStart==0&&this.rowsShown>=this.totalRows) hide(this.nav.viewAll);
    else show(this.nav.viewAll);  
  }

  if(this.nav.pageList!=""){
    var page=el(this.nav.pageList);
    page.innerHTML='';
    var page_start=0;
    var page_end=this.totalRows;
    if(page_end>page_start+20*this.maxRows) page_end=page_start+20*this.maxRows;
    page.innerHTML='';
    if(this.totalRows>this.maxRows){
      for(var i=page_start; i<page_end; i+=this.maxRows){
        if(i==this.rowStart) page.innerHTML=page.innerHTML+"&nbsp;("+parseInt(i/this.maxRows+1)+")";
        else page.innerHTML=page.innerHTML+'&nbsp;<a href="javascript:'+this.nav.objectName+'.jumpTo('+i+');">'+parseInt(i/this.maxRows+1)+'</a>';
      }
    }
  }    
}

function AjaxScrollObject_showRows(){  
  // clear display 
  var y=this.target.getElementsByTagName('TR');      
  while(y.length>0){    
     this.target.removeChild(y[0]);         
     y=this.target.getElementsByTagName('TR');     
  }  
  this.rowsShown=0;
  // correct invalid rowStart
  if(this.rowStart+1>this.totalRows){
    this.rowStart=this.totalRows-1;
  }
  if(this.rowStart<0) this.rowStart=0;
  // reset cache if needed    
  if(this.rowStart<this.cacheOffset){
    this.cache=null;
    this.cache=new Array();
    this.cacheOffset=this.rowStart-parseInt(this.maxCache/2);
    if(this.cacheOffset<0)this.cacheOffset=0;
  }
  if(this.rowStart>this.cacheOffset+this.maxCache){
    this.cache=null;
    this.cache=new Array();
    this.cacheOffset=this.rowStart-parseInt(this.maxCache/2);
  }
  // display records;
  for(var i=this.rowStart; i<this.totalRows&&i<this.rowStart+this.maxRows; i++){
      this.target.appendChild(this.createRow(this.cache[i-this.cacheOffset]));
      this.rowsShown++;
  }
  if(this.onMove!=null) this.onMove(this.rowStart,this.rowsShown,this.totalRows);
  // load next set of missing records
  if(!this.loading){
    for(var i=this.rowStart; i<this.rowStart+this.maxRows*2&&i<this.totalRows; i++){
      if(!this.cache[i-this.cacheOffset]){
        var sf=el(this.searchForm);
        sf.rowStart.value=i;
        sf.rowCount.value=this.maxRows;
        var instance=this;
        this.loading=true;
        ajaxFormFunction(this.searchForm,function(sc,st,rt,rxml){instance.preload(sc,st,rt,rxml);});      
        break;
      }
    }
  }  
  this.setNav();
}

function AjaxScrollObject_updateRecord(id,xmlObj){
  if(id-this.cacheOffset>=0&&id-this.cacheOffset<this.maxCache+this.maxRows){  
    this.cache[id-this.cacheOffset]=xmlObj;
    if(id>=this.rowStart&&id<this.rowStart+this.rowsShown){
      this.showRows();
      return true;
    }
  }
  return false;
}


function AjaxScrollObject_preload(sc,st,rt,rxml){
  this.loading=false;
  if(this.debug) alert(rt);
  var rs, t;
  var rowTag;

  rs=getTagValue(rxml,'rowStart')*1;
  t=getTagValue(rxml,'totalRows')*1;  
  rowTag=getTagValue(rxml,'rowXMLTag');  
  
  // reset cache if total changes
  if(this.totalRows!=t){
    this.cache=null
    this.cache=new Array();
    this.cacheOffset=this.rowStart-parseInt(this.maxCache/2);
    if(this.cacheOffset<0)this.cacheOffset=0;    
  }
  
  this.totalRows=t;
  var x=rxml.getElementsByTagName(rowTag);
  
  // load cache
  for(var i=0; i<x.length; i++){
     if(i+rs-this.cacheOffset>=0) this.cache[i+rs-this.cacheOffset]=x[i];
  }
  this.showRows();
  if(this.onComplete!=null)  this.onComplete(sc,st,rt,rxml);  
}



function AjaxScrollObject_jumpTo(start){ }

function AjaxScrollObject_reload(){ }

function AjaxScrollObject_resize(x,y){ }

function AjaxScrollObject_resizeXY(x,y){
  var rowHeigth=0;
  if(this.target.getElementsByTagName('TR')[0]){
    rowHeight=this.target.getElementsByTagName('TR')[0].offsetHeight;   
    if(rowHeight<Math.abs(y)){              
      if(y<0){
        var rows=parseInt((0-y)/rowHeight); 
        this.contract(rows);
      }else{
         var rows=parseInt(y/rowHeight); 
         this.expand(rows);
      }
      return true;
    }
  }
}


function AjaxScrollObject_previous(){
  if(this.rowStart>0){  this.rowStart--; this.showRows(); }
}

function AjaxScrollObject_previousPage(){
  if(this.rowStart>0){ 
    this.rowStart-=this.maxRows;
    if(this.rowStart<0) this.rowStart=0;
    this.showRows();
  }
}

function AjaxScrollObject_next(){
  this.rowStart++;
   this.showRows();
}

function AjaxScrollObject_nextPage(){
  this.rowStart+=this.rowsShown;
  this.showRows();
}

function AjaxScrollObject_first(){
  this.rowStart=0;
  this.showRows();
}

function AjaxScrollObject_last(){
  this.rowStart=this.totalRows-this.maxRows;
  if(this.rowStart<0) this.rowStart=0;
  this.showRows();
}

function AjaxScrollObject_viewAll(reload){
  if(!this.navLock){
    this.maxRows=this.totalRows;
    if(reload){
      this.totalRows=1;
      this.rowStart=0;
      this.cache=null; 
      this.cacheOffset=0; 
      this.cache=new Array()    
    }
    this.showRows();
  }
}
function AjaxScrollObject_expand(rows){
   if(!this.navLock){
    if(!rows)rows=1;
    if(rows<1)rows=1;
    this.maxRows+=rows;
    this.showRows();
   }
}
function AjaxScrollObject_contract(rows){
   if(!this.navLock){
    if(!rows)rows=1;
    if(rows<1)rows=1;
    this.maxRows-=rows;
    if(this.maxRows<=4) this.maxRows=5;
    this.showRows();
   }
}



// events
function AjaxScrollObject_onMove(start,shown,total){
}


AjaxScrollObject.prototype.setNav=AjaxScroolObject_setNav;

AjaxScrollObject.prototype.showRows = AjaxScrollObject_showRows;
AjaxScrollObject.prototype.preload =AjaxScrollObject_preload;
AjaxScrollObject.prototype.updateRecord=AjaxScrollObject_updateRecord;

AjaxScrollObject.prototype.previous = AjaxScrollObject_previous;
AjaxScrollObject.prototype.previousPage = AjaxScrollObject_previousPage;
AjaxScrollObject.prototype.next = AjaxScrollObject_next;
AjaxScrollObject.prototype.nextPage = AjaxScrollObject_nextPage;
AjaxScrollObject.prototype.first = AjaxScrollObject_first;
AjaxScrollObject.prototype.last = AjaxScrollObject_last;
AjaxScrollObject.prototype.viewAll = AjaxScrollObject_viewAll;

AjaxScrollObject.prototype.expand = AjaxScrollObject_expand;
AjaxScrollObject.prototype.contract = AjaxScrollObject_contract;

AjaxScrollObject.prototype.jumpTo = AjaxScrollObject_jumpTo;
AjaxScrollObject.prototype.resize = AjaxScrollObject_resize;
AjaxScrollObject.prototype.resizeXY = AjaxScrollObject_resizeXY;
AjaxScrollObject.prototype.reload = AjaxScrollObject_reload;


AjaxScrollObject.prototype.onMove = AjaxScrollObject_onMove;
