 /* Set to TRUE to enable test output data to  be written to a div (id: scrolldebug) */
 var scroll_debug_mode = false;
 
 /*
  * This determines at what point of scrolling down the current set of results to trigger
  * the loading of the next page of data. This value represents a PERCENTAGE of the current
  * set and is measured at the top of the scroll pane. Example: 0.5 for halfway, 0.2 for 1/5
  * of the way. Setting this too high (i.e. 9.0) can result in the user seeing empty space 
  * below the results before the next page is loaded, unless the page size is very larege
  */
  var triggerPoint = 0.5;
 
 /*
  * Settings to configure individual widget scrolling parameters. The values here
  * allow us to know how big each record in a widget is so that we know how big
  * to render the div so that the scrollbar remains consistent despite how many
  * actual pages of results are loaded.
  */
 function ScrollConfig( widgetId, startOffset, itemsPerPage, itemHeight, itemsInView )
 {
  this.widgetId = widgetId;
  
  // We need this to determine how many items we have scrolled past based on the size
  // of each item and the difference between the current offset and the original
  this.startOffset = startOffset;
  
  // Track the size of the pane that we see the results in
  this.itemsInView = itemsInView;
  this.scrollpaneHeight = ( itemsInView * itemHeight );
  
  // Track the current offset, from the bottom of the viewport
  this.currentOffset = ( startOffset - ( itemsInView * itemHeight ) );
  
  this.itemsPerPage = itemsPerPage;
  this.itemHeight = itemHeight;
  this.pageHeight = ( itemsPerPage * itemHeight );
  //this.cacheSize = cacheSize;
  
  // List of parameters as a URI string to pass along with the request for the next page
  this.params = "";

  // Which field results are currently sorted by so we know which icon to change
  this.sortBy = "";
  
  this.pagesLoaded = 1;			  // The number of pages that have been loaded
  this.pageCount = 1;					// Total number of pages available to get
  
  this.itemsLoaded = itemsPerPage;    // Defaults to the size of the first page, unless there is fewer than one page
  this.itemCount = 1;                 // Total number of results displayed. Some margin of error because the
                                      // last page might not be a full page of results

  this.getTotalHeight = function() { return ( this.itemHeight * this.itemCount ); }
  this.getCurrentHeight = function() 
    { 
      return ( this.itemsLoaded * this.itemHeight );
      //return ( this.pageHeight * this.pagesLoaded ); 
    }
  
  // The checkpoint at which to load the next page of data
  this.nextLoadAt = 0;	
  
  this.updateNextLoadAt = 
  	function()
  	{
  		// If the current number of pages loaded is equal to the total number of pages, set the
  		// next load to an unreachable number so that it doesn't get triggered again
  		if( this.pagesLoaded == this.pageCount )
  		{
  			this.nextLoadAt = 10000;
  			return;
  		}
  		
  		// As you scroll downward the offset gets smaller, even into the negatives. So make
  		// sure that the next load happens at a lower number. Set the checkpoint to when the 
  		// bottom of the scroll pane is at a percentage of the way through the current result set. 
  		// This  should allow plenty of time for the data to load before they get there
  		this.nextLoadAt = ( this.startOffset - Math.round( this.getCurrentHeight() * triggerPoint ) );
  	}
  	
  this.updateItemsLoaded =
    function()
    {
      if( this.pagesLoaded >= this.pageCount )
        this.itemsLoaded = this.itemCount;
  	  else
        this.itemsLoaded = ( this.pagesLoaded * this.itemsPerPage );
        
      if( this.itemsLoaded > this.itemCount )
        this.itemsLoaded = this.itemCount;
    }
    
 }
  
 // Extracts the WidgetId from the scroll pane element name, and returns it
 function extractWID( paneId )
 {
  // Pull the substring out
  widgetId = paneId.replace(/scrollpane_/, "");
  
  return widgetId;
 }

 function dout( str, app, widget_id )
 {
  // Only use if debug mode is enabled
  if( !scroll_debug_mode )
    return;
  
  if( app )
    document.getElementById("scrolldebug").innerHTML += str;
  else
    document.getElementById("scrolldebug").innerHTML = str;
 }
 
 var activeScrollpane = null;
 
 // Execute only after the page has finished loading
 jQuery(document).ready(function()
 {
   jQuery('.scroll-pane').jScrollPane( {showArrows:true, minDragHeight:25, scrollbarWidth:15, scrollbarMargin:0} );
     
   // Bind a default event to the scroll so we can also track which widget is being scrolled and should be monitored
   jQuery('.scroll-pane').bind(
     'scroll',
     function()
     {       
       // Get and store the active scrollpane
       var scrollpane = jQuery(this);
       activeScrollpane = scrollpane;
      
       // Get the ID of the widget that this scroll pane belongs to so we can update the correct one
       widget_id = extractWID(jQuery(this).attr("id"));
       
       // Alias for the object
       widgetObj = eval("w_" + widget_id);
       
       // If we've already loaded all the pages, don't do anything else. Saves some processing time
       if( widgetObj.pagesLoaded >= widgetObj.pageTotal )
       	return;
       
       // If start offset is not yet set, determine it and set it now, as well as set the point to update the data
       startOffset = widgetObj.startOffset;
       if( startOffset == 0 )
       {
        // Set the starting offset to the top position of the page_* element
        startOffset = jQuery(this).parent().parent().offset().top;
        //startOffset = jQuery(this).offset().top;
        
        widgetObj.startOffset = startOffset;
        widgetObj.updateNextLoadAt();
       }
       
       // Set current offset. We check based on the bottom of the pane so subtract the height of it to the offset
       currentOffset = ( jQuery(this).offset().top - widgetObj.scrollpaneHeight );
       
       widgetObj.currentOffset = currentOffset;
       
       // If the current offset is less than the trigger point for loading the next page, and not all pages are loaded yet,
       // fire off the next page load
       if( widgetObj.pagesLoaded < widgetObj.pageCount && currentOffset <= widgetObj.nextLoadAt  )
       {
        // Make sure that the sort method doesn't get changed
        change_sort = false;
        
       	// If all pages have already been loaded, stop here
       	loadWidgetContent( widget_id, widgetObj.params );
       	
       	if( scroll_debug_mode )
       	  dout("<br><b><font style='font-size: 12pt'>LOADING PAGE " + widgetObj.pagesLoaded + " of " + eval("w_" + widget_id).pageCount + "</font><br> ", 1);
       }
       else
       {
	        if( scroll_debug_mode )
	        {
		       // If the startOffset value does not exist in the config for the widget scrolling, set it now
		       dout("<b>Actively scrolling: " + widget_id + "</b><br>", 0 );
		       dout(" Starting offset: " + startOffset + "<br>", 1);
		       dout(" Current offset (direct): " + currentOffset + "<br>", 1);
		       dout(" Next load at: " + widgetObj.nextLoadAt + "<br>", 1);
		       dout(" Pages loaded: " + widgetObj.pagesLoaded + " of " + eval("w_" + widget_id).pageCount + 
		              " ( " + widgetObj.itemsLoaded + " of " + eval("w_" + widget_id).itemCount + " items )<br>", 1);
		       dout(" Sizer height: " + document.getElementById("scrollsizer_" + widget_id ).style.height + "<br>", 1);
		       dout(" Scrollpane height: " + document.getElementById("scrollpane_" + widget_id).style.height + "<br>", 1);
           dout(" Page height: " + document.getElementById("page_" + widget_id).style.height + "<br>", 1);
	        }
        
       }
       
       return false;        
     });

 });

 /*
	* Actviate/reactivate scrollbars - has to be done any time a scrollbar pane is replaced, such as character log filtering
  */
 function activateScrollbars()
 {
  jQuery('.scroll-pane').jScrollPane( {showArrows:true, minDragHeight:25, scrollbarWidth:15, scrollbarMargin:0} );
 }
 
 /*
  * Resize the divs for controlling the scroll area heights
  */
  function resizeScrollDivs( widget_id, pane, sizer, page )
  {
    if( null != page )
      document.getElementById( "page_" + widget_id ).style.height = page;
    
    if( null != pane )
      document.getElementById( "scrollpane_" + widget_id ).style.height = pane;
    
    if( null != sizer )
      document.getElementById( "scrollsizer_" + widget_id ).style.height = sizer;
      
    turbine_j("div#page_" + widget_id + " .jScrollPaneContainer").height( pane );
  }
  
  
  /**********************************************************\
    Debug stuff
  \**********************************************************/
  
  function createDebugPane( widgetId )
  {
    if( !scroll_debug_mode )
      return null;
  
    jQuery("#page").append('<div id="scrolldebug_' + widgetId + '">&nbsp;</div>');
  }
  
  /* If scroll debug mode is enabled, create the pane that displays the debug info */
  if( scroll_debug_mode )
  {
	  jQuery(document).ready(function()
	  {
	    // First thing first .. create the DIV to display the info
	    jQuery("#page").prepend('<div id="scrolldebug">Test scrolldebug element</div>');
	    
	    jQuery(window).bind(
	    'scroll',
	    function()
	     {     
	       if( document.body.scrollTop )
	         sTop = document.body.scrollTop;
	       else
	         sTop = document.documentElement.scrollTop;
	       
	       document.getElementById("scrolldebug").style.top = ( sTop + 50 ) + "px";
	     });
	   });

	}