/**
 * Ajax Pager. 
 * 
 */
var Paginator = function(config) 
{
	this.target = config.target;
	this.path = config.path;
	this.spinner_target = config.spinner_target;
	this.inner_target = config.inner_target;
	this.form = config.form;
	this.form_data = {};
	this.page = 1;
	this.sort_field = config.sort_field;
	this.sort_dir = config.sort_dir;
	this.clear_immediate = (config.clear_immediate !== null) ? config.clear_immediate : true;
    this.append_mode = (config.append_mode !== null) ? config.append_mode : false;
    this.page_size = (config.page_size !== null) ? config.page_size : false;
    this.offset = 0;

	/**
	 * Change the page. Sort order and search parameters are preserved.
	 *
	 * @param page the page of data to load
	 */
	this.changePage = function(page)
	{
		this._clear();

		this.page = page;

		var data = {
			page: this.page,
			sortby: this.sort_field,
			order: this.sort_dir,
			offset: this.offset,
			page_size: this.page_size
		};

		// Use the last search data
		for(var field_name in this.form_data)
		{
			data[field_name] = this.form_data[field_name];
		}

		this._ajax(data);
	};
	
	this.refreshPage = function()
	{
		this.changePage(this.page);
	}
	
	/**
	 * Pull the next page. Sort order and search parameters are preserved.
	 *
	 */
	this.nextPage = function()
	{
		this.changePage(this.page + 1);
	};
	
	/**
	 * Increments offset to account for dynamically shifting content.
	 */
	this.incrementOffset = function()
	{
		this.offset++;
	}
	
	/**
	 * Decrements offset to account for dynamically shifting content.
	 */
	this.decrementOffset = function()
	{
		this.offset--;
	}

	/**
	 * Queries the controller passing in values from all input fields in
	 * this.form as well as the last sort field and order. Resets to page 1.
	 */
	this.search = function()
	{
		this._clear();

		var data = {};

		this.page = 1;
		data.page = this.page;
		data.sortby = this.sort_field;
		data.order = this.sort_dir;

		// Add the search form values into the ajax data
		var form_data = {};
		if(this.form)
		{
			var inputs = jQuery(this.form+' :input');
			inputs.each(
				function()
				{
					data[this.name] = jQuery(this).val();
					// keep a copy of the form data for sorting and page changes
					form_data[this.name] = jQuery(this).val();
				}
			);
		}

		this.form_data = form_data;

		this._ajax(data);
	};

	/**
	 * Sort the results. Search parameters are preserved but page is reset to 1
	 *
	 * @param field the field to sort by
	 * @param direction the direction to sort, 'ASC' or 'DESC'
	 */
	this.sort = function(field, direction)
	{
		this._clear();

		this.sort_field = field;
		this.sort_dir = direction;
		this.page = 1;

		var data = {
			page: this.page,
			sortby: this.sort_field,
			order: this.sort_dir
		};

		// Use the last search data
		for(var field_name in this.form_data)
		{
			data[field_name] = this.form_data[field_name];
		}

		this._ajax(data);
	};

	/**
	 * Perform an asynchronous query to the controller action at this.path
	 * using the supplied data object as GET parameters. The request returns to
	 * and is handled by this._handleResponse
	 *
	 * @param data the data to send as parameters to the controller
	 */
	this._ajax = function(data)
	{
		var request_object = {
			url: this.path,
			type: 'GET',
			data: data,
			dataType: 'html',
			context: this,
			success: this._handleResponse
		};

		// do it
		jQuery.ajax(request_object);
	};

	/**
	 * Shows the spinner and fades all children of this.inner_target or, if not
	 * available, this.target
	 */
	this._clear = function()
	{
		jQuery(this.spinner_target).show();
		if(this.clear_immediate && !this.append_mode)
		{
            alert(this.clear_immediate);
			if(this.inner_target)
			{
				jQuery(this.inner_target).children().fadeOut('slow');
			}
			else
			{
				jQuery(this.target).children().fadeOut('slow');
			}
		}
	};

	/**
	 * Handles an ajax response by removing all children of this.target and then
	 * setting this.targets innerHTML to the ajax response text, which would
	 * ideally be a processed template representing the data requested.
	 *
	 * This is called automatically by jQuery when the ajax call returns.
	 *
	 * @param ajax_response the response text from jQuery
	 */
	this._handleResponse = function(ajax_response)
	{
		jQuery(this.spinner_target).hide();
        if(this.append_mode) {
            jQuery(this.target).html(ajax_response);
        }
        else {
            jQuery(this.target).replaceWith(ajax_response);
        }
		if(this.inner_target)
		{
			jQuery(this.inner_target).fadeIn('slow');
		}
		else 
		{
			jQuery(this.target).fadeIn('slow');
		}
		
	};
	
};

