dojo.require("dojo.cookie");

var productFilter = function(reviewTableId) {

	var _reviewBodyId = reviewTableId;
	var _reviewBody;
	var _loaderGif = dojo.byId('loader');

	/*var _blueArrowImg = document.createElement('img');

	_blueArrowImg.setAttribute('src', '/images/blueArrow.gif');
	_blueArrowImg.setAttribute('alt', 'Read more');*/

	var _compareButton = dojo.byId('compareButton');
	_compareButton.style.display = 'none';

	var _selectedReviews = new Array();

	var _checkCss = function(_action, _object, _firstClass, _secondClass) {
		switch (_action) {
		case 'swap':
			_object.className = !_checkCss('check', _object, _firstClass) ? _object.className
					.replace(_secondClass, _firstClass)
					: _object.className.replace(_firstClass, _secondClass);
			break;
		case 'add':
			if (!_checkCss('check', _object, _firstClass)) {
				_object.className += _object.className ? ' ' + _firstClass
						: _firstClass;
			}
			break;
		case 'remove':
			var rep = _object.className.match(' ' + _firstClass) ? ' ' + _firstClass
					: _firstClass;
			_object.className = _object.className.replace(rep, '');
			break;
		case 'check':
			return new RegExp('\\b' + _firstClass + '\\b').test(_object.className);
			break;
		}

	};
	
	var _indexOf = function(array, obj) {
		for (var i = 0; i < array.length; i++) {
			if (array[i] == obj){
				return i;
			}
		}
		return -1;
	};
	
	var _buildShortList = function(review)
	{
		var shortListLink = document.createElement('a');
		
		var removeString = 'Remove ' + review.getName() + ' from your short list';
		shortListLink.value = review.getId();
		shortListLink.setAttribute('title', removeString);
		shortListLink.setAttribute('href', ' javascript:void(0)');
		shortListLink.checked = true;
		shortListLink.id = 'shortListLink' + review.getId();
		_checkCss('add', shortListLink, 'floatLeft');
		_checkCss('add', shortListLink, 'noUnderline');
		
		// add the div
		
		var shortListDiv = document.createElement('div');
		_checkCss('add', shortListDiv, 'product');
		_checkCss('add', shortListDiv, 'brown');
		_checkCss('add', shortListDiv, 'borderR');
		_checkCss('add', shortListDiv, 'borderB');
		
		// add the image
		
		var shortListImg = document.createElement('img');
		shortListImg.setAttribute('alt', removeString);
		_checkCss('add', shortListImg, 'smallImage');
		_checkCss('add', shortListImg, 'articleImage');		
		shortListImg.setAttribute('src', review.getImage());
		shortListImg.id = 'shortListImg' + review.getId();
		shortListDiv.appendChild(shortListImg);
		
		shortListHeading = document.createElement('h3');
		shortListHeading.id = 'shortListHeader' + review.getId();
		var reviewManufacturer  = review.getManufacturer().getName();
		var reviewName			= review.getName();
		shortListHeading.appendChild(document.createTextNode(reviewManufacturer + ' ' + reviewName));
		
		shortListDiv.appendChild(shortListHeading);
		
		var shortListPara = document.createElement('p');
		shortListPara.id = 'shortListPara' + review.getId();
		// create and append the cute but functionally useless little image.
		var removeSquare = document.createElement('img');
		removeSquare.setAttribute('src', '/images/removeSquare.gif');
		removeSquare.setAttribute('alt', removeString);
		
		shortListPara.appendChild(removeSquare);
		shortListPara.appendChild(document.createTextNode(' Remove'));
		
		shortListDiv.appendChild(shortListPara);
		
		shortListLink.appendChild(shortListDiv);
		
		dojo.connect(shortListLink, 'onclick', theProductFilter, 'toggleSelection');
		return shortListLink;
	};

	/**
	 * Acts as a setup and tear down for the selected products
	 */
	var _compare = function(theProductFilter) {
		var i, activeReview, hiddenField, reviewData, trReview;

		var popDiv = dojo.byId('selectedProducts');

		if (popDiv) {
			while (popDiv.hasChildNodes()) {
				popDiv.removeChild(popDiv.firstChild);
			}
		}

		for (i = 0; i < _selectedReviews.length; i++) {
			activeReview = _selectedReviews[i];

			hiddenField = document.createElement('input');
			hiddenField.setAttribute('type', 'hidden');
			hiddenField.setAttribute('name', 'reviews[]');
			hiddenField.value = activeReview.getId();

			popDiv.appendChild(hiddenField);
			reviewData = _buildShortList(activeReview);

			popDiv.appendChild(reviewData);
			// alert(hiddenField.value);
			// get the row if it exists and highlight it as chosen
			if (trReview = dojo.byId('tr' + activeReview.getId())) {
				_checkCss('add', trReview, 'chosen');
			}
		}

		if (i >= 2) {
			_compareButton.style.display = 'block';
		} else {
			_compareButton.style.display = 'none';
		}
	};

	var _findReviewById = function(reviewId) {
		var i;
		for (i = 0; i < _selectedReviews.length; i++) {
			if (_selectedReviews[i].getId() == reviewId) {
				return i;
			}
		}
		return false;
	};
	
	var _clearNode = function (node)
	{
		if (node) {
			while (node.hasChildNodes()) {
				node.removeChild(node.firstChild);
			}
		}
	};
	


	return {

		loaderStart : function() {
			_loaderGif.style.background = '#EFEFEF url(/images/ajaxLoader.gif) no-repeat bottom right';
		},

		loaderFinish : function() {
			_loaderGif.style.background = '#E8F4FF';
		},

		getSelectedReviews : function() {
			return _selectedReviews;
		},

		selectReview : function(selectedReview) {

			if (_findReviewById(selectedReview.getId()) === false) {
				_selectedReviews.push(selectedReview);
				this._addReviewToCookies(selectedReview);
			}

			_compare(this);

		},
		
		_addReviewToCookies: function(selectedReview) {
			if (dojo.cookie.isSupported()) {
				// rather than this `object[path] = array` stuff it would be nice
				// if IE worked with cookie paths like Firefox and Safari so 
				// we could just have a separate array for each category based on the path
				var shortlistedReviews = dojo.fromJson(dojo.cookie("reviewShortlist"));
				var path = document.location.pathname;
				if (shortlistedReviews == undefined) {
					var shortlistedReviews = new Object();
				}
				if (shortlistedReviews[path] == undefined) {
					shortlistedReviews[path] = new Array();
				}
				if (_indexOf(shortlistedReviews[path], selectedReview.getId()) == -1) {
					shortlistedReviews[path].push(selectedReview.getId());
				}
				dojo.cookie("reviewShortlist", dojo.toJson(shortlistedReviews));
			}
		},

		deselectReview : function(reviewId) {
			// workaround for IE bug is to use a new array and replace the
			// existing one
			
			//alert('deslecting ' + reviewId);
			var i, trReview, newArray = new Array();

			if (trReview = dojo.byId('tr' + reviewId)) {
				_checkCss('remove', trReview, 'chosen');
			}

			for (i = 0; i < _selectedReviews.length; i++) {
				if (_selectedReviews[i].getId() != reviewId) {
					newArray.push(_selectedReviews[i]);
				}
			}
			_selectedReviews = newArray;
			
			this._removeReviewFromCookies(reviewId);

			_compare(this);
		},
		
		_removeReviewFromCookies: function(reviewId) {
			if (dojo.cookie.isSupported()) {
				var shortlistedReviews = dojo.fromJson(dojo.cookie("reviewShortlist"));
				var path = document.location.pathname;
				if (shortlistedReviews == undefined) {
					var shortlistedReviews = new Object();
				} 
				if (shortlistedReviews[path] == undefined) {
					shortlistedReviews[path] = new Array();
				} else {
					shortlistedReviews[path].splice(_indexOf(shortlistedReviews[path], reviewId), 1);
				}
				dojo.cookie("reviewShortlist", dojo.toJson(shortlistedReviews));
			}
		},
		
		initSelectedReviewsFromCookies : function() {
			if (dojo.cookie.isSupported()) {
				var shortlistedReviews = dojo.fromJson(dojo.cookie("reviewShortlist"));
				var path = document.location.pathname;
				// Put the reviews from the cookies into the shortlist section
				if (shortlistedReviews !== undefined && shortlistedReviews[path] !== undefined) {		
					shortlistedCategoryReviews = shortlistedReviews[path];
					for (i = 0; i < shortlistedCategoryReviews.length; i++) {
						var review = filterSet.getReviewById(shortlistedCategoryReviews[i]);
						if (review !== undefined && _findReviewById(review.getId()) === false) {
							review.setSelected(true); // remember to also set it as selected
							_selectedReviews.push(review);
						} else {
							// review was not found, ideally we would load the review 
							// and put it on the shortlist anyway but not currently possible @todo!
							// for the time being we'll just clean up reviews we can't load
							this._removeReviewFromCookies(shortlistedCategoryReviews[i]);
						}
						
						// Also select the checkbox for the review
						var inputCell = dojo.byId('cellSelect' + shortlistedCategoryReviews[i]);
						if (inputCell) {
							var inputElement = inputCell.firstChild;
							inputElement.checked = 'checked';
						}
					}
					
					_compare(this);
				}
			}
		},


		buildTable : function(theFilterSet) {
			var i, reviews = theFilterSet.getReviews();

			for (i = 0; i < reviews.length; i++) {
				this.buildTableRow(reviews[i], i);
			}
			this.buildFooter(theFilterSet);
		},

		buildFooter : function(theFilterSet) {
			
			var count = theFilterSet.getTotal();
			
			var offset = theFilterSet.getOffset();
			
			var limit = theFilterSet.getLimit();
			var _tableFooter = dojo.byId('productsPagination');
			
			_clearNode(_tableFooter);
			
			if (count > limit) {

				// we should paginate here 
				var pageId, paginationStart, paginationFinish, pagesDiv, previousDiv, previousText, previousLink, nextLink, currentPage, page;
				currentPage = 1 + Math.ceil(offset/limit);
				paginationStart = currentPage - 4;
				paginationFinish = currentPage + 4;
				previousDiv = document.createElement('div');
				_checkCss('add', previousDiv, 'prev');
				previousDiv.id ='previousPage';
				_tableFooter.appendChild(previousDiv);
				
				pagesDiv = document.createElement('div');
				_checkCss('add', pagesDiv, 'pages');
				_tableFooter.appendChild(pagesDiv);

				previousText = document.createTextNode('Prev');
				if (currentPage > 1) {
					previousLink = this.buildPaginationLink('previousPageLink', currentPage-1, '', 'Previous');
				} else {
					previousLink = document.createElement('span');
				}
				

				previousLink.appendChild(previousText);
				previousDiv.appendChild(previousLink);				
				
				for (pageId=1; pageId<=Math.ceil(count/limit); pageId++) {
					var page = null;
					
					if ( (pageId >= paginationStart) && (pageId <= paginationFinish) ) {
						if (pageId!= currentPage) {
							var pageOffsetStart = 1 + ((pageId-1) * limit);
							var pageOffsetFinish = pageOffsetStart + limit;
							if (pageOffsetFinish > count) {
								pageOffsetFinish = count;
							}
							
							var linkTitle 	= 'Show results ' + pageOffsetStart + ' to ' + pageOffsetFinish;
							var linkText 	= (paginationStart == pageId) || (paginationFinish == pageId) ? '...' : pageId;
							page 			= this.buildPaginationLink('page' + pageId, pageId, linkText, linkTitle);
							_checkCss('add', page, 'selected');
						} else {
							page = document.createElement('strong');
							page.appendChild(document.createTextNode(pageId));
						}
						pagesDiv.appendChild(page);
					}					
				}
				// now lets append the "next" button if necessary
				var nextDiv = document.createElement('div');
				_checkCss('add', nextDiv, 'next');
				
				if ( (pageId) > currentPage ) {
					linkText = 'Next ' + limit + '  results';
					nextLink = this.buildPaginationLink('nextPage', currentPage + 1, '', linkText);
					
				} else {
					nextLink  = document.createElement('span');
				}
				nextLink.appendChild(document.createTextNode('Next'));
				nextDiv.appendChild(nextLink);
				_tableFooter.appendChild(nextDiv);
			}
		},
		
		buildPaginationLink : function(id, page, body, title)
		{
			var link = document.createElement('a');
			link.id = id;
			link.setAttribute('href', 'javascript: void(0)');
			link.setAttribute('title', title);

			link.page = page;
			link.appendChild(document.createTextNode(body));
			dojo.connect(link, 'onclick', this, 'shiftResults');
			
			return link;
		},
		
		
		renderFilterList	: function(filterDivId, theFilterSet)
		{
			var filterDiv, bandDiv, bandUl, bandLi, filtersDiv = dojo.byId(filterDivId);
			
			if (filtersDiv) {
				_clearNode(filtersDiv);
				
				var filters = theFilterSet.getFilters(); 

				for (i=0; i < filters.length; i++) {
					if (i % 5 == 0) {
						filterDiv = document.createElement('div');
						_checkCss('add', filterDiv, 'floatLeft');
						filtersDiv.appendChild(filterDiv);
					}
					var bands 		= filters[i].getBands();

					for (j = 0; j<bands.length; j++) {
						if (j % 6 == 0) {
							var bandDiv = document.createElement('div');
							if (filters[i].getLabel() == 'Rating') {
								_checkCss('add', bandDiv, 'smallReviewsFiveColumn rating');
							}else{
								_checkCss('add', bandDiv, 'smallReviewsFiveColumn');
							}
							var filterHeading = document.createElement('h2');
							filterInner = (j == 0) ? filters[i].getLabel() : '\u00a0';
							filterInnerNode = document.createTextNode(filterInner);
							filterHeading.appendChild(filterInnerNode);
							bandDiv.appendChild(filterHeading);
							var bandUl = document.createElement('ul');
							bandDiv.appendChild(bandUl);
							filterDiv.appendChild(bandDiv);
						}
						var band = bands[j];
						
						var bandLi = document.createElement('li');
						
						var bandLink = document.createElement('a');
						bandLink.setAttribute('href', 'javascript: void(0)');
						if (filters[i].getLabel() == 'Rating') {
							var bandInner = document.createElement('img');
							bandInner.setAttribute('alt', band.getLabel());
							bandInner.setAttribute('src', 'images/rating6/' + band.getLabel() + '.gif');
						} else {
							var bandInner = document.createTextNode(band.getLabel());
						}
						bandLink.appendChild(bandInner);
						var bandSpan = document.createElement('span');
						_checkCss('add', bandSpan, 'quiet');
						_checkCss('add', bandSpan, 'small');
						
						bandSpan.id = 'band' + band.getId() + 'Count';
						var bandCount = band.getCount();
						if (!bandCount) {
							bandCount = 0;
						}
						bandSpan.appendChild(document.createTextNode('(' + bandCount + ')'));
						bandLink.appendChild(bandSpan);
						
						bandLink.band = band;
						
						dojo.connect(bandLink, 'onclick', this, 'bandClick');
						bandLi.appendChild(bandLink);
						this.setBand(bandLi, band);
						//onclick="highLinks(this); javascript: Band.fetch({$band->getId()}).update(); return false;">{if $filter->getLabel() == 'Rating'}<img src="images/rating6/{$band->getLabel()}.gif" alt="{$band->getLabel()}" />{else}{$band->getLabel()}{/if} <span id="band{$band->getId()}Count" class="quiet small">{if (!is_null($band->getCount()) )}({$band->getCount()}){/if}</span></a>
						bandUl.appendChild(bandLi);
					}
				}
				
			}
			
			var sortRatingHeader 	= dojo.byId('sortByRating');
			var sortRatingLink 		= document.createElement('a');
			
			_checkCss('add', sortRatingLink, 'sort');
			sortRatingLink.appendChild(document.createTextNode('Sort by Rating'));
			sortRatingLink.searchValue  = 'rating';
			sortRatingLink.sortOrder	= 'DESC';
			
			sortRatingLink.href = 'javascript: void(0);';
			_clearNode(sortRatingHeader);
			
			sortRatingHeader.appendChild(sortRatingLink);
			dojo.connect(sortRatingLink, 'onclick', this, 'setSearch');
			
			var sortPriceHeader 	= dojo.byId('sortByPrice');
			
			var sortPriceLink		= document.createElement('a');
			_checkCss('add', sortPriceLink, 'sort');
			sortPriceLink.href = 'javascript: void(0);';
			
			sortPriceLink.appendChild(document.createTextNode('Sort by Price'));
			sortPriceLink.searchValue 	= 'price';
			sortPriceLink.sortOrder		= 'DESC';
			
			_clearNode(sortPriceHeader);
			sortPriceHeader.appendChild(sortPriceLink);			
			dojo.connect(sortPriceLink, 'onclick', this, 'setSearch');
		},
		
		setBand	: function(theObject, theBand)
		{
			var action = theBand.getActive() ? 'add' : 'remove';
			_checkCss(action, theObject, 'selected');
		},

		buildTableRow : function(reviewToAdd, areWeHumanOrAreWeDancer) {

			if (reviewToAdd.getPartCode().toString() != 'undefined') {

				// insert a new row for a review
				var trReview = _reviewBody.insertRow(0);

				trReview.id = 'tr' + reviewToAdd.getId();

				this.buildFirstCell(trReview, reviewToAdd);
				this.buildSecondCell(trReview, reviewToAdd);
				this.buildThirdCell(trReview, reviewToAdd);
				this.buildFourthCell(trReview, reviewToAdd);

				trReview.className = (areWeHumanOrAreWeDancer % 2 == 0) ? 'odd'	: 'even';

			}

		},
		/**
		 * Build the first cell of the row, appending elements as necessary.
		 */

		buildFirstCell : function(theRow, reviewToAdd) {
			var theCell = theRow.insertCell(0);

			theCell.id = 'cellFirst' + reviewToAdd.getId();
			
			
			var reviewLink = document.createElement('a');
			reviewLink.setAttribute('href', reviewToAdd.getUri());
			reviewLink.setAttribute('title', reviewToAdd.getPartCode());

			var reviewLinkImg = reviewLink.cloneNode(true);

			var reviewImg = document.createElement('img');
			reviewImg.setAttribute('src', reviewToAdd.getImage());
			_checkCss('add', reviewImg, 'articleImage');
			_checkCss('add', reviewImg, 'smallImage');

			reviewImg.setAttribute('alt', reviewToAdd.getName());

			reviewLinkImg.appendChild(reviewImg);

			var reviewHeadingLink = reviewLink.cloneNode(true);
			var reviewHeading = document.createElement('h2');
			
			var reviewManufacturer  = reviewToAdd.getManufacturer().getName();
			var reviewName			= reviewToAdd.getName();
			var reviewHeadingText = document.createTextNode(reviewManufacturer + ' ' + reviewName);

			reviewHeadingLink.appendChild(reviewHeadingText);
			reviewHeading.appendChild(reviewHeadingLink);

			var reviewParagraph = document.createElement('p');
			_checkCss('add', reviewParagraph, 'floatRight');
			_checkCss('add', reviewParagraph, 'bold');


			theCell.appendChild(reviewLinkImg);
			theCell.appendChild(reviewHeading);
			theCell.appendChild(reviewParagraph);

			return theCell;
		},

		buildSecondCell : function(theRow, reviewToAdd) {

			var theCell = theRow.insertCell(1);

			theCell.id = 'cellRating' + reviewToAdd.getId();
			var ratingImg = document.createElement('img');

			ratingImg.setAttribute('src', '/images/rating6/' + reviewToAdd.getRating() + '.gif');
			ratingImg.setAttribute('alt', 'Rating');	
			theCell.appendChild(ratingImg);

			return theCell;
		},

		buildThirdCell : function(theRow, reviewToAdd) {
			var theCell = theRow.insertCell(2);

			theCell.id = 'cellPriceGrabber' + reviewToAdd.getId();

			var priceText = document.createTextNode(reviewToAdd.getPrice());
			theCell.appendChild(priceText);
			
			return theCell;
		},

		buildFourthCell : function(theRow, reviewToAdd) {
			var theCell = theRow.insertCell(3);

			theCell.id = 'cellSelect' + reviewToAdd.getId();

			var reviewCheckbox = document.createElement('input');
			reviewCheckbox.setAttribute('type', 'checkbox');
			reviewCheckbox.setAttribute('value', reviewToAdd.getId());
			reviewCheckbox.setAttribute('name', 'reviewsCheckbox[]');

			reviewCheckbox.checked = reviewToAdd.getSelected();

			reviewCheckbox.id = 'link' + reviewToAdd.getId();

			//reviewCheckbox.review = reviewToAdd;
			dojo.connect(reviewCheckbox, 'onclick', this, 'toggleSelection');

			theCell.appendChild(reviewCheckbox);

			return theCell;
		},
		
		bandClick	: function(event)
		{
			var bandObj, selectedBand = event.target;
			
			while (!selectedBand.band) {
				selectedBand = selectedBand.parentNode;
			}			
			
			if (bandObj = selectedBand.band) {
				//alert(bandObj.getId());
				bandObj.setActive(!bandObj.getActive());
				this.setBand(selectedBand.parentNode, bandObj);
				bandObj.update();
			}

		},

		/**
		 * Based on the results from the consumed XML, populate the bands with
		 * the updated count of how many there are.
		 */
		updateBandCounts : function(theFilterSet) {
			var i, j, theseFilters;
			theseFilters = theFilterSet.getFilters();
			for (i = 0; i < theseFilters.length; i++) {
				var spanBands = theseFilters[i].getBands();

				for (j = 0; j < spanBands.length; j++) {
					this.updateBandCount(spanBands[j]);
				}
			}
		},

		/**
		 * Update a specific band's associated span.
		 */
		updateBandCount : function(theBand) 
		{
			var spanId, bandSpan, bandText;

			spanId = 'band' + theBand.getId() + 'Count';
			if (bandSpan = document.getElementById(spanId)) {
					// remove any existing text nodes
				while (bandSpan.hasChildNodes()) {
					bandSpan.removeChild(bandSpan.firstChild);
				}
				var bandCount = theBand.getCount();
				if (!bandCount) {
					bandCount = 0;
				}
				// create a new text node with the count of products
				bandText = document.createTextNode('(' + bandCount + ')');
				// append it to the span
				bandSpan.appendChild(bandText);
			}
		},

		setSearch : function(searchSelect) {
					
			var search = searchSelect.target;
			filterSet.setSearch(search.searchValue);
			search.sortOrder = (search.sortOrder == 'DESC') ? 'ASC' : 'DESC';
		
			this.setOrder(search.sortOrder);
			//filterSet.xmlRefresh();
		
		},

		setOrder : function(order) {
			filterSet.setSort(order);
			filterSet.xmlRefresh();
		},

		shiftResults : function(selected) {
			var offset;
			
			if ( (selected.constructor === Number) && (Math.round(selected, 0) === selected)) {
				page = selected;
			} else {
				page = selected.target.page;
			}
			var offset = (page - 1) * filterSet.getLimit();

			if (offset > filterSet.getTotal()) {
				offset = filterSet.getTotal();
			}
			
			if (offset != filterSet.getOffset()) {
				filterSet.setOffset(offset);
				filterSet.xmlRefresh();
			}
		},


		toggleSelection : function(obj) 
		{
		
		
			var selected 	= (obj.target) ? obj.target : obj;
			
			while (!selected.value) {
				selected = selected.parentNode;
			}
		
			var review =  filterSet.getReviewById(selected.value);
		
			var checkbox;
			
			if (review) {
				review.setSelected(!review.getSelected());
				checkbox = dojo.byId('link' + review.getId());
				if (review.getSelected()) {
			
					checkbox.checked = true;
					this.selectReview(review);
			
				} else {
					checkbox.checked = false;
					this.deselectReview(review.getId());
				}
				//selected.blur();
			} else {
				// has to be deselect doesn't it?
				this.deselectReview(selected.value);
			}
			
			return;
		},

		fire : function(event, filterSet) {
			this.update(filterSet);
		},

		update : function(filterSet) {
		
			var reviews = filterSet.getReviews();
			// Flip the array so that the first item appears at the top of the table
				reviews.reverse();
				if (!_reviewBody) {
					_reviewBody = dojo.byId(_reviewBodyId);
				}
				// set previously selected ones as selected
				var i, j;
		
				for (i = 0; i < _selectedReviews.length; i++) {
					for (j = 0; j < reviews.length; j++) {
						if (_selectedReviews[i].getId() == reviews[j].getId()) {
							reviews[j].setSelected(true);
							break;
						}
					}
				}
		
				_clearNode(_reviewBody);
		
				this.buildTable(filterSet);
		
				this.updateBandCounts(filterSet);
		
				_compare(this);
		
				// alert(filterSet.getTotal());
		
			},
		
			yarr : function() {
				alert('yarr');
			}

	};
};

