jQuery(function($){
  function performSearch(page){
    // Generate a new SearchRequest.
    var request = new SearchRequest();
    request.setCriterion('topic', 'campaign', [ 'CAT' ]);
    request.addSortingOrder('published_at', false);
    request.setPage(page);
    request.setPerPage(5);

    // Clear out any previous messages; show thinking indicator.
    $('.api-message').hide();
    $('.api-thinking').show();

    // Create search interface by registering username, request, and callbacks; perform search.
    var search_interface = new Search('Y2F0X3NlYXJjaDpjNHRfNTM0cmNo', request, processResponse, processError);
    search_interface.exec();
  }


  function processError(xml_http_request, message, exception){
    $('.api-thinking').hide();
    $('#api-message-search_error').show();
  }


  function processResponse(request, results){
    // Clear out any previous search results.
    $('.api-container-item').remove();

    // Process stories.
    var stories = results['stories'];
    for( var index = 0; index < stories.length; index++ ){
      var current_story = stories[index];
      var story_id = 'story-' + current_story.id;
      var title = current_story.title;
      var content = current_story.content;
      var summary = current_story.summary;
      var published_identity = current_story.person.published_identity;
      var subtitle = published_identity + ' writes:';

      // Display the retrieved story.
      var story_row = '<div class="api-container-item" id="' + story_id + '">';
      story_row += (title != null) ? '<h2><a href="/story.html#' + current_story.id + '">' + title + '</a></h2>' : '';
      story_row += 
          '<div class="api-container-item-subtitle">' + subtitle + '</div>' + 
          '<div class="api-container-item-summary">' + summary + '</div>' +
          '</div>';
      $('.api-container').append(story_row);
    }
    
    // Display pagination details.
    if( stories.length > 0 ){
      var pagination = results['pagination'];
      for( property in pagination )  pagination[property] = parseInt(pagination[property]);
      generatePageControls('.api-pagination .api-pagination-controls', pagination);
      // generatePageInformation('.api-pagination .api-pagination-info', pagination);
    }
    else {
      $('#api-message-no_items').show();
    }

    $('.api-thinking').hide();
  }
  
  
  function generatePageControls(css_element_reference, pagination, options){
    if( typeof(options) == 'undefined' )  var options = {};
    var page = pagination['page'];
    var per_page = pagination['per_page'];
    var total_pages = pagination['total_pages'];
    var inner_window = (options['inner_window'] != null) ? options['inner_window'] : 2;
    var outer_window = (options['outer_window'] != null) ? options['outer_window'] : 1;
    
    // Remove previous page controls.
    $(css_element_reference + ' a').remove();
    $(css_element_reference + ' span').remove();
    
    // Previous page link.
    var current_page = page - 1;
    var label = (options['prev_label'] != null) ? options['prev_label'] : '&laquo;&nbsp;Prev';
    var css = (current_page == 0) ? 'prev_page, disabled' : 'prev_page';
    (current_page == 0) ?
        $(css_element_reference).append(generatePageSpan(label, css)) : 
        $(css_element_reference).append($(generatePageLink(current_page, label, css)).click(generatePageLinkFunction(current_page)));

    // Link pages.
    var pages_to_link = determinePagesToLink(page, total_pages, inner_window, outer_window);
    for( var index = 0; index < pages_to_link.length; index++ ){
      current_page = pages_to_link[index];
      // Display spacers between page windows.
      if( current_page == -1 ){
        $(css_element_reference).append(generatePageSpan('...'));
        continue;
      }
      
      (current_page == page) ?
          $(css_element_reference).append(generatePageSpan(current_page, 'current')) : 
          $(css_element_reference).append($(generatePageLink(current_page)).click(generatePageLinkFunction(current_page)));
    }
    
    // Next page link.
    current_page = page + 1;
    label = (options['next_label'] != null) ? options['next_label'] : 'Next&nbsp;&raquo;';
    css = (current_page > total_pages) ? 'next_page, disabled' : 'next_page';
    (current_page > total_pages) ?
        $(css_element_reference).append(generatePageSpan(label, css)) : 
        $(css_element_reference).append($(generatePageLink(current_page, label, css)).click(generatePageLinkFunction(current_page)));
  }
  
  
  function determinePagesToLink(page, total_pages, inner_window, outer_window){
    var pages_to_link = [];
    
    // Page links; 1 + outer window.
    var upper_bound = (1 + outer_window < total_pages) ? 1 + outer_window : total_pages;
    for( var current_page = 1; current_page <= upper_bound; current_page++ ){
      pages_to_link.push(current_page);
    }
    
    // Page links; inner window + page + inner window.  Check to see if we need to add a spacer.
    var lower_bound = (page - inner_window <= upper_bound) ? upper_bound + 1 : page - inner_window;
    if( page - inner_window > upper_bound + 1 )  pages_to_link.push(-1);
    upper_bound = (page + inner_window < total_pages) ? page + inner_window : total_pages;
    for( var current_page = lower_bound; current_page <= upper_bound; current_page++ ){
      pages_to_link.push(current_page);
    }
    
    // Page links: outer window + last.  Check to see if we need to add a spacer.
    lower_bound = (total_pages - outer_window <= upper_bound) ? upper_bound + 1 : total_pages - outer_window;
    if( total_pages - outer_window > upper_bound + 1 )  pages_to_link.push(-1);
    upper_bound = total_pages;
    for( var current_page = lower_bound; current_page <= upper_bound; current_page++ ){
      pages_to_link.push(current_page);
    }
    
    return pages_to_link;
  }
  
  
  function generatePageSpan(label, css){
    var output = '<span';
    output += (typeof(css) != 'undefined') ? ' class="' + css + '"' : '';
    output += '>' + label + '</span>';
    return output;
  }
  
  
  function generatePageLink(current_page, label, css){
    if( typeof(label) == 'undefined' )  var label = current_page;
    var output = '<a href="#' + current_page + '"';
    output += (typeof(css) != 'undefined') ? ' class="' + css + '"' : '';
    output += '>' + label + '</a>';
    return output;
  }
  
  
  function generatePageLinkFunction(current_page){
    return (function(){ performSearch(current_page); });
  }
  
  
  function generatePageInformation(css_element_reference, pagination, options){
    if( typeof(options) == 'undefined' )  var options = {};
    var page = pagination['page'];
    var per_page = pagination['per_page'];
    var total_entries = pagination['total_entries'];
    var lower_bound = ((page - 1) * per_page) + 1;
    var upper_bound = (page * per_page < total_entries) ? page * per_page : total_entries;

    var output = 'Displaying <strong>' + lower_bound + '&nbsp;-&nbsp;' + upper_bound + '</strong>' +
        ' of <strong>' + total_entries + '</strong> total stories.';
    $(css_element_reference).html(output);
  }
  
  
  function redirectSearch(){
    var element_all_words = $('#api-input_controls-search_terms')[0];

    if( ! hasValue(element_all_words) ){
      alert('Please specify at least one search criteria.');
      return;
    }
    
    var search_uri = window.location.protocol + '//' + window.location.host + '/story_search.html#' + escape(element_all_words.value);
    window.location.href = search_uri;
  }

  
  // Prepare page when the DOM is ready.
  $(document).ready(function(){ 
    $('.api-input_controls button').click(function(){ redirectSearch(); });
    performSearch(1);
  });

});
