/*
* jQuery pager plugin
* Version 0.2.0 (3/7/2009) for americans (7/3/2009)
* @requires jQuery v1.3.1 or later
*
*
* Copyright (c) 2008-2009 Matthew Spence
* Licensed under the GPL licenses:
* http://www.gnu.org/licenses/gpl.html
* 
*
*
*/
(function($) {

  $.widget("ui.ajaxPager", {
  
    // Initial function to create html and behaviours
    _init: function() {
    
      // empty holder
      
      // find out the number of pages
      this.numberOfPages = 0;
      this.numberOfPages += this.options.pages.length;
      this.numberOfPages += this.element.children('*').length;
      
      
      this.currentPage = this.options.page;
      
      // create the html and behaviours
      this.element.html(this._render());
      this.element.append(this._renderLinks());
      
      this.setPage(this.currentPage);
      
      return this;
    },
    
    
    // Create the the html and behaviours
    _render: function () {
    
      var pager = this;
      
      // find predfined pages
      elements = this.element.children('*');
            
      this.element.empty();
      
      $.each(elements,function(t,element){
        if ($(element).attr('class').search(/page(\d+)/)!=-1) {
          pager.options.pages.splice([$(element).attr('class').match(/page(\d+)/)[1]-1],0, {
            content: $(element).html(),
            type: "string"
          });
        }
        
      });
      
      
      // temp holder
      var holder = $("<div></div>");
      
      // page holder
      this.pagesE = $("<div class='ajaxPagerPages'><div class='ajaxPagerCurrentPage'></div></div>");
      holder.append(this.pagesE);
      
      var pages = Array();

      var a = this;
      
      // foreach page
      $.each(this.options.pages, function (k,page) {
        var page = this;

        // create page
        //pages[k] = $("<div class='ajaxPagerPage page"+(k+1)+"'></div>");
        pages[k]={};
        
        // add page to output
//        this.pagesE.append(pages[k]);
        
        // find content
        if (typeof page == 'string' && pager.type == 'string') {
          page = {
            content: page
          }
        } else if (typeof page == 'string') {
          page = {
            url: page
          }
        }
        
        
                
        // store page options in the page 
        pages[k].options = page;
        pages[k].pageNumber = k+1; 
         

      });
      this.pages = pages;
      $.each(pages, function (k,page) {

        if (typeof page != 'object' || typeof page.options != 'object') {
          i++;
          return true;
        }
        
        // add the global on show function to the page if it doesnt have one
        if (typeof page.options.onShow=='function') {
          page.options._onShow = function (i) {
            page.options.onShow(i);
            a.options.onPageShow(i); 
          }; 
          
        } else {
          page.options._onShow = function (i) {
            a.options.onPageShow(i);
          };
        }
        
        // add the global on load function to the page if it doesnt have one
        if (typeof page.options.onLoad=='function') {
          page.options._onLoad = function (i) {
            page.options.onLoad(i);
            a.options.onPageLoad(i); 
            page.loaded=true;
          }; 
          
        } else {
          page.options._onLoad = function (i) {
            a.options.onPageLoad(i);
            page.loaded=true;
          };
        }
        
        // if page type is undefined use the default
        if (typeof page.options.type != 'string') {
          page.options.type = pager.options.type;
        }
        
        // if page on demand is undefined use the default
        if (typeof page.options.preLoad == 'undefined') {
          if (pager.options.preLoad===true) {
            page.options.preLoad = true;
          } else {
            page.options.preLoad = false;
          }
        }
        
        // if page doesnt have a destroyOriginal use global
        if (typeof page.options.destroyOriginal == 'undefined') {
          if (pager.options.destroyOriginal === true) {
            page.options.destroyOriginal = true;
          } else {
            page.options.destroyOriginal = false;
          }
        }
          
        // add the global selector to the page if it doesn't have one
        if (page.options.selector!=false && typeof page.options.selector!='string' && typeof a.options.selector=='string') {
          page.options.selector = a.options.selector.replace(/{i}/g, k+1);
        } 
        // if not on demand load
        if (page.options.preLoad || page.options.type == 'element' || page.options.type=='string') {
          pager._loadPage(page);
        }

      });
      

      
      return holder;
      
    },
    
    // set the page to pageNumber
    setPage: function (pageNumber) {
      
      // save pageNumber
      this.currentPage = pageNumber;
      
      if (!this.pages[pageNumber-1].loaded) {
        // load the page
        this.loadPage(pageNumber);
      }
      
      this._preLoad(this.pages[pageNumber-1]);
      
      // refresh
      this._refresh();
      
      // refresh links
      this._refreshLinks();
      
      //this.options.pages[pageNumber].ong);
      return this;
      
    },
    
    // set page to one more than current
    nextPage: function () {
      this.setPage(this.currentPage+1);
      return this;
    },
    
    // set page to one less than current
    previousPage: function () {
      this.setPage(this.currentPage-1);
      return this;
    },
    
    // set to first page
    firstPage: function () {
      this.setPage(1);
    },
    
    // set to last page
    lastPage: function () {
      this.setPage(this.numberOfPages);
    },
    
    // refresh the status on pages and links
    _refresh: function () {
      
      // add page prefix
      if (typeof this.pages[this.currentPage-1].options.prefix == 'string') {
        prefix = this.pages[this.currentPage-1].options.prefix.replace("{i}",this.currentPage);;
      } else if (typeof this.options.pagePrefix == 'string') {
        prefix = this.options.pagePrefix.replace("{i}",this.currentPage);;
      } else {
        prefix = "";
      }

      // add page suffix
      if (typeof this.pages[this.currentPage-1].options.suffix == 'string') {
        suffix =  this.pages[this.currentPage-1].options.suffix.replace("{i}",this.currentPage);;
      } else if (typeof this.options.pageSuffix == 'string') {
        suffix = this.options.pageSuffix.replace("{i}",this.currentPage);
      } else {
        suffix = "";
      }
      
      this.pagesE.find('.ajaxPagerCurrentPage').html(prefix+this.pages[this.currentPage-1].content+suffix);
      
    },
    
    
    
    
    _refreshLinks: function () {
      
      var pager = this;
      pager.linksE.find('*').remove();
      
      // Find out if wasted links before current page       
      if (pager.options.linkPagesAfter +pager.options.linkPagesEnd - (pager.currentPage)>0 && pager.options.linkOverflow) {
        wastedLinksBefore = pager.options.linkPagesAfter + pager.options.linkPagesEnd - (pager.currentPage);
      } else {
        wastedLinksBefore = 0;
      }
      
      
      // Find out if wasted links before
      if (pager.options.linkPagesBefore +pager.options.linkPagesStart - (pager.numberOfPages - pager.currentPage - 1)>0 && pager.options.linkOverflow) {
        wastedLinksAfter = pager.options.linkPagesBefore + pager.options.linkPagesStart - (pager.numberOfPages - pager.currentPage-1);
      } else {
        wastedLinksAfter = 0;
      }
      console.log(pager.options.linkPagesBefore +"+"+pager.options.linkPagesStart +"- ("+pager.numberOfPages +"-"+ pager.currentPage+")");


      

      
      $.each(this.pages,function (k,page) {
      
        if ((typeof pager.pages[k] == 'object') && (k+1<=pager.options.linkPagesStart || k>=pager.numberOfPages-pager.options.linkPagesEnd || (k>=pager.currentPage-(pager.options.linkPagesBefore+wastedLinksAfter)-1 && k<=pager.currentPage+(pager.options.linkPagesAfter+wastedLinksBefore)-1) || (k+1<pager.currentPage && pager.options.linkPagesBefore==0) || (k+1>pager.currentPage && (pager.options.linkPagesAfter)==0))) {
        
          // create link
          pager.links[k] = $("<div class='ajaxPagerPageLink'>"+(k+1)+"</div>");
          
          // set status
          if (k+1!=pager.currentPage) {
            pager.links[k].addClass('active');
          } else {
            pager.links[k].addClass('disabled').addClass('current');
          }
            
          // store page number
          pager.links[k][0].pageNumber = k+1;
          
          // bind event
          pager.links[k].click(function () {
            if($(this).hasClass('active')) { pager.setPage(this.pageNumber); }
          });
          
          pager.linksE.append(pager.links[k]);
          
          
        } else if (k==pager.currentPage-(pager.options.linkPagesBefore+wastedLinksAfter)-2 || k==pager.currentPage+(pager.options.linkPagesAfter+wastedLinksBefore)) {
          
          // create ...
          pager.links[k] = $("<div class='ajaxPagerPageBreak'>"+pager.options.linkPagesBreak+"</div>");
          
          pager.linksE.append(pager.links[k]);

        }
        
        
      });
      
      // add previous link
      if (this.options.previous) {
        previousLink = $('<div class="ajaxPagerPreviousLink">'+this.options.previousText+'</div>')
          .click(function () { if($(this).hasClass('active')) { pager.previousPage() }});
        // set status
        if (1!=pager.currentPage) {
          previousLink.addClass('active');
        } else {
          previousLink.addClass('disabled').addClass('current');
        } 
        this.linksE.prepend(previousLink);
      }
      
      // add first link
      if (this.options.first) {
        firstLink = $('<div class="ajaxPagerFirstLink">'+this.options.firstText+'</div>')
          .click(function () { if($(this).hasClass('active')) { pager.firstPage() }});
          
        // set status
        if (1!=pager.currentPage) {
          firstLink.addClass('active');
        } else {
          firstLink.addClass('disabled').addClass('current');
        } 
        this.linksE.prepend(firstLink);
      }
      
      // add next link
      if (this.options.next) {
        nextLink = $('<div class="ajaxPagerNextLink">'+this.options. nextText+'</div>')
          .click(function () { if($(this).hasClass('active')) { pager.nextPage() }});
        // set status

        if (pager.numberOfPages!=pager.currentPage) {
          nextLink.addClass('active');
        } else {
          nextLink.addClass('disabled').addClass('current');
        }  
        this.linksE.append(nextLink);
      }
      
      // add last link
      if (this.options.last) {
        lastLink = $('<div class="ajaxPagerLastLink">'+this.options.lastText+'</div>')
          .click(function () { if($(this).hasClass('active')) { pager.lastPage() }});
        // set status
        if (pager.numberOfPages!=pager.currentPage) {
          lastLink.addClass('active');
        } else {
          lastLink.addClass('disabled').addClass('current');
        } 
        this.linksE.append(lastLink);
      }
      
    },
    _renderLinks: function () {
      
      this.links = Array();
      var links = this.links;
      
      // links holder
      this.linksE = $('<div class="ajaxPagerLinks"></div>');
      
      this._refreshLinks();
      
      return this.linksE;
      
    },
    
    loadPage: function (pageNumber) {
      this._loadPage(this.pages[pageNumber-1]);
    },
    
    _preLoad: function (page) {
      if (this.options.preLoad>1) {
        for(i=0;i<=this.options.preLoad;i++) {
          if (typeof this.pages[page.pageNumber+i] == 'object' && !this.pages[page.pageNumber+i].loaded) {
            this._loadPage(this.pages[page.pageNumber+i]);
          }
          
        }
      }
    },
    
    _loadPage: function (page) {
      pager = this;
      // generate page content
      switch (page.options.type) {
        
        // for static strings
        case "string":
          page.content = page.options.content;
          page.options._onLoad(page.pageNumber);         
          break;
          
        // for ajax
        case "ajax":
          
          // set content to "Loading..."
          if (typeof page.options.loadingText == 'string') {
            page.content = page.options.loadingText.replace("{i}",page.pageNumber);  
          } else {
            page.content = this.options.loadingText.replace("{i}",page.pageNumber);
          }
          
          
          $.ajax({
            'url': page.options.url,
            success: function (data) {
              
              if (typeof page.options.selector != 'undefined' && page.options.selector != false) {
                page.content = $(page.options.selector,$("<div>"+data+"</div>")).html();
              } else if ($(data).find('body').length>0) {
                page.content = $(data).find('body').html();
              } else {
                page.content = data;
              }
              
              pager._refresh();
              page.options._onLoad(page.pageNumber);
              
            }
            
          });
          break;
          
        
        // for iframes
        case "iframe":

          page.content = '<iframe src ="'+page.options.url+'"><p>Your browser does not support iframes.</p></iframe>';
          page.options._onLoad(page.pageNumber);
          break;
        
        // other elements
        case "element":

          if ($(page.options.selector).length>0) {          
            page.content = $(page.options.selector).html()
          };
          if (page.options.destroyOriginal) {
            $(page.options.selector).remove();
          }
          page.options._onLoad(page.pageNumber);
          break;
          
      }
        
    },
    
    reloadPage: function (pageNumber) {
      this.pages[pageNumber-1].loaded = false;
      this.loadPage(pageNumber);
      this._refresh();
    },
    
    reloadAll: function () {
      for(var k in this.pages) {
        this.reloadPage(parseInt(k)+1);
      }
    },
    
    loadAll: function () {
      for(var k in this.pages) {
        this.loadPage(parseInt(k)+1);
      }
    },
    
    
    reloadPageOnDemand: function (pageNumber) {
      this.pages[pageNumber-1].loaded = false;
    },
    
    reloadAllOnDemand: function () {
      for(var k in this.pages) {
        this.reloadPageOnDemand(parseInt(k)+1);
      }
    }
    
    
  });
  
  $.extend($.ui.ajaxPager, {
    defaults: {
      previous: true,
      destroyOriginal: true,
      previousText: "&lt;",
      next: true,
      nextText: "&gt;",
      first: true,
      firstText: "&#x7c;&lt;",
      last: true,
      lastText: "&gt;&#x7c;",
      linkPagesStart: 2,
      linkPagesBefore: 5,
      linkPagesAfter: 5,
      linkPagesEnd: 2,
      linkPagesBreak: "...",
      linkOverflow: true,
      linkPagesMax: 0,
      onDemand: 0,
      pagePrefix: "",
      pageSuffix: "",
      page: 1,
      type: 'string',
      onPageShow: function () {},
      onPageLoad: function () {},
      pagePrefix: null,
      pageSuffix: null,
      loadingText: "Loading...",
      pages: Array()
      
    }
  });
  
})(jQuery);