var getRequest = function(filterSetObj) {

	filterSetObj = filterSetObj || filterSet;

	var requestUri = filterSetObj.getRequestUri();
	var requestArgs = filterSetObj.getRequestArgs();
	var fullUri = requestUri + '?' + requestArgs;

	// productFilter.loaderStart();

	var _response = dojo.xhrGet( {
		// The following URL must match that used to test the server.
		url :fullUri,
		handleAs :'text',

		// timeout : 5000, // Time in milliseconds
		// content : filterSetObj.getRequestArgs(),

		// The LOAD function will be called on a successful response.
		load : function(response, ioArgs) {

			try {
				filterSetObj.xmlParse(response);
				priceService.parseReviews(filterSetObj.getReviews());
				priceService.fetchAll();
			} catch (e) {

			}
			// productFilter.loaderFinish();
			return response;
		},

		// The ERROR function will be called in an error case.
		error : function(response, ioArgs) {
			// alert("HTTP status code: ", ioArgs.xhr.status);
			console.error("HTTP status code: ", ioArgs.xhr.status);
			//alert(response);
			// alert(this.content);
			return response;
		}

	});		
};

/**
 * PriceService class deals with putting the pricegrabber prices on the reviews filter index
 */
dojo.declare("PriceService", null, {
	constructor: function(xmlRequestUri) {
		this._xmlRequestUri = xmlRequestUri;
		this._masterIds = {};
	},
	
	/**
	 * Looks for masterIds in the reviews array
	 * 
	 * @param reviews
	 */
	parseReviews: function(reviews) {
		this._masterIds = {}; // clear the master Ids every time we parse the reviews collection
		for (i in reviews) {
			var masterId = reviews[i].getMasterId();
			if (masterId != undefined && masterId != 0) {
				this.addReview(masterId, reviews[i]);
			}
		}
	},
	
	/**
	 * Saves a review against its assigned masterId for use later
	 
	 * @param masterId
	 * @param review
	 */
	addReview: function(masterId, review) {
		this._masterIds[masterId] = review; 
	},
	
	/**
	 * Gets an array of masterIds from the collection of masterId indexed reviews
	 * 
	 * @return Array
	 */
	getMasterIds: function() {
		var masterIds = new Array();
		for (attr in this._masterIds) {
			masterIds.push(attr);
		}
		return masterIds;
	},
	
	/**
	 * Ask the Pricegrabber service for the product details using AJAX
	 * 
	 */
	fetchAll: function() {

		var masterIds = this.getMasterIds();
		if (masterIds.length > 0) {
		    var requestArgs = 'method=getAll&masterIds=' + this.getMasterIds().join(',');
		    var fullUri = this._xmlRequestUri + '?' + requestArgs;
		    var priceService = this;
		    var _response = dojo.xhrGet( {
		        url: fullUri,
		        handleAs: 'xml',
		        load: function(data, args)
		        {
		    		var productData = priceService._parseXmlDoc(data);
		    		for (i in productData) {
		    			priceService._insertPrice(productData[i].review, productData[i].price, productData[i].num_retailers);
		    		}
		        },
		        error: function(data, args)
		        {
		        	console.log('Error in PriceService.fetchAll xhrGet');
		        }
		    });
		}

	},
	
	/**
	 * Does nothing - should do the same as above but for a single product - is it really needed?
	 * @param masterId
	 * @param reviewId
	 * @return
	 */
	
	fetchOne: function(masterId, reviewId) {
		// @todo turn the masterId into a price and a num_retailers then add it to the product
	    var requestArgs = 'method=get&masterId=' + masterId;
	    var fullUri = this._xmlRequestUri + '?' + requestArgs;
	    var priceService = this;
	    alert("function 'fetchOne' is not implemented");
	
	},
	/**
	 * Turns the XMLDocument returned by the AJAX into a nice array of objects with just the info needed for inserting into the page
	 * 
	 * @param xmlDoc
	 * @return Array
	 */
	_parseXmlDoc: function(xmlDoc) {
		var returnProductData = new Array();
        var products = xmlDoc.getElementsByTagName('products');
        if (products.length > 0 && products[0].hasChildNodes()) {
            var product = products[0].firstChild;
            while (product) {
                var review, price, offers;
                var node = product.firstChild;
                while (node) {
                    switch (node.nodeName) {
                        case 'masterId':
                        	if (node.firstChild) {
                        		review = this._masterIds[node.firstChild.nodeValue];
                        	}
                            break;
                        case 'price':
                        	if (node.firstChild) {
                        		price = node.firstChild.nodeValue;
                        	}
                            break;
                        case 'num_sellers':
                        	if (node.firstChild) {
                        		offers = node.firstChild.nodeValue;
                        	}
                            break;
                    }
                    node = node.nextSibling;
                }
                
                if (review && price && offers) {
                    returnProductData.push({review: review, price: price, num_retailers: offers});
                }
                
                product = product.nextSibling;
            }
        }
        return returnProductData;
	},
	
	/**
	 * Create the HTML Elements for the price and add it into the page
	 * @param review
	 * @param price
	 * @param num_retailers
	 * @return
	 */
	_insertPrice: function(review, price, num_retailers) {
		var theCell = document.getElementById('cellPriceGrabber' + review.getId());
		
		if (theCell != undefined) {
			if (theCell.childNodes.length == 1) {			
				var priceLink = document.createElement('a');
				priceLink.setAttribute('href', review.getUri() + '#latestPrices');
				priceLink.setAttribute('title', review.getPartCode());
				priceLink.setAttribute('class', 'small');
				
				var brNode = document.createElement('br');
				
				var retailersText = document.createTextNode('(' + num_retailers + ' retailers)');
				
				priceLink.appendChild(retailersText);
				
				theCell.appendChild(brNode);
				theCell.appendChild(priceLink);
			}
		}
	}
});