(function() {

  var PER_PAGE_DEFAULT = 100;
  var INFINITE_SCROLL_DELAY = 500;
  
  var enable_scoll_load = true;
  
  var page = 1;
  var total_pages = 1;

  var search_terms = "";
  var search_terms_in_progress = null;
  
  var new_search = true;

  function enqueue(song_id) {
    $('tr#row_' + song_id).addClass('selected');
  	$('input.enqueueButton').attr('disabled', 'disabled');
  
    var cancelled = false;
  	
  	// Prompt for a control code if one isn't established
  	if (window.name === "") {
  	  cancelled = true;
  	  var prompt_result = prompt("Please enter the control code on your suite's screen");
  	  if (prompt_result !== '' && prompt_result !== null) {
  	    window.name = prompt_result;
        cancelled = false;
      };
  	};
  	
    var done = function() {
      $('input.enqueueButton').removeAttr('disabled');
    	$('tr.selected').removeClass('selected');
    };

  	var handle_success = function() {
  	  $('tr.selected').addClass('success');
  	  done();
  	};
  	
  	var handle_error = function(xhr) {
      // Respond based on the error type
      switch(xhr.status) {
        // Forbidden.  This means it's the wrong room code
        // reset the control code to nil and recursively try again
        case 403: 
          window.name = '';
          enqueue(song_id);
          break;
          
        default:
          alert("Something's gone wrong :( - Please tell your server");
          done();
          break;
      };
		};
		
		// Perform the enqueue ajax request if
		// we haven't cancelled the enqueue process
		// (ie, we cancelled out of entering the room code)
  	if (!cancelled) {

  	  var data = {
    	  song_id: song_id,
    	  room_code: window.name
    	};
  	  
      $.ajax({
        url: '/api/v1/queue',
        type: 'POST',
        data: data,
        dataType: 'json',
        timeout: 40000,
        success: handle_success,
        error: handle_error
      });
      
    } else {
      done();  // just clean up if we're not doing the request
    };
  };

  function begin_search() {
    enable_scroll_load = false;
  	$('#spinner').show();
  };
  
  function pre_search() {
    $('#searchResults').html('');
  	$('#searchForm > input').attr('disabled', 'disabled');
  	$(document).scrollTop(0);
  };
        
  function process_search_result(data) {
    
    total_pages = data.total_pages; 
        
    var current_artist = null;
    var current_buffer = $();  // a DOM structure to build up for each artist's songs
    var wrapper_id = 'resultsPage-' + page;
    var page_wrapper = $('<div/>', {id: wrapper_id });
    
    $.each(data.songs, function(index, song) {
      if (song.artist !== current_artist) {
        if (current_artist !== null) {
          // starting a new artist, output the buffer for the previous artist
          $(page_wrapper).append(current_buffer)
        };
        current_buffer = $('<div/>').addClass("artist_results").append($('#_artistTable').tmpl(song));
        current_artist = song.artist;
      };
      $('table.songs > tbody:last', current_buffer).append($('#_songsByArtist').tmpl(song))
    });
    $(page_wrapper).append(current_buffer);
    $("#searchResults").append(page_wrapper);
    $("#" + wrapper_id).hide().fadeIn(500);
    
    search_terms_in_progress = null;
  };

  function complete_search() {
  	$('#spinner').hide();
    $('#loadingNotice').hide();
  	enable_scroll_load = true;
  };

  function copy_params_to_URL() {
    $.address.history(true);
    $.address.parameter('query', search_terms);
    //$.address.parameter('page', page);
    $.address.update();
  };
  
  function copy_URL_to_params() {
    search_terms = $.address.parameter('query');
    if (!search_terms) {
      search_terms = "";
    } else {
      search_terms = unescape(search_terms);
      $('#query').attr('value', search_terms);
    };
    page = 1;

  };

  function process_query() {
    if (search_terms && search_terms !== search_terms_in_progress) {
      search_terms_in_progress = search_terms;
      $.ajax({
    		url: '/api/v1/songs/search',
    		data: {'query': search_terms, 'per_page': PER_PAGE_DEFAULT, 'page': page},
    		type: 'GET',
    		dataType: 'json',
    		beforeSend: begin_search,
    		success: process_search_result,
    		error: function() {
    		  search_terms_in_progress = null;
    		},
    		complete: complete_search
      });
    };
  };

  function clear_params() {
    var params = $.address.parameterNames();
    $.each(params, function(i,v) {
      $.address.parameter(v, null);
    });
  };
  
  function near_bottom() {
    var threshold = $(document).height() - ($(window).height() + 200);
    return ($(window).scrollTop() > threshold)
  };
  
  function manage_loading_notice() {
    if ( (page < total_pages) && near_bottom() ) {
      $('#loadingNotice').show();
    }
  }
  
  function handle_infinite_scroll() {
    
    // is there more data to load?
    if (page < total_pages) {
      // are we near the bottom of the page?
      if (near_bottom() && enable_scroll_load) {
        $('#loadingNotice').show();
        page += 1;
        process_query();
      };
    };
  };

  $(document).ready(function() {

    complete_search();
	  clear_params();
	    
    // activate handling of deep linking
    $.address.autoUpdate(false);
    $.address.history(false);
  	$.address.externalChange(function(e) {
  	  if (typeof e !== 'function') {
    	  copy_URL_to_params();
    	  pre_search();
    	  process_query();
  	  }
  	});

    // override search form to use deep linking
    $('#searchForm').submit(function() {
      search_terms = this.query.value;
      page = 1;
      copy_params_to_URL();
      $('#query').blur();
      pre_search();
      process_query();
      return false;
    });

    $('#query').click(function() {
      this.focus();
      this.select();
      this.value = "";
    });

    $('#reset').click(function() {
      $('#query').focus();
    });
    
    // set up infinite scroll
    // scroll_timer = setInterval(handle_infinite_scroll, 1000);
    $(window).scroll(handle_infinite_scroll);
  });
  
  document.enqueue = enqueue;

})();
