/*
 * pagination.js
 *
 */
var Pagination = {

  inner_window: 2, // links around the current page
  outer_window: 0, // links around beginning and end
  gap_marker: '<span class="gap">&hellip;</span>',
  separator: ' ',
  previous_label: '&laquo; Previous',
  next_label: 'Next &raquo;',
  total_pages: null,
  current_page: null,
  total_entries: null,
  entries: null,
  per_page: null,
  offset: null,
  
  init: function(pagination) {
    Pagination.total_entries = pagination["total_entries"];
    Pagination.entries = pagination["entries"];
    Pagination.per_page = pagination["per_page"];
    Pagination.offset = pagination["offset"];
    
    Pagination.total_pages = Math.ceil(Pagination.total_entries / Pagination.per_page) || 1;
    Pagination.current_page = (Pagination.offset / Pagination.per_page) + 1;
  },
  
  paginate: function() {    
    links = Pagination.windowed_links();

    links.unshift(Pagination.page_link_or_span(Pagination.previous_page(), 'disabled prev_page', Pagination.previous_label));
    links.push(Pagination.page_link_or_span(Pagination.next_page(), 'disabled next_page', Pagination.next_label));
        
    html = links.join(Pagination.separator);

    return html;
  },
  
  pagination_info: function() {
    var from = Pagination.offset + 1;
    var to = Pagination.offset + Pagination.per_page;
    var total = Pagination.total_entries;
    if (to > total) to = total;
    
    return from + "-" + to + " of " + total;
  },
  
  visible_page_numbers: function() {
    window_from = Pagination.current_page - Pagination.inner_window;
    window_to = Pagination.current_page + Pagination.inner_window;

    // adjust lower or upper limit if other is out of bounds
    if(window_to > Pagination.total_pages) {
      window_from -= window_to - Pagination.total_pages;
      window_to = Pagination.total_pages;
    }
    if(window_from < 1) {
      window_to += 1 - window_from;
      window_from = 1;
      if(window_to > Pagination.total_pages)
        window_to = Pagination.total_pages;
    }

    visible = [];
    left_gap = [];
    right_gap = [];
    for(i=1; i<=Pagination.total_pages; i++) visible.push(i);
    for(i=(2 + Pagination.outer_window); i<=(window_from - 1); i++) left_gap.push(i);
    for(i=(window_to + 1); i<=(Pagination.total_pages - Pagination.outer_window - 1); i++) right_gap.push(i);
    if(left_gap[left_gap.length - 1] + 1 - left_gap[0] > 1) {
     for(i=0; i<left_gap.length; i++) {
       index = jQuery.inArray(left_gap[i], visible);
       if(index >= 0) visible.splice(index,1);
     }
    }
    if(right_gap[right_gap.length - 1] + 1 - right_gap[0] > 1) {
      for(i=0; i<right_gap.length; i++) {
        index = jQuery.inArray(right_gap[i], visible);
        if(index >= 0) visible.splice(index,1);
      }
    }
    
    return visible;
  },
  
  windowed_links: function() {
    links = [];
    prev = null;
    
    $.each(Pagination.visible_page_numbers(), function(i, obj) {
      if(prev && obj > prev + 1) links.push(Pagination.gap_marker);
      links.push(Pagination.page_link_or_span(obj, 'current'));
      prev = obj;
    });
    
    return links;
  },

  previous_page: function() {
    return Pagination.current_page > 1 ? (Pagination.current_page - 1) : null;
  },
  
  next_page: function() {
    return Pagination.current_page < Pagination.total_pages ? (Pagination.current_page + 1) : null;
  },
  
  page_link_or_span: function(page, span_class, text) {
    text = text || page.toString();
    
    if(page && page != Pagination.current_page) {
      classnames = span_class && span_class.indexOf(' ') && span_class.split(' ')[span_class.split(' ').length-1];
      return '<a href="'+Url.new_url({page: page})+'" class="'+span_class+'">'+text+'</a>';
    } else {
      return '<span class="'+span_class+'">'+text+'</span>';
    }
  }

};
