function reviewHandler() {
	
	var me = this;
	
	this.init = function() {
	
		var sub = document.getElementById('btnReview');
		if(!sub)
			return;
		if(navigator.userAgent.indexOf('MSIE') > -1) { 
			var tmpBtn = sub;
				sub = document.createElement('<INPUT type="button" />');
				sub.value = tmpBtn.value;
				sub.id = 'btnReview';
			tmpBtn.parentNode.insertBefore(sub, tmpBtn);
			tmpBtn.parentNode.removeChild(tmpBtn);
		} else
			sub.setAttribute('type', 'button');
		sub.onclick = function() {
			me.addReview();
		}
			
	}
	
	this.deleteReview = function(id) {

		if(!confirm('Are you sure?'))
			return;
		
		var form = document.getElementById('form_review');
		var review = document.getElementById('review_' + id);
		var params = new Array();
			params['id'] = id;
			params['ajax'] = true;
			
		doRequest(me.getBaseUrl(form.getAttribute('action')) + 'delete', function(res){
			if(!res.responseXML) {
				alert(res.responseText);
				return;
			}
			new Effect.SlideUp(review, { afterFinish: function(obj) {
				var par = obj.element.parentNode;
					par.removeChild(obj.element);
				var reviews = me.getReviewContainers(par);
				if(reviews.length == 0)
					document.getElementById('reviewCount').innerHTML = 'Reviews';
				else
					document.getElementById('reviewCount').innerHTML = 'Reviews (' + (reviews.length+1) + ')';
				var firstTReview = document.getElementById('firstReview');
				if(reviews.length == 0) {
					if(firstTReview)
						firstTReview.style.display = 'block';
					else {
						firstTReview = document.createElement('DIV');
						firstTReview.id = 'firstReview';
						firstTReview.innerHTML = '<br />&nbsp;&nbsp;&nbsp;No reviews have been made. Be the first to write one!';
						par.insertBefore(firstTReview, form);
					}
				} else {
					if(firstTReview)
						firstTReview.style.display = 'none';
					if(!document.getElementById('review_rss')) {
						var revCont = reviews[0];
						var postCont = getElementsByClassName(revCont, 'DIV', 'collectibles_specific_reviews_post')[0];
						var cont = postCont.parentNode;
		
						var rsscont = document.createElement('DIV');
							rsscont.className = 'collectibles_specific_reviews_rss';
							rsscont.id = 'review_rss';
						var rssLink = document.createElement('A');
							rssLink.href = '#';
						var rssImage = document.createElement('IMG');
							rssImage.src = 'http://www.collectionstation.com/resources/images/icons/rss_16x16.png';
							rssLink.appendChild(rssImage);
							rsscont.appendChild(rssLink);
							cont.insertBefore(rsscont, postCont);
					}
				}
			}});
		}, params);
		
	}
	
	this.addReview = function() {
		
		//debugger;
		
		var form = document.getElementById('form_review');
		
		var review = document.getElementById('review_text');
		var pros = document.getElementById('pros');
		var cons = document.getElementById('cons');
		var rating = document.getElementById('revRating');
		var itemId = document.getElementById('item');
		
		var validationErrors = ''
		if(review.value.split(' ').length < 20)
			validationErrors += "Review must contain a minimum of 20 words!\n";
		if(pros.value.split(' ').length < 15)
			validationErrors += "Pros must contain a minimum of 15 words!\n";
		if(cons.value.split(' ').length < 15)
			validationErrors += "Cons must contain a minimum of 15 words!\n";
		if(rating.value == 'null') 
			validationErrors += "You must rate this item if you are writing a review!\n";
		
		if(validationErrors != '') {
			alert("The following errors have occurred:\n\n" + validationErrors);
			return;
		}
		
		var params = new Array();
			params['itemId'] = itemId.value;
			params['review_text'] = review.value;
			params['pros'] = pros.value;
			params['cons'] = cons.value;
			if(rating.value.indexOf('|') == -1)		
				params['revRating'] = rating.value;
			else
				params['revRating'] = 'null';
			params['ajax'] = true;
			
		doRequest(form.getAttribute('action'), function(res) {
			if(!res.responseXML) {
				alert(res.responseText);
				return;
			}
			params['revRating'] = rating.value;
			me.showReview(res.responseXML.documentElement, params);
		}, params);
		
	}

	this.cleanReviewData = function(data) {

		return data;

	}

	this.getReviewContainers = function(c) {
		
		var results = new Array();
		for(var i = 0; i < c.childNodes.length; i++) {
			
			if(c.childNodes[i].className && c.childNodes[i].className.indexOf('collectibles_specific_reviews_row') > -1)
				results[results.length] = c.childNodes[i];
			
		}
		return results;
		
	}
	
	this.handleCommentData = function(data) {
		data = data.replace(/[\n\r]+/g, '');
		data = data.replace(/\<br\>/g, "\n");	
		data = data.replace(/\<br \/\>/g, "\n");
		return data;	
	}
	
	this.editReview = function(id) {

		var review = document.getElementById('review_' + id);
		
		var form = document.getElementById('form_review');
		
		var reviewtext = document.getElementById('reviewtext_' + id);
		var reviewprostext = document.getElementById('reviewprostext_' + id);
		var reviewconstext = document.getElementById('reviewconstext_' + id);
		var btns = document.getElementById('updatebtns_' + id);
		var updatebtn = document.getElementById('update_review_' + id);
		var cancelbtn = document.getElementById('cancel_review_' + id);
		
		var reviewData = reviewtext.innerHTML;  
		var prosData = reviewprostext.innerHTML;
		var consData = reviewconstext.innerHTML;
		
		var reviewtext_area = document.createElement('TEXTAREA');
			reviewtext_area.id = 'edit_reviewtext_' + id;
			reviewtext_area.className = 'edit_reviewInput';
			reviewtext_area.value = reviewData;
			reviewtext_area.setAttribute('data', reviewData);
			reviewtext.innerHTML = '';
			reviewtext.appendChild(reviewtext_area);
		var reviewtextpros_area = document.createElement('TEXTAREA');
			reviewtextpros_area.id = 'edit_reviewtextpros_' + id;
			reviewtextpros_area.setAttribute('data', prosData);
			reviewtextpros_area.value = prosData;
			reviewtextpros_area.className = 'edit_reviewInput';
			reviewprostext.innerHTML = '';
			reviewprostext.appendChild(reviewtextpros_area);	
		var reviewtextcons_area = document.createElement('TEXTAREA');
			reviewtextcons_area.id = 'edit_reviewtextcons_' + id;
			reviewtextcons_area.setAttribute('data', consData)
			reviewtextcons_area.value = consData;	
			reviewtextcons_area.className = 'edit_reviewInput';
			reviewconstext.innerHTML = '';
			reviewconstext.appendChild(reviewtextcons_area);

		btns.style.display = 'block';
					
		updatebtn.onclick = function() {
			var reviewtext = document.getElementById('reviewtext_' + id);
			var reviewprostext = document.getElementById('reviewprostext_' + id);
			var reviewconstext = document.getElementById('reviewconstext_' + id);
			var reviewtext_txt = document.getElementById('edit_reviewtext_' + id);
			var reviewprostext_txt = document.getElementById('edit_reviewtextpros_' + id);
			var reviewconstext_txt = document.getElementById('edit_reviewtextcons_' + id);
			
			var params = new Array();
				params['id'] = id;
				params['review_text'] = reviewtext_txt.value;
				params['pros'] = reviewprostext_txt.value;
				params['cons'] = reviewconstext_txt.value;
				params['ajax'] = true;
				
			doRequest(me.getBaseUrl(form.getAttribute('action')) + 'update', function(res) {
				if(!res.responseXML) {
					alert(res.responseText);
					return;
				}
				
				reviewtext.innerHTML = me.nl2br(params['review_text']);
				reviewprostext.innerHTML = me.nl2br(params['pros']);
				reviewconstext.innerHTML = me.nl2br(params['cons']);
				
				btns.style.display = 'none';
				
				new Effect.Highlight('review_' + id);
				
			}, params);
		}
		cancelbtn.onclick = function() {
			
			var reviewtext = document.getElementById('reviewtext_' + id);
			var reviewprostext = document.getElementById('reviewprostext_' + id);
			var reviewconstext = document.getElementById('reviewconstext_' + id);
			var reviewtext_txt = document.getElementById('edit_reviewtext_' + id);
			var reviewprostext_txt = document.getElementById('edit_reviewtextpros_' + id);
			var reviewconstext_txt = document.getElementById('edit_reviewtextcons_' + id);
			var data = btns.getAttribute('data');
			reviewtext.innerHTML = me.nl2br(reviewtext_txt.getAttribute('data'));
			reviewprostext.innerHTML = me.nl2br(reviewprostext_txt.getAttribute('data'));
			reviewconstext.innerHTML = me.nl2br(reviewconstext_txt.getAttribute('data'));
			btns.style.display = 'none';
		}
	}
	
	this.getBaseUrl = function(url) {
		
		var parts = url.split('/');
		var newUrl = '';
		for(var i = 0; i < parts.length-((url[url.length-1] == '/') ? 2 : 1); i++) {
			newUrl += parts[i] + '/';
		}
		return newUrl;
		
	}
	
	this.showReview = function(res, data) {
		
		var id = res.getAttribute('id');
		var username = res.getAttribute('username');
		var image = res.getAttribute('userimage');
		var tools_view = res.getAttribute('view');
		var firstTReview = document.getElementById('firstReview');
		if(firstTReview)
			firstTReview.style.display = 'none';
		
		var form = document.getElementById('form_review');
		var cont = document.getElementById('collectibles_specific_reviews_details_container');
		
		var reviews = me.getReviewContainers(cont);
		document.getElementById('reviewCount').innerHTML = 'Reviews (' + (reviews.length+1) + ')';
		var nextClass = (reviews.length == 0 ? 'collectibles_specific_reviews_row1' : ((reviews[reviews.length-1].className == 'collectibles_specific_reviews_row1') ? 'collectibles_specific_reviews_row2' : 'collectibles_specific_reviews_row1'));
		
		var review = document.createElement('DIV');
			review.className = nextClass;
			review.id = 'review_' + id;
			
		var anc = document.createElement('A');
			anc.name = 'review:' + id;
			review.appendChild(anc);
			
		var imagecont = document.createElement('DIV');
			imagecont.className = 'collectibles_specific_reviews_userpic';
		var userimage = document.createElement('IMG');
			userimage.setAttribute('title', username);
			userimage.setAttribute('alt', username);
			userimage.src = ((image == '') ? 'http://www.collectionstation.com/resources/images/misc/profile_pic_50x50.gif' : 'http://www.collectionstation.com/resources/images/profile/thumb/' + image);
			userimage.style.width = '50px';
			userimage.style.height = '50px';
			imagecont.appendChild(userimage);
			review.appendChild(imagecont);
		
		var reviewcont = document.createElement('DIV');
			reviewcont.className = 'collectibles_specific_reviews_postcont';
		
		var reviewuser = document.createElement('DIV');
			reviewuser.className = 'collectibles_specific_reviews_username';
		var reviewuserLink = document.createElement('A');
			reviewuserLink.href = 'http://www.collectionstation.com/' + username;
			reviewuserLink.appendChild(document.createTextNode(username));
			reviewuser.appendChild(reviewuserLink);
			reviewuser.appendChild(document.createTextNode(' reviewed this ' + me.reviewTime(new Date())));
			reviewcont.appendChild(reviewuser);
		
		var itemId = document.getElementById('item');
		var reviewCount = document.createElement('DIV');
			reviewCount.className = 'review_count';
		var reviewCountLink = document.createElement('A');
			reviewCountLink.href = 'http://www.collectionstation.com/item/view/'+itemId.value+'/reviews/' + id;
			reviewCountLink.appendChild(document.createTextNode('#' + (reviews.length+1)));
			reviewCount.appendChild(reviewCountLink);
			reviewcont.appendChild(reviewCount);
			
		if(reviews.length == 0) {
			var rsscont = document.createElement('DIV');
				rsscont.className = 'collectibles_specific_reviews_rss';
				rsscont.id = 'review_rss';
			var rssLink = document.createElement('A');
				rssLink.href = '#';
			var rssImage = document.createElement('IMG');
				rssImage.src = 'http://www.collectionstation.com/resources/images/icons/rss_16x16.png';
				rssLink.appendChild(rssImage);
				rsscont.appendChild(rssLink);
			reviewcont.appendChild(rsscont);
		}		
		
		var reviewcont_inner = document.createElement('DIV');
			reviewcont_inner.className = 'collectibles_specific_reviews_post';
		
		var reviewtext = document.createElement('DIV');
			reviewtext.id = 'reviewtext_' + id;
			reviewtext.innerHTML = me.nl2br(unescape(data['review_text']));
			reviewcont_inner.appendChild(reviewtext);
			reviewcont_inner.appendChild(document.createElement('BR'));
			reviewcont_inner.appendChild(document.createElement('BR'));
		
		var temps = document.createElement('B');
			temps.appendChild(document.createTextNode('Pros'))
			reviewcont_inner.appendChild(temps);
			reviewcont_inner.appendChild(document.createElement('BR'));
			
		var reviewprostext = document.createElement('DIV');
			reviewprostext.id = 'reviewprostext_' + id;
			reviewprostext.innerHTML = me.nl2br(unescape(data['pros']));
			reviewcont_inner.appendChild(reviewprostext);
			reviewcont_inner.appendChild(document.createElement('BR'));
			reviewcont_inner.appendChild(document.createElement('BR'));
		
		var temps = document.createElement('B');
			temps.appendChild(document.createTextNode('Cons'))
			reviewcont_inner.appendChild(temps);
			reviewcont_inner.appendChild(document.createElement('BR'));
		
		var reviewconstext = document.createElement('DIV');
			reviewconstext.id = 'reviewconstext_' + id;
			reviewconstext.innerHTML = me.nl2br(unescape(data['cons']));
			reviewcont_inner.appendChild(reviewconstext);
			reviewcont_inner.appendChild(document.createElement('BR'));
			reviewcont_inner.appendChild(document.createElement('BR'));
			
		var updatebtns = document.createElement('DIV');
			updatebtns.id = 'updatebtns_' + id;
			updatebtns.style.display = 'none';
			
		var updatebtn = document.createElement('INPUT');
			updatebtn.id = 'update_review_' + id;
			updatebtn.value = 'Save';
			updatebtn.setAttribute('type', 'button');
			updatebtn.onclick = function() {};
			updatebtns.appendChild(updatebtn);
		var cancelbtn = document.createElement('INPUT');
			cancelbtn.id = 'update_cancel_' + id;
			cancelbtn.value = 'Cancel';
			cancelbtn.setAttribute('type', 'button');
			cancelbtn.onclick = function() {};
			updatebtns.appendChild(cancelbtn);
			reviewcont_inner.appendChild(updatebtns);
			
		var temps = document.createElement('B');
			temps.appendChild(document.createTextNode('Rated'))
			reviewcont_inner.appendChild(temps);
			reviewcont_inner.appendChild(document.createElement('BR'));
			
		var ratingcont = document.createElement('DIV');
			ratingcont.className = 'rating setup5HalfStar';
		var ratingul = document.createElement('UL');
		var ratingaccli = document.createElement('LI');
			ratingaccli.className = 'rating_accessibility';
			ratingaccli.appendChild(document.createTextNode('Some accessibility text'));
			ratingul.appendChild(ratingaccli);
		var ratingcurrli = document.createElement('LI');
			ratingcurrli.className = 'rating_current';
			if(data['revRating'].indexOf('|') > -1)
				data['revRating'] = data['revRating'].split('|')[1];
			ratingcurrli.style.width = (data['revRating'] * 18) + 'px';
			ratingcurrli.appendChild(document.createTextNode(data['revRating'] + '/5'));
			ratingul.appendChild(ratingcurrli);
		var ratingres = document.createElement('DIV');
			ratingres.className = 'rating_result';
			ratingres.appendChild(document.createTextNode('You rated: ' + data['revRating'] + '/5'));
			ratingcont.appendChild(ratingul);
			ratingcont.appendChild(ratingres);
			
		reviewcont_inner.appendChild(ratingcont);
		reviewcont.appendChild(reviewcont_inner);
		
		var review_tools = document.createElement('DIV');
			review_tools.className = 'collectibles_specific_reviews_tools';
		var tools_ddl = document.createElement('SELECT');
			tools_ddl.id = 'review_options_'+id;
			tools_ddl.options[tools_ddl.options.length] = new Option('Options', -1);
			tools_ddl.options[tools_ddl.options.length] = new Option('Edit', 'edit');
			tools_ddl.options[tools_ddl.options.length] = new Option('Delete', 'delete');
			tools_ddl.options[tools_ddl.options.length] = new Option('Sticky', 'sticky');
			tools_ddl.onchange = function() {
				me.handleOptionSelect(this);
			}
		/*var tools_edit = document.createElement('A');
			tools_edit.href = 'javascript:void(0)';
			tools_edit.id = 'review_edit_' + id;
			tools_edit.onclick = function() {
				me.editReview(this.id.split('_')[2]);
			};
			tools_edit.appendChild(document.createTextNode('Edit'));
			review_tools.appendChild(tools_edit);
			review_tools.appendChild(document.createTextNode(' | '));
		var tools_delete = document.createElement('A');
			tools_delete.href = 'javascript:void(0)';
			tools_delete.id = 'review_delete_' + id;
			tools_delete.onclick = function() {
				me.deleteReview(this.id.split('_')[2]);				
			};
			tools_delete.appendChild(document.createTextNode('Delete'));
			review_tools.appendChild(tools_delete);*/
			review_tools.appendChild(tools_ddl);
		if(res.getAttribute('view') == 'true')
			reviewcont.appendChild(review_tools);
		var br = document.createElement('BR');
			br.style.clear = 'both';
		reviewcont.appendChild(br);
		review.appendChild(reviewcont);
		cont.insertBefore(review, form);		
		
		var reviewt = document.getElementById('review_text');
		var prost = document.getElementById('pros');
		var conste = document.getElementById('cons');
		reviewt.value = '';
		prost.value = '';
		conste.value = '';
		
		
		new Effect.Highlight(review, {queue: 'front'});
		new Effect.ScrollTo(review, {queue: 'end'});
	}
	
	this.handleOptionSelect = function(which) {
		var id = which.id.split('_')[2];
		if(which.selectedIndex == -1 || which.options[which.selectedIndex].value == -1)
			return false;
		switch(which.options[which.selectedIndex].value) {
			case 'edit' :
				me.editReview(id);
			break;
			case 'delete' :
				me.deleteReview(id);			
			break;
			case 'sticky' :
				me.stickyReview(id);
			break;
			case 'unsticky' :
				me.unstickyReview(id);				
			break;
		}
		
	}
	
	this.stickyReview = function(id) {
		
		if(!confirm('Are you sure?'))
			return;
			
		window.location = 'http://www.collectionstation.com/tools/stickReview/'+id;
		
	}
	
	this.unstickyReview = function(id) {
		
		if(!confirm('Are you sure?'))
			return;

		window.location = 'http://www.collectionstation.com/tools/unStickReview/'+id;
		
	}
	
	this.nl2br = function(text){
		return text.replace(/\n/g, "<br />");
	}
	
	this.reviewTime = function(d) {
		
		var hour = d.getHours();
		var isAM = true;
		if(hour < 10) {
			hour = '0' + hour;
			isAM = true;
		} else if(hour > 12) {
			isAM = false;
			hour = hour - 12;
		}
		var minute = d.getMinutes();
		if(minute < 10)
			minute = '0' + minute;
		
		return 'Today at ' + hour + ':' + minute + ((isAM) ? ' AM' : ' PM');
	}	
	
}