
/**
 * cspkPager - Object used to assist AJAX-enabled paging
 * The pager is always associated with an ajax method that uses a model's "api_search" function
 * and then returns formatted html based on the result set.
 * 
 * @param {Object} A pager endpoint as defined in cityspk.api.pager_endpoints
 * @param {string|DOM element} The selector of the DOM element containing the page items
 * @param {string|DOM element} The selector of the DOM element containing the pager HTML
 * @param {string|DOM element} The selector of the DOM element containing the sorter HTML
 * @param {Object} The search parameters to pass to the api_search function
 * @param {Object} The search options to pass to the api_search function
 * @param {Object} Extra information to pass to the backend (optional)
 * @param {Object} Callback occuring after a successful reload() (optional)
 */
var cspkPager = function(endpoint, items_holder, pager_holder, sorter_holder, searchParams, searchOptions, searchContext, postloadMethod)
{
  this.fadeSpeed = 100;
  this.pending = false;
  
  this.endpoint = endpoint;
  
  this.sorter_holder = $(sorter_holder);
  this.pager_holder = $(pager_holder);
  this.items_holder = $(items_holder);
  this.items = this.items_holder.find('.pager_item');
  this.num_items = this.items.length;

  this.searchParams = searchParams ? searchParams : {};
  this.searchOptions = searchOptions ? searchOptions : {};
  this.searchContext = searchContext ? searchContext : {};
  
  this.searchOptions.page = 1;
  
  //Keep a copy of the original searchParams and searchOptions for clientnav
  this.orig_sp = new cloneObject(this.searchParams);
  this.orig_so = new cloneObject(this.searchOptions);
  
  this.postloadMethod = postloadMethod;

  this.items.hide(); //just hide quickly on a page load
  
  var tempPager = this;
  this.clientNav = new ClientNavigator(function(URLArray) { tempPager.onURLChange(URLArray); } );
  this.clientNav.start();
  
  if (this.num_items) this.chainShowItem(0);
};



cspkPager.prototype.chainShowItem = function(index)
{
  if (index >= this.num_items || this.pending) return;
  var temp_pager = this;
  this.items.eq(index).fadeIn(this.fadeSpeed, function() { temp_pager.chainShowItem(index+1); });
};

cspkPager.prototype.hideItems = function(callback)
{
  if (!callback) callback = function(){};
  if (!this.num_items)
  {
    callback();
    return;
  }
  var i =0;
  var temp_num_items = this.num_items;
  this.items.fadeOut(this.fadeSpeed, function()
  {
    i++;
    if (i >= temp_num_items) callback();
  });
};

cspkPager.prototype.pageChange = function(num, menuitem)
{
  if (this.pending) return;
  this.pager_holder.find(".pagination_filter_insert a").removeClass("active");
  this.searchOptions.page = num;
  this.updateURLFromState();
};

cspkPager.prototype.sortChange = function(sort, menuitemindex)
{
  if (this.pending) return;
  this.sorter_holder.find(".pagination_filter_insert a").removeClass("active").eq(menuitemindex).addClass("active"); //problem
  this.searchOptions.sort = sort;
  this.searchOptions.page = 1;
  this.updateURLFromState();
};

cspkPager.prototype.startPending = function()
{
  this.pending = true;
  //TODO: loading animation
};

cspkPager.prototype.stopPending = function()
{
  this.pending = false;
  //TODO: stop loading animation 
};

cspkPager.prototype.onURLChange = function(URLArray)
{
  this.searchParams = new cloneObject(this.orig_sp);
  this.searchOptions = new cloneObject(this.orig_so);
  var i;
  for (i=0; i < URLArray.length - 1; i=i+2)
  {
    var key = URLArray[i];
    var val = URLArray[i+1];
    if (key == "sort" || key == "page") {
      this.searchOptions[key] = val;
    } else {
      this.searchParams[key] = val;
    }
  };
  this.reload();
};

cspkPager.prototype.updateURLFromState = function()
{
  if (!this.clientNav) return;
  
  var anchorString = "";
  for (var key in this.searchParams)
  {
    var val = this.searchParams[key];
    if (val != this.orig_sp[key])
      anchorString += "/"+key+"/"+val;
  };
  if (this.searchOptions.sort && this.orig_so.sort != this.searchOptions.sort)
    anchorString += "/sort/"+this.searchOptions.sort;
  
  if (this.searchOptions.page && this.orig_so.page != this.searchOptions.page)
    anchorString += "/page/"+this.searchOptions.page;

  this.clientNav.URL(anchorString);

};

cspkPager.prototype.reload = function()
{
  this.startPending();
  var temp_pager = this;
  this.hideItems(function()
  {
    cityspk.api.pager(function(response)
    {
      if (temp_pager.clientNav) temp_pager.clientNav.isLoading = false;
      if (response.type == cityspk.SUCCESS)
      {
        temp_pager.items_holder.hide().html(response.data.html);
        temp_pager.pager_holder.each(function() { $(this).html(response.data.pager_html); } ); //IE bug workaround
        temp_pager.items = temp_pager.items_holder.find(".pager_item");
        temp_pager.num_items = temp_pager.items.length;
        temp_pager.items.hide();
        temp_pager.items_holder.css("display","block");
        temp_pager.stopPending();
        if (temp_pager.num_items) temp_pager.chainShowItem(0);
        if (temp_pager.postloadMethod) temp_pager.postloadMethod(response);
      } else temp_pager.stopPending();
    }, temp_pager.endpoint, temp_pager.searchParams, temp_pager.searchOptions, temp_pager.searchContext);
  });
};

