$PWT.Class.create
(
	{
		$namespace:	'$DMSBT.search',
		$name:		'ResultSet',
		$traits:
		[
			$PWT.trait.Configurable,
			$PWT.trait.Observable
		]
	}
)
(
	{
		config:
		{
			resultsContainer:		null,
			paginationContainer:	null,
			URI:					'',
			page:					1,
			pageRange:				[1,5],
			perPage:				5,
			total:					0,
			results:				[],
			timeout:				5,
			template_row:			null,
			template_noResults:		null,
			template_loading:		null,
			template_page:			null,
			template_currentPage:	null,
			ellipsisButtonAction:	'default',
			backButtonAction:		'default'
		},
		events:
		{
			onModifyPageResults:	true,
			onLoading:				true
		},
		template:
		{
			row:
			[
				'<tr class="{CLASS}">',
					'<td class="col_0"></td>',
				'</tr>'
			].join(''),
			noResults:
			[
				'<tr class="even">',
					'<td colspan="7" style="text-align:center;">No results to display.</td>',
				'</tr>'
			].join(''),
			loading:
			[
				'<tr class="even">',
					'<td colspan="7" style="text-align:center;"><img src="images/ajax-loader.gif" /> Fetching more results. Please wait...</td>',
				'</tr>'
			].join(''),
			page:			'<li class="{CLASS}"><a href="javascript:{};">{PAGENUM}</a></li>',
			currentPage:	'<li class="current">{PAGENUM}</li>'
		},
		URI:				'',
		page:				1,
		pageRange:			[1,5],
		pageRangeNum:		5,
		perPage:			5,
		total:				0,
		numPages:			0,
		results:			[],
		resultsContainer:	null,
		paginationContainer:null,
		headerRow:			null,
		checkAllBox:		null,
		checkBoxes:			[],
		checkState:			[],
		pageButtons:		[],
		init:	function(resultSet)
		{
			this.URI		=this.config.URI.replace(/&amp;/g,'&');
			this.page		=parseInt(this.config.page);
			this.perPage	=this.config.perPage;
			this.total		=this.config.total;
			this.validateRange(this.config.pageRange);
			if (Object.isString(this.config.template_row))
			{
				this.template.row=this.config.template_row;
			}
			if (Object.isString(this.config.template_noResults))
			{
				this.template.noResults=this.config.template_noResults;
			}
			if (Object.isString(this.config.template_loading))
			{
				this.template.loading=this.config.template_loading;
			}
			if (Object.isString(this.config.template_page))
			{
				this.template.page=this.config.template_page;
			}
			if (Object.isString(this.config.template_currentPage))
			{
				this.template.currentPage=this.config.template_currentPage;
			}
			if (Object.isString(this.config.resultsContainer))
			{
				this.resultsContainer=$('#'+this.config.resultsContainer);
			}
			else
			{
				this.resultsContainer=this.config.resultsContainer;
			}
			if (this.total)
			{
				if (Object.isString(this.config.paginationContainer))
				{
					this.paginationContainer=$('#'+this.config.paginationContainer);
				}
				else
				{
					this.paginationContainer=this.config.paginationContainer;
				}
				//Get key elements in the resultsContainer.
				this.headerRow	=$('tr.header',this.resultsContainer);
//				this.checkAllBox=$(Sizzle('input.checkAll',this.headerRow).first());
//				
//				//Bind events.
//				this.checkAllBox.onclick=this.checkAll.bind(this)
				
				if (this.config.results.length>this.perPage)
				{
					var page=this.page,
						set	=[];
					for (var i=0,j=0,k=1,l=this.config.results.length; j<l; i++,j++,k++)
					{
						set.push(this.config.results[j]);
						if (i==9)
						{
							this.addResultsToPage(page,set);
							delete set;
							i	=0;
							set	=[];
							page++;
						}
						else if (k==l)
						{
							this.addResultsToPage(page,set);
							delete set;
						}
					}
				}
				else
				{
					this.addResultsToPage(this.page,this.config.results);
				}
				//Show the page originally defined from config.
				this.showPage(this.page);
			}
		},
		validateRange: function()
		{
			if (this.config.pageRange[0]>this.config.pageRange[1])
			{
				throw new Error('Invalid page range. Page range must be a 2 length array with the first number being less than the second number.');
			}
			if (this.config.pageRange[0]<=0)
			{
				throw new Error('Invalid page range. The first page range number must be greater than 0 and less than the second number.');
			}
			this.pageRange		=this.config.pageRange;
			this.pageRangeNum	=(this.pageRange[1]+1)-this.pageRange[0];
		},
		applyTemplate: function(template,data)
		{
			for (var key in data)
			{
				template=template.replace(new RegExp('\{'+key+'\}','g'),data[key]);
			}
			return template;
		},
		addResultsToPage: function(pageNum,results)
		{
			this.results[pageNum]=results;
		},
		generatePagination: function()
		{
			if (this.results.length)
			{
				this.numPages	=Math.ceil(this.total/this.perPage);
				var HTML		=['<ul>'];
				if (this.pageRange[0]!=1)
				{
					HTML.push(this.applyTemplate(this.template.page,{CLASS:'button-back',PAGENUM:'&#171;'}));
				}
				for (var i=this.pageRange[0]; i<=this.pageRange[1] && i<=this.numPages; i++)
				{
					if (i!=this.page)
					{
						HTML.push(this.applyTemplate(this.template.page,{CLASS:'',PAGENUM:i}));
					}
					else
					{
						HTML.push(this.applyTemplate(this.template.currentPage,{PAGENUM:i}));
					}
				}
				if (this.numPages>5)
				{
					//HTML.push(this.applyTemplate(this.template.page,{CLASS:'button-more',PAGENUM:'&#8230;'}));
				}
				HTML.push('</ul>');
				this.paginationContainer.html(HTML.join(''));
			}
			else
			{
				this.paginationContainer.html(['<ul>',this.applyTemplate(this.template.currentPage,{CLASS:'current',PAGENUM:1}),'<ul>'].join(''));
			}
			this.pageButtons=$('li',this.paginationContainer);
			this.bindPageButtonClickHandlers();
			return this;
		},
		clearRows: function()
		{
			var parentNode=this.headerRow.parent();
			$('>table tr[class!=header]',this.resultsContainer).remove();//.each
//			(
//				function(element)
//				{
//					parentNode.empty(element);
//				}.bind(this)
//			);
		},
		showPage: function(pageNum)
		{
			//First remove all the rows in the table with the exception of the header row.
			this.clearRows();
			//Uncheck the checkall checkbox.
//			this.checkAllBox.checked=false;
			//Now get a set of results based on the requested page.
			//var	resultSet	=this.results.slice(((pageNum-1)*this.perPage),this.perPage),
			var	resultSet	=this.results[pageNum] || [],
				HTML		=[];
			if (resultSet.length)
			{
				//Apply them to the page.
				this.fireEvent('onModifyPageResults',this,resultSet,HTML);
				if (!HTML.length)
				{
					for (var i=0,j=resultSet.length,k=true; i<j; i++,k=!k)
					{
						HTML.push(this.applyTemplate(this.template.row,resultSet[i]));
					}
				}
				$(HTML.join('')).insertAfter(this.headerRow);
//				delete this.checkBoxes;
//				this.checkBoxes=Sizzle('td.col_0 input[class!=checkAll]',this.resultsContainer);
				this.page=parseInt(pageNum);
//				this.bindCheckboxCheckHandlers();
//				this.checkAllBox.checked=this.allCheckedOnPage();
			}
			else
			{
//				this.URI=this.URI.replace('page='+this.page,'page='+pageNum);
				this.loadPage
				(
					pageNum,
					function(JSON)
					{
						this.perPage=JSON.perPage;
						if (JSON.results.length)
						{
							this.showPage(JSON.page);
						}
						else
						{
							this.clearRows();
							this.headerRow.insertAfter(this.template.noResults);
						}
						if (JSON.total!=this.total)
						{
							this.total		=JSON.total;
							var totalPages	=(this.total/this.perPage);
							if (this.page>totalPages)
							{
								this.showPage(totalPages);
							}
							else
							{
								this.generatePagination();
							}
						}
					}.bind(this)
				);
				this.headerRow.append(this.template.loading);
				this.page=parseInt(pageNum);
			}
			this.generatePagination();
			return this;
		},
		loadPage: function(pageNum,callback)
		{
			var reg=new RegExp(/page=([0-9]{0,3})/);
			if (reg.test(this.URI))
			{
				this.URI=this.URI.replace(reg,'page='+pageNum);
			}
			else
			{
				this.URI+=((/\?/.test(this.URI))?'&':'?')+'page='+pageNum;
			}
			$.getJSON
			(
				this.URI+'&json=1',
				function(response)
				{
					if (response.results.length)
					{
						this.addResultsToPage(response.page,response.results);
					}
					else
					{
						this.addResultsToPage(response.page,[]);
					}
					if (Object.isFunction(callback))callback(response);
				}.bind(this)
			);
		},
		bindPageButtonClickHandlers: function()
		{
			var pages=this.pageButtons.filter('li[class!=current]');
			for (var i=0,j=pages.length; i<j; i++)
			{
				var value=$(pages[i].down()).html();
				if (Object.isNumeric(value))
				{
					pages[i].down().onclick=this.showPage.bind(this,parseInt(value));
				}
				else if ($(pages[i]).hasClass('button-more'))
				{
					pages[i].down().onclick=function()
					{
						if (this.config.ellipsisButtonAction=='default')
						{
							this.showNextPageSet();
						}
						else if (Object.isFunction(this.config.ellipsisButtonAction))
						{
							this.config.ellipsisButtonAction(this);
						}
					}.bind(this)
				}
				else if ($(pages[i]).hasClass('button-back'))
				{
					pages[i].down().onclick=function()
					{
						if (this.config.backButtonAction=='default')
						{
							this.showPreviousPageSet();
						}
						else if (Object.isFunction(this.config.backButtonAction))
						{
							this.config.backButtonAction(this);
						}
					}.bind(this)
				}
			}
			return this;
		},
		showNextPageSet: function()
		{
			this.pageRange[0]+=this.pageRangeNum;
			this.pageRange[1]+=this.pageRangeNum;
			this.showPage(this.pageRange[0]);
		},
		showPreviousPageSet: function()
		{
			this.pageRange[0]-=this.pageRangeNum;
			this.pageRange[1]-=this.pageRangeNum;
			this.showPage(this.pageRange[1]);
		},
//		checkAll: function()
//		{
//			var checked=(this.checkAllBox.checked);
//			for (var i=0,j=this.checkBoxes.length; i<j; i++)
//			{
//				this.checkBoxes[i].checked=checked;
//				this.setCheckboxState(this.checkBoxes[i]);
//			}
//		},
//		bindCheckboxCheckHandlers: function()
//		{
//			for (var i=0,j=this.checkBoxes.length; i<j; i++)
//			{
//				this.restoreCheckboxState(this.checkBoxes[i]);
//				this.checkBoxes[i].onchange=function(checkbox)
//				{
//					this.setCheckboxState(checkbox);
//					this.checkAllBox.checked=this.allCheckedOnPage(this.page);
//				}.bind(this,this.checkBoxes[i]);
//			}
//			return this;
//		},
//		setCheckboxState: function(checkbox)
//		{
//			this.checkState[this.page][checkbox.value]=checkbox.checked;
//		},
//		restoreCheckboxState: function(checkbox)
//		{
//			if (Object.isUndefined(this.checkState[this.page]))
//			{
//				this.checkState[this.page]					={};
//				this.checkState[this.page][checkbox.value]	=false;
//			}
//			if (Object.isUndefined(this.checkState[this.page][checkbox.value]))
//			{
//				this.checkState[this.page][checkbox.value]	=false;
//			}
//			checkbox.checked=this.checkState[this.page][checkbox.value];
//			return this;
//		},
//		allCheckedOnPage: function()
//		{
//			var	total		=this.checkBoxes.length,
//				numChecked	=0;
//			for (var i=0; i<total; i++)
//			{
//				if (this.checkBoxes[i].checked)numChecked++;
//			}
//			return (numChecked==total);
//		},
//		getAllCheckedValues: function()
//		{
//			var values=[];
//			for (var i=0,j=this.checkState.length; i<j; i++)
//			{
//				for (var value in this.checkState[i])
//				{
//					if (this.checkState[i][value])values.push(value);
//				}
//			}
//			return values;
//		},
		setTotal: function(total)
		{
			this.total=total;
			this.generatePagination();
		},
		getPage: function()
		{
			return this.page;
		},
		getNextPage: function()
		{
			var nextPage=this.page+1;
			if (nextPage<=this.numPages)
			{
				return nextPage;
			}
			else
			{
				return false;
			}
		},
		getNextUnloadedPage: function()
		{
			for (var i=1,j=this.numPages; i<=j; i++)
			{
				if (Object.isUndefined(this.results[i]))
				{
					return i;
				}
			}
			return false;
		}
	}
);
