/**
 * Paginator Class
 * @param settings - An object that sets the overriding settings based on this.settings
 * @author Dallas Gutauckis <dgutauckis@myyearbook.com>
 */
function Paginator(settings)
{
  /**
   * Settings container
   * 
   * The callback function should accept two parameters: pageNumber, and context
   *   - Context is the Paginator object that processed the event. The callback function, 
   *     when it has completed the content change, should call context.buildPaginator() 
   */
  this.settings = $.extend({
      callbackChangePageTo: undefined,
      container: $(''),
      itemCount: 0,
      itemsPerPage: 10,
      page: 1
    }, settings);
  
  this.initialize = function() {
    if ( this.settings.container.size() != 0 )
    {
      this.buildPaginator();
    }
  };
  
  this.pageCount = 0;
  
  /**
   * Event fired when one of the pagination options is clicked
   */
  this.pageClicked = function(e){
    var context = e.data.context;
    var nextVal = $(this).text();
    if ( $(this).hasClass('prev') )
    {
      nextVal = 1;
    } else if ( $(this).hasClass('next') ) {
      var lastPage = Math.ceil( context.settings.itemCount / context.settings.itemsPerPage );
      nextVal = lastPage;
    }

    nextVal = parseInt( nextVal );
    context.settings.page = nextVal;
    
    if ( context.settings.callbackChangePageTo != undefined )
    {
      context.settings.callbackChangePageTo( nextVal, context );
    } else {
      context.buildPaginator(); 
    } 
  };
  
  this.getPageCount = function()
  {
    return Math.ceil( this.settings.itemCount / this.settings.itemsPerPage );
  },
  
  this.changePage = function( difference )
  {
    nextVal = this.settings.page + difference;
    
    if ( nextVal >= 0 && nextVal <= this.getPageCount() )
    {
      if ( this.settings.callbackChangePageTo != undefined )
      {
        this.settings.callbackChangePageTo( nextVal, this );
      }
      this.buildPaginator();
      return true;
    }
    else
    {
      return false;
    }
  },
  
  /**
   * Builds the paginator html
   */
  this.buildPaginator = function() {
    var pageCount = this.getPageCount();
    
    if ( this.settings.page > pageCount && this.settings.itemCount > 0 )
    {
      this.settings.page = pageCount;
      if ( this.settings.callbackChangePageTo != undefined )
      {
        this.settings.callbackChangePageTo( pageCount, this );
      }
    }
    
    this.pageCount = pageCount;
    
    var isShowingFirstPage = false;
    var isShowingLastPage = false;
    if ( pageCount > 1 )
    {
      var html = '';
      // If we're not on page 1
      if ( this.settings.page > 1 )
      {
        // Previous pages
        for ( var i = (this.settings.page - 1); ( ( i >= 1 ) && ( this.settings.page - i <= 1 ) ); i-- )
        {
          var pclass = 'pseudolink';
          if ( i == this.settings.page )
          {
            pclass += ' selected';
          }
          html = '<span class="' + pclass + '">' + i + '</span>' + html;
          if ( i == 1 )
          {
            isShowingFirstPage = true;
          } else if ( i == pageCount )
          {
            isShowingLastPage = true;
          }
        }
        
        if ( i == 1 )
        {
          html = '<span class="pseudolink">1</span>' + html;
          isShowingFirstPage = true;
        } 
      }
      
      // Next pages
      for ( var i = this.settings.page; ( i <= this.settings.page + 1 && i <= pageCount ); i++ )
      {
        var pclass = 'pseudolink';
        if ( i == this.settings.page )
        {
          pclass += ' selected';
        }
        html += '<span class="' + pclass + '">' + i + '</span>';
        if ( i == 1 )
        {
          isShowingFirstPage = true;
        } else if ( i == pageCount )
        {
          isShowingLastPage = true;
        }
      }
      
      if ( i == pageCount )
      {
        html += '<span class="pseudolink">' + i + '</span>';
        isShowingLastPage = true;
      } 
      
      // If we're not already on the first page... show the first page link
      if ( this.settings.page > 1 && ! isShowingFirstPage )
      {
        html = '<span class="pseudolink prev">&laquo;</span>' + html;
      }
      
      // If we're not already on the last page... show the last page link.
      if ( this.settings.page != pageCount && ! isShowingLastPage )
      {
        html += '<span class="pseudolink next">&raquo;</span>';
      }
      
      html = '<div class="paginationPaginator">' + html + '</div>';
      
      var context = this;
    }
    else
    {
      html = '';
    }
    
    this.settings.container.html( html );
    this.settings.container.find('span').bind('click',{context: context},this.pageClicked);
    
    return pageCount;
  }
}
