var PaginateDiv = Class.create({
	initialize: function(div)
	{
		this.div = false;
		if (!$(div))
		{
			throw "The element you specified does not exists in the DOM, please create this element first";
		}
		if (!div)
		{
			throw "Please specify a div you have created to contain the pagination links";
		}
		this.div = div;
		if ($(this.div+'_2'))
		{
			this.div2 = div+'_2';
		}
		this.obj = this;
		this.format = 'json';
		this.page = 1;
	},
	getDiv: function()
	{
		return this.div;
	},
	setTotal: function(total)
	{
		this.total = false;
		if (total != parseInt(total))
		{
			throw "Total must be numeric";
		}
		this.total = total;
	},
	getTotal: function()
	{
		return this.total;
	},
	setLimit: function(limit)
	{
		this.limit = false;
		if (limit != parseInt(limit))
		{
			throw "Limit must be numeric";
		}
		this.limit = limit;
	},
	getLimit: function()
	{
		return this.limit;
	},
	setPage: function(page)
	{
		this.page = false;
		if (page != parseInt(page))
		{
			throw "Page must be numeric";
		}
		this.page = page;
	},
	getPage: function()
	{
		return this.page;
	},
	setTotalPages: function(pages)
	{
		this.totalPages = false;
		if (pages != parseInt(pages))
		{
			throw "Total pages must be numeric";
		}
		this.totalPages = pages;
	},
	getTotalPages: function()
	{
		return this.totalPages;
	},
	setDelta: function(delta)
	{
		this.delta = false;
		if (delta != parseInt(delta))
		{
			throw "Delta must be numeric";
		}
		this.delta = delta;
	},
	getDelta: function()
	{
		return this.delta;
	},
	setFormat: function(format)
	{
		this.format = 'json';
		if (format.toLowerCase() != 'json' && format.toLowerCase() != 'xml')
		{
			throw "XML and JSON are the only support formats at this time";
		}
		this.format = format;
	},
	getFormat: function()
	{
		return this.format;
	},
	setParseFunction: function(func)
	{
		this.parse = false;
		if (!func)
		{
			throw "You must create a function to parse the results of the AJAX call and pass it here";
		}
		this.parse = func;
	},
	getParseFunction: function()
	{
		return this.parse;
	},
	setObject: function(obj)
	{
		this.obj = this;
		if (typeof(obj) != 'object' || !obj)
		{
			throw "The object you just created needs to be passed here";
		}
		this.obj = obj;
	},
	getObject: function()
	{
		return this.obj;
	},
	setUrlParams: function(params)
	{
		this.params = false;
		if (!params)
		{
			throw "Please pass in additional URL parameters in query string format";
		}
		this.params = params;
	},
	getUrlParams: function()
	{
		return this.params;
	},
	setPageID: function(page_id)
	{
		this.page_id = false;
		if (page_id != parseInt(page_id))
		{
			throw "Page ID must be numeric";
		}
		this.page_id = page_id;
	},
	getPageID: function()
	{
		return this.page_id;
	},
	setModule: function(module)
	{
		this.module = false;
		if (!module)
		{
			throw "Please specify a site page module";
		}
		this.module = module;
	},
	getModule: function(module)
	{
		return this.module;
	},
	create: function()
	{
		if (!this.total && this.total != 0)
		{
			this.setTotal(0);
		}
		if (!this.limit)
		{
			this.setLimit(0);
		}
		if ($(this.div2))
		{
			$(this.div2).innerHTML = '';
		}
		$(this.div).innerHTML = '';
		if (!this.page)
		{
			this.setPage(1);
		}
		if (!this.delta)
		{
			this.setDelta(2);
		}
		var totalElem = new Element('input', {'id': this.div+'_total', 'type': 'hidden', 'value': this.total});
		var limitElem = new Element('input', {'id': this.div+'_limit', 'type': 'hidden', 'value': this.limit});

		pageTotal = (this.total / this.limit).ceil();
		showPages = (this.delta * 2) + 1;
		this.setTotalPages(pageTotal);

		if (pageTotal <= 1)
		{
			return false;
		}

		if (this.page == 1)
		{
			var prevLink = new Element('span', {'style': 'padding-right: 15px;', 'id': this.div+'_prev'}).update('&lt Prev');

			if ($(this.div2))
			{
				var prevLink2 = new Element('span', {'style': 'padding-right: 15px;', 'id': this.div2+'_prev'}).update('&lt; Prev');
			}
		}
		else
		{
			prevNum = this.page - 1;
			var prevLink = new Element('a', {'href': 'javascript:;', 'style': 'padding-right: 15px;', 'id': this.div+'_prev'}).update('&lt Prev');
			$(prevLink).observe('click', this.prepAJAX.bindAsEventListener(this, prevNum, this.obj));

			if ($(this.div2))
			{
				var prevLink2 = new Element('a', {'href': 'javascript:;', 'style': 'padding-right: 15px;', 'id': this.div2+'_prev'}).update('&lt Prev');
				$(prevLink2).observe('click', this.prepAJAX.bindAsEventListener(this, prevNum, this.obj));
			}
		}
		$(this.div).insert(prevLink);

		if ($(this.div2))
		{
			$(this.div2).insert(prevLink2);
		}

		if (pageTotal >= (showPages + 2))
		{
			if (this.page < (1 + this.delta))
			{
				start = 1;
				end = showPages;
			}
			else
			{
				if (this.page < (pageTotal - this.delta))
				{
					start = this.page - this.delta;
					end = this.page + this.delta;
				}
				else
				{
					start = pageTotal - showPages + 1;
					end = pageTotal;
				}
			}

			if (start > this.delta)
			{
				diff = start + 1;
				step = (diff > showPages) ? start - showPages : start - (diff / 2).ceil();
			}

			if (end <= (pageTotal - this.delta))
			{
				diff = pageTotal - end;
				step = (diff > showPages) ? end + showPages : end + (diff / 2).ceil();
			}
		}
		else
		{
			start = 1;
			end = pageTotal;
		}

		if (start >= this.delta)
		{
			diff = start - 1;
			step = (diff > showPages) ? (start + this.delta) - showPages : start - (diff / 2).ceil();
			var leftEllipsis = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div+'_left_ellipsis'}).update('&hellip;');
			$(leftEllipsis).observe('click', this.prepAJAX.bindAsEventListener(this, step, this.obj));
			$(this.div).insert(leftEllipsis);

			if ($(this.div2))
			{
				var leftEllipsis2 = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div2+'_left_ellipsis'}).update('&hellip;');
				$(leftEllipsis2).observe('click', this.prepAJAX.bindAsEventListener(this, step, this.obj));
				$(this.div2).insert(leftEllipsis2);
			}
		}

		counter = start;
		while (counter <= end)
		{
			if (counter == this.page)
			{
				var numLink = new Element('span', {'style': 'padding: 0 2px;', 'id': this.div+'_page_'+counter}).update(counter);
				$(this.div).insert(numLink);

				if ($(this.div2))
				{
					var numLink2 = new Element('span', {'style': 'padding: 0 2px;', 'id': this.div2+'_page_'+counter}).update(counter);
					$(this.div2).insert(numLink2);
				}
			}
			else
			{
				var numLink = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div+'_page_'+counter}).update(counter);
				$(this.div).insert(numLink);
				$(numLink).observe('click', this.prepAJAX.bindAsEventListener(this, counter, this.obj));

				if ($(this.div2))
				{
					var numLink2 = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div2+'_page_'+counter}).update(counter);
					$(this.div2).insert(numLink2);
					$(numLink2).observe('click', this.prepAJAX.bindAsEventListener(this, counter, this.obj));
				}
			}
			counter++;
		}

		if (end <= (pageTotal - this.delta) + 1)
		{
			diff = pageTotal - end;
			step = (diff > showPages) ? (end - this.delta) + showPages : end + (diff / 2).ceil();
			var rightEllipsis = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div+'_right_ellipsis'}).update('&hellip;');
			$(rightEllipsis).observe('click', this.prepAJAX.bindAsEventListener(this, step, this.obj));
			$(this.div).insert(rightEllipsis);

			if ($(this.div2))
			{
				var rightEllipsis2 = new Element('a', {'href': 'javascript:;', 'style': 'padding: 0 2px;', 'id': this.div2+'_right_ellipsis'}).update('&hellip;');
				$(rightEllipsis2).observe('click', this.prepAJAX.bindAsEventListener(this, step, this.obj));
				$(this.div2).insert(rightEllipsis2);
			}
		}

		if (this.page < pageTotal)
		{
			var nextNum = this.page + 1;
			var nextLink = new Element('a', {'href': 'javascript:;', 'style': 'padding-left: 15px;', 'id': this.div+'_next'}).update('Next &gt;');
			$(nextLink).observe('click', this.prepAJAX.bindAsEventListener(this, nextNum, this.obj));

			if ($(this.div2))
			{
				var nextLink2 = new Element('a', {'href': 'javascript:;', 'style': 'padding-left: 15px;', 'id': this.div2+'_next'}).update('Next &gt;');
				$(nextLink2).observe('click', this.prepAJAX.bindAsEventListener(this, nextNum, this.obj));
			}
		}
		else
		{
			nextLink = new Element('span', {'style': 'padding-left: 15px;', 'id': this.div+'_next'}).update('Next &gt;');

			if ($(this.div2))
			{
				nextLink2 = new Element('span', {'style': 'padding-left: 15px;', 'id': this.div2+'_next'}).update('Next &gt;');
			}
		}

		if ($(this.div2))
		{
			$(this.div2).insert(nextLink2);
			$(this.div2).removeClassName('moduleLoadingMedium');
		}

		$(this.div).removeClassName('moduleLoadingMedium');
		$(this.div).insert(nextLink);
		$(this.div).insert(totalElem);
		$(this.div).insert(limitElem);
	},
	prepAJAX: function(event, page, obj)
	{
		$(this.div).innerHTML = '&nbsp;';
		$(this.div).addClassName('moduleLoadingMedium');

		if ($(this.div2))
		{
			$(this.div2).innerHTML = '&nbsp;';
			$(this.div2).addClassName('moduleLoadingMedium');
		}

		obj.setPage(page);
		obj.doAJAX(obj);
	},
	doAJAX: function(obj)
	{
		$(this.div).innerHTML = '&nbsp;';

		if ($(this.div2))
		{
			$(this.div2).innerHTML = '&nbsp;';
		}

		if (!obj)
		{
			obj = this;
		}
		var offset = (obj.page * obj.limit) - obj.limit;
		if (obj.limit == 1)
		{
			offset = obj.page - 1;
		}
		if (!obj.page_id)
		{
			obj.setPageID(9999);
		}
		if (!obj.module)
		{
			obj.setModule();
		}
		url = '/index.php?page_id='+obj.page_id+'&module='+obj.module+'&limit='+obj.limit+'&offset='+offset+'&format='+obj.format;
		if (obj.params)
		{
			url += '&'+this.params;
		}

		new Ajax.Request(url, {
			method: 'get',
			onSuccess: function(success)
			{
				if (obj.format == 'json')
				{
					var retval = success.responseText.evalJSON();
				}
				else
				{
					var retval = success.responseText;
				}

				obj.results = retval;

				if (obj.parse)
				{
					parseFunc = obj.parse+'()';
					eval(parseFunc);
				}
				else
				{
					obj.parseResults();
				}

				obj.setTotal(retval.total);
				obj.setLimit(retval.limit);
				obj.setPage(obj.page);
				obj.create();
			},
			onFailure: function()
			{
				alert('An error occurred, please try again');
			}
		});
	}
});

var Pagination = Class.create(PaginateDiv, {
	initialize: function($super, div)
	{
		$super(div);
	}
});
