/*	
Script: jlogger.js
	Enables clientside logging for any client side data or events.
	
Dependancies:
	 mootools - <Moo.js>, <Utility.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>
	 cnet libraries - <dbug.js>
	
Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>

Class: Jlogger
Enables clientside logging for any client side data or events.
You can capture any data the browser knows; resolution, scroll distance (see <JlScroller>), mouseover, etc.

Reports:
Reports for Jlogger events can be found in CNET DW reports at

CNET Reporting > Shared Reports > Redball > Miscellaneous > JLogger Events

Arguments:
	options - optional, an object containing options.

Options:
	tag - (required) the tag for DW
	element - (optional) the id of the element or the DOM element itself or false; use false if you want to call //.ping
						yourself, use a dom element if you want to observe it using the event option below. defaults to false
	event - (optional) the event that the element captures; load, click, etc. (do not include "on")
	ontid - (string or integer) the ontology id, defaults to the nodeId of the page
	
	ptId - (string or integer) the product id, defaults to the pageType of the page
	edId - (string or integer) the edition id, defaults to the editionId of the page
	siteId - (string or integer) the site Id, defaults to the siteId of the page
	cval - (string) the cval option passed to DW; defaults to false (no value)
	ctype - (string) the ctype val passed to DW; defaults to false (no value)
	useraction - (optional; string or integer) the urs user action id, not used if not included
	fireOnce - (boolean; optional) only fire this event once (true); fire every time (false; default)

Events:
	onPing - (function) callback executed when the ping method is executed

	
Example:
	(start code)
//ping DW when the window loads
new Jlogger({
	ontid: '20', 
	siteId:'4', 
	ptId:'2001',
	tag:'windowLoad', 
	element: window, 
	event: 'load',
	fireOnce: true
});

//ping dw when the user clicks on some element
new Jlogger({
	ontid: '20', 
	siteId:'4', 
	ptId:'2001',
	tag:'somethingClicked', 
	element: 'myElementId', 
	event: 'click',
});

//ping DW NOW
new Jlogger({
	ontid: '20', 
	siteId:'4', 
	ptId:'2001',
	tag:'someAction'
}).ping();
(end)

Note:
See <JlScroller> class for scroll capturing.
	*/
var Jlogger = new Class({
	options: {
		ctype: false,
		cval: false,
		tag: false,
		element: false,
		event: false,
		useraction: false,
		fireOnce: false,
		executeNow: false, //deprecated, use new Jlogger().ping();
		onPing: $empty
	},
	errors: 0,
	fired: false,
	active: true,
	initialize: function(options) {
		var defaults = (typeof PageVars != "undefined")?{
			ontid: PageVars.nodeId,
			siteId: PageVars.siteId,
            asId: PageVars.assetId,
            ptId: PageVars.pageType,
			edId: PageVars.editionId
		}:{};
		this.setOptions(defaults, options);
		if(this.options.element == 'window') this.options.element = window;
		this.setup();
		if(this.options.executeNow) this.ping();//deprecated, use new Jlogger().ping();
	}, 
	setup: function(){
		if(!$(this.options.element)) return;
		var opt = this.options; //saving bytes
		if ($type(opt.tag) && $type(opt.element) && $type(opt.event)){
			//else tag is set, element is set, and event is set, log this info and...
			dbug.log('event observe(element: '+opt.element+', event: '+opt.event+', tag: '+opt.tag+')');
			//if the event == "load" and the observed element is the window, execute the ping immediately
			if(opt.event == 'load' && opt.element == window) opt.executeNow = true;
			//observe the elemnt for the event.
			if(opt.element != window) $(opt.element).addEvent(opt.event, this.ping.bind(this));
			else if(opt.event != 'load') $(opt.element).addEvent(opt.event, this.ping.bind(this));
		}
	},
	//generates the url to ping DW and returns it
	makeURL: function(tag) {
		var url = 'http://dw.com.com/redir?';
		var opt = this.options;//saving bytes
		if($type(opt.ontid)) url+= 'ontid='+opt.ontid+'&';
		if($type(opt.siteId)) url+= 'siteid='+opt.siteId+'&';
        if($type(opt.asId)) url+= 'asId='+opt.asId+'&';
        if($type(opt.ptId)) url+= 'ptId='+opt.ptId+'&';
		if($type(opt.edId)) url+= 'edId='+opt.edId+'&';
		if($type(opt.ctype)) url+= 'ctype='+opt.ctype+'&';
		if($type(opt.cval)) url+= 'cval='+opt.cval+'&';
		if($type(opt.useraction)) url+= 'useraction='+opt.useraction+'&';
		url+= 'tag='+opt.tag+'&destUrl=/i/b.gif';
		//append a date value so that the browser doesn't cache the request
		url+= '&uniquePingId='+new Date().getTime();
		return url;
	},
/*	Property: ping
		Adds the call to DW with the passed in url; if url is not defined, it will create 
		one with the options that were passed in when it was created. Will not ping if 
		fireOnce = true and this has already been fired.
		
		Arguments:
		url - (string) the url to append to the dom (optional)
		force - (boolean) execute the ping even if fireOnce=true and this has already been fired
			*/
	//creates a clear gif with the url passed in
	ping: function(url, force) {
		//if fireOnce is set and this hasn't yet fired, or fireOnce isn't set or is false, and this observer is active
		//then ping dw
		if (force || (((!this.fired && this.options.fireOnce) || !this.options.fireOnce) && this.active)) {
			//if the url isn't passed in to this function, get it from the makeURL function in this class
            url = ($type(url) != 'string' || url.length == 0)?this.makeURL():url;
            //if the doc is loaded, continue with the ping (doing this before the doc is loaded will break IE)
			window.addEvent('domready', function(){
				new Element('img').setProperty('src', url);
				//just creating the img and setting its src will cause the browser to hit the url, you don't
				//need to append it to the DOM
				this.fired = true;
				dbug.log(this.options.tag + ': '+(this.options.event||'')+'\nping: '+url);
				this.fireEvent('onPing');
			}.bind(this));
		}
	},
/*	Property: pingTag
		Use this instance of Jlogger and all its options, but ping DW with a different tag.
		
		Arguments:
		tag - (string) the tag to use in the ping.
		force - (boolean) execute the ping even if fireOnce=true and this has already been fired
		
		Example:
		>var jlWinLoad = new Jlogger({tag: 'myTag', element: document.body, event: 'load', ptId: 12345});
		>//later...
		>jlWinLoad.pingTag('someOtherTag'); //pings DW with the new tag 
		>//but doesn't alter the settings of the instance
	*/
	pingTag: function(tag, force){
		this.ping(this.makeURL(tag), force);
	},
/*	Property: stopObserving
		Stops pingging DW; can be turned back on with <startObserving>
	*/
	stopObserving: function(){
		//turns off this logger
		this.active = false;
	},
/*	Property: startObserving
		Starts pinging DW again; see also <stopObserving>.
	*/
	startObserving: function(){
		//turns it back on
		this.active = true;
	}
});
Jlogger.implement(new Events);
Jlogger.implement(new Options);
//legacy namespace
var jlogger = Jlogger;
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/common/utilities/jlogger.js,v $
$Log: jlogger.js,v $
Revision 1.16  2007/11/19 23:23:05  newtona
CNETAPI: added method "getMany" to all the CNETAPI.Utils.* classes so that you can get numerous items in one request.
ObjectBrowser: improved exclusion handling for child elements
jlogger.js, element.position.js: docs update
Fx.Sort: cleaning up tabbing
string.cnet: just reformatting the logic a little.

Revision 1.15  2007/09/20 22:26:06  kruegerw
Fixing some problems with Jlogger when passing in an element and an event

Revision 1.14  2007/09/18 18:29:18  kruegerw
use ptId to pass pagetype to DW, not pId.  Also, adding in tracking of the assetId while I'm in here for more granularity.

Revision 1.13  2007/09/17 18:05:49  newtona
moving page var defaults into the init phase.

Revision 1.12  2007/08/30 17:09:27  newtona
stickyWinFx, modalizer: updated syntax a litle
jlogger: updated docs
fixed a bug in Fx.Sort w/ IE6

Revision 1.11  2007/03/10 00:37:10  newtona
docs update

Revision 1.10  2007/03/10 00:31:10  newtona
.pingDW is now just .ping
element and event are no longer required (so jloggers can just get fired inline)
executeNow is deprecated; just use new Jlogger().ping()
added support for cval and ctype

Revision 1.9  2007/03/09 23:57:18  newtona
docs update

Revision 1.8  2007/03/09 23:23:23  newtona
*** empty log message ***

Revision 1.7  2007/03/09 20:15:03  newtona
numerous bug fixes

Revision 1.6  2007/03/09 18:42:27  newtona
options.name is no longer required or used

Revision 1.5  2007/02/21 00:30:18  newtona
switched Class.create to $empty

Revision 1.4  2007/02/07 20:52:22  newtona
implemented Options class
implemented Events class

Revision 1.3  2007/01/26 05:56:03  newtona
syntax update for mootools 1.0
docs update

Revision 1.2  2007/01/22 21:54:17  newtona
updated for mootools version 1.0
updated namespaces to capitazlied values

Revision 1.1  2007/01/09 02:39:35  newtona
renamed addons directory to "common" directory

Revision 1.4  2006/11/13 23:54:31  newtona
added some error handling

Revision 1.3  2006/11/03 19:42:06  newtona
moved jlscroller into it's own file

Revision 1.2  2006/11/03 19:38:32  newtona
Cleaning up a bit of code and documentation, mainly around the way the class stores options.

Revision 1.1  2006/11/02 21:28:08  newtona
checking in for the first time.


*/


/*	
Script: jlscroller.js
Extends the <jLogger> class to capture scroll events.

Dependancies:
	 mootools - <Moo.js>, <Utility.js>, <String.js>, <Array.js>, <Function.js>, <Element.js>, <Dom.js>
	 cnet libraries - <dbug.js>, <jlogger.js>
	
Author:
	Aaron Newton, <aaron [dot] newton [at] cnet [dot] com>

Class: JlScroller 
Adds Scroll captures to the jlogger class; extends <jlogger>.

Arguments:
	options - optional, an object containing options.

Options:
	scrollTo - {top: #|element, bottom: #|element}
		- top: a number for the top range to observe (i.e. if the user scrolls down that many pixels)
	     or an element, whose top will set the top range of the scroll area to observe
	bottom: (optional) - if left empty, the range will be zero (i.e. top = bottom)
	    - a number for the bottom range to observe
			- or the same element as the top element which will create a range the height of that element,
			- or, no value for top but an element id for the bottom will set the bottom of the element 
			     to a single line across the page,
			- or a different element, the top of which will define the bottom range of the area
 Note:
 a scrollTo observer requires no entry for the 'element' variable to instantiate it.
	      additionally, either the top or the bottom range must be visible (i.e. any portion 
			 of the range) for the ping to fire			

Example:
	(start code)
//capture a scroll to 800 pixels
new jlogger({
	ontid: '20', 
	siteId:'4', 
	pId:'2001', 
	tag:'scrollTo800', 
	fireOnce: false,
	event: 'scrollTo',
	scrollTo: {top:'800'}
});

//capture scroll to the top of an element
new jlogger({
	ontid: '20', 
	siteId:'4', 
	pId:'2001', 
	tag:'scrollBoxTop', 
	fireOnce: false,
	event: 'scrollTo',
	scrollTo: {top:'myElement'}
});
(end)
	*/
var JlScroller = Jlogger.extend({
	setup: function() {
		//if passed in: tag, event, and event == "scrollTo", set up a scroller monitor
 		if ($type(this.options.tag) && $type(this.options.event) && this.options.event == "scrollTo") {
			//log this if debug=true is in the url
			dbug.log('event observe(element: '+this.options.element+', event: '+this.options.event+', tag: '+this.options.tag+', scrollTo: '+this.options.scrollTo+')');
			//set up scrollTo monitor
			this.setUpScrollTo();
		} else this.parent();
	},
	//if we're observing a scroll event, this function handles the setup.
	setUpScrollTo: function() {
		//start with top & bottom set to invalid values (i.e. numbers that the browser can't create on the page)
		var top = -1;
		var bottom = -1;
		try {
			//if scrollTo.top is a number, set that number to the top range
			if ($type(this.options.scrollTo.top) && this.options.scrollTo.top.toInt) top = this.options.scrollTo.top.toInt();
			//else top is not a number, so set top to the top of the element passed in
			else if ($type(this.options.scrollTo.top)) top = $(this.options.scrollTo.top).getTop();
			//save this top value. we're going to need this variable even if it wasn't passed in
			//if all that was passed in was bottom: <elementId>, we'll need to get the top of that
			//element to figure out the bottom of it.
			tmpTop = top;
			//of the bottom is set
			if($type(this.options.scrollTo.bottom)) {
				//if top is still -1 and bottom isn't a number (it's assumed then that it's an element id)
				if (top == -1 && !$chk(parseInt(this.options.scrollTo.bottom)))
					//and save its top
					top = $(this.options.scrollTo.bottom).getTop();
				//if the bottom is the same as the top (in the case of passing in the same element id for both)
				//or the top wasn't set, then set the bottom of the range to the bottom of the element
				//which is calculated by adding the top position of the element to the height of the element
				if (this.options.scrollTo.bottom == this.options.scrollTo.top || !$type(this.options.scrollTo.top))
					bottom = $(this.options.scrollTo.bottom).getStyle('height').toInt() + top;
				else if ($chk(parseInt(this.options.scrollTo.bottom)) && tmpTop >= 0) //else, if the bottom is a number and top is set to something
					bottom = tmpTop + this.options.scrollTo.bottom; //add it to the top value
				else if ($chk(parseInt(this.options.scrollTo.bottom))) //else the top isn't set, so the bottom is just the number passed in
					bottom = this.options.scrollTo.bottom;
				else//else the bottom is an element, so the bottom is equal to the top of it.
					bottom = $(this.options.scrollTo.bottom).getTop();
			} else //else, bottom isn't set at all, so set it's numerical location = to the top
				bottom = top;
			//set top back to our placeholder
			top = tmpTop;
			//if top is still invalid (i.e. -1), make it equal to the bottom value
			if (top < 0) top = bottom;
			dbug.log("new tripwire (%s): top: %s, bottom: %s", this.options.tag, top, bottom);
			if (top >= 0 && bottom >=0) {
				//if the top & the bottom are both valid numbers (>0), set up the scroll observer
				window.addEvent('scroll', this.isOnScreen.bind(this, [top, bottom]));
				//check to see if this range is on screen right NOW
				this.isOnScreen(top, bottom);
			}
		} catch(e) {
			//if there was an error, the DOM might not be ready yet, let's wait a moment and try again
			//let's cap these retries at 10 times.
			if (this.errors < 10) {
				dbug.log('JlScroller error: %o, attempt #: %s', e, this.errors);
				this.errors++;
				this.setUpScrollTo.delay(20);
			} else dbug.log('giving up attempt to set up instance of JlScroller for %s', this.options.tag);
		}
	},
	isOnScreen: function(top, bottom) {
		//is the area defined on the screen
		// top: the top of the area
		// bottom: optional - the bottom of the zone
		// if bottom is not defined, then the area is just a line = top
		var dim = this.getScreenDimensions(); //get the dimensions of the browser screen
		var scroll = this.getScrollOffset(); //get the scroll offset
		try {
			//if the top of our range is between the scroll offset and the scroll offset + the window height (i.e. is visible)
			//or if the bottom is in that range
			if ((top > scroll.y && top < scroll.y+dim.h) || (bottom > scroll.y && bottom < scroll.y+dim.h)) {
				//if this hasn't been marked as having fired...
				//ping dw; note that ping sets this.fired to true
				if(!this.fired) this.ping();

			//if the user scrolled and the range is NOT visible, AND fireOnce is not set to true
			//set fired back to false (so it can fire again, but only once for each time that the
			//range becomes visible)
			} else if (this.fired && !this.options.fireOnce) this.fired = false;
		} catch(e) { dbug.log("isOnScreen error: %s", e) }
	},
	getScreenDimensions: function() {
		return {w: window.getWidth(), h: window.getHeight()};
	},
	getScrollOffset: function() {
		return {x: window.getScrollLeft(), y: window.getScrollTop()};
	}
});
//legacy namespace
var jlScroller = JlScroller;
/* do not edit below this line */   
/* Section: Change Log 

$Source: /cvs/main/flatfile/html/rb/js/global/cnet.global.framework/common/utilities/jlscroller.js,v $
$Log: jlscroller.js,v $
Revision 1.6  2007/03/28 18:09:03  newtona
removing $type.isNumber dependencies

Revision 1.5  2007/03/10 00:31:10  newtona
.pingDW is now just .ping
element and event are no longer required (so jloggers can just get fired inline)
executeNow is deprecated; just use new Jlogger().ping()
added support for cval and ctype

Revision 1.4  2007/03/09 20:15:03  newtona
numerous bug fixes

Revision 1.3  2007/01/26 05:56:03  newtona
syntax update for mootools 1.0
docs update

Revision 1.2  2007/01/22 21:54:17  newtona
updated for mootools version 1.0
updated namespaces to capitazlied values

Revision 1.1  2007/01/09 02:39:35  newtona
renamed addons directory to "common" directory

Revision 1.2  2006/11/04 00:52:21  newtona
added docs, fixed a little syntax

Revision 1.1  2006/11/03 19:41:25  newtona
moving jlscroller class into it's own javasacript file


*/




/*
Script: Tips.js
	Class for creating nice tooltips that follow the mouse cursor when hovering over an element.

License:
	MIT-style license.

Note:
	Tips requires an XHTML doctype.
*/

var Tips = new Class({

	Implements: [Events, Options],

	options: {
		onShow: function(tip){
			tip.setStyle('visibility', 'visible');
		},
		onHide: function(tip){
			tip.setStyle('visibility', 'hidden');
		},
		maxTitleChars: 30,
		showDelay: 100,
		hideDelay: 100,
		className: 'tool',
		offsets: {'x': 16, 'y': 16},
		fixed: false
	},

	initialize: function(elements, options){
		this.setOptions(options);
		elements = $$(elements);
		this.document = (elements.length) ? elements[0].ownerDocument : document;
		this.toolTip = new Element('div', {
			'class': this.options.className + '-tip',
			'styles': {
				'position': 'absolute',
				'top': '0',
				'left': '0',
				'visibility': 'hidden'
			}
		}, this.document).inject(this.document.body);
		this.wrapper = new Element('div').inject(this.toolTip);
		elements.each(this.build, this);
	},

	build: function(el){
		el.$attributes.myTitle = (el.href && el.get('tag') == 'a') ? el.href.replace('http://', '') : (el.rel || false);
		if (el.title){
			var dual = el.title.split('::');
			if (dual.length > 1){
				el.$attributes.myTitle = dual[0].trim();
				el.$attributes.myText = dual[1].trim();
			} else {
				el.$attributes.myText = el.title;
			}
			el.removeProperty('title');
		} else {
			el.$attributes.myText = false;
		}
		if (el.$attributes.myTitle && el.$attributes.myTitle.length > this.options.maxTitleChars)
			el.$attributes.myTitle = el.$attributes.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
		el.addEvent('mouseenter', function(event){
			this.start(el);
			if (!this.options.fixed) this.locate(event);
			else this.position(el);
		}.bind(this));
		if (!this.options.fixed) el.addEvent('mousemove', this.locate.bind(this));
		var end = this.end.bind(this);
		el.addEvent('mouseleave', end);
	},

	start: function(el){
		this.wrapper.empty();
		if (el.$attributes.myTitle){
			this.title = new Element('span').inject(
				new Element('div', {'class': this.options.className + '-title'}
			).inject(this.wrapper)).set('html', el.$attributes.myTitle);
		}
		if (el.$attributes.myText){
			this.text = new Element('span').inject(
				new Element('div', {'class': this.options.className + '-text'}
			).inject(this.wrapper)).set('html', el.$attributes.myText);
		}
		$clear(this.timer);
		this.timer = this.show.delay(this.options.showDelay, this);
	},

	end: function(event){
		$clear(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this);
	},

	position: function(element){
		var pos = element.getPosition();
		this.toolTip.setStyles({
			'left': pos.x + this.options.offsets.x,
			'top': pos.y + this.options.offsets.y
		});
	},

	locate: function(event){
		var doc = this.document.getSize();
		var scroll = this.document.getScroll();
		var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight};
		var prop = {'x': 'left', 'y': 'top'};
		for (var z in prop){
			var pos = event.page[z] + this.options.offsets[z];
			if ((pos + tip[z] - scroll[z]) > doc[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
			this.toolTip.setStyle(prop[z], pos);
		}
	},

	show: function(){
		if (this.options.timeout) this.timer = this.hide.delay(this.options.timeout, this);
		this.fireEvent('onShow', [this.toolTip]);
	},

	hide: function(){
		this.fireEvent('onHide', [this.toolTip]);
	}
});

var ImgTips = new Class({
	Extends: Tips,
	initialize: function(elements, options) {
		options = options || {};
		this.parent(elements, $merge({
			largePathAttribute: 'enlarge'
		}, options));
	},
	
	build: function(el){
		if (el.get(this.options.largePathAttribute)) {
			
			el.$attributes.myTitle = '<img src="'+el.get(this.options.largePathAttribute)+'" />';
			el.$attributes.myText = '';
			el.removeAttribute('title');
		} else {
			el.myText = false;
		}

		el.addEvent('mouseenter', function(event){
			this.start(el);
			if (!this.options.fixed) this.locate(event);
			else this.position(el);
		}.bind(this));
		if (!this.options.fixed) el.addEvent('mousemove', this.locate.bind(this));
		var end = this.end.bind(this);
		el.addEvent('mouseleave', end);
	}
});

var MG = {};
MG.ThumbScroller = new Class({
	Implements: Options,
	currentTop: 0,
	options: {
		thumbContainer: 'productThumbs',
		thumbScroller: 'thumbScroller',
		upArrow: 'scrollThumbsUp',
		downArrow: 'scrollThumbsDown'
	},
	
	initialize: function(options) {
		this.setOptions(options);
		this.container = $(this.options.thumbContainer);
		this.scroller = $(this.options.thumbScroller);
		this.scroll = new Fx.Scroll(this.container);
		$(this.options.downArrow).addEvent('click', this.scrollDown.bind(this));
		$(this.options.upArrow).addEvent('click', this.scrollUp.bind(this));
	},
	
	scrollDown: function() {
		this.scroll.toElement(this.scroller.getElements('img.imageTips')[3]);
		$(this.options.downArrow).setStyle('display','none');
		$(this.options.upArrow).setStyle('display','block');
	},
	
	scrollUp: function() {
		this.scroll.toTop();
		$(this.options.downArrow).setStyle('display','block');
		$(this.options.upArrow).setStyle('display','none');
	}
});

window.addEvent('domready', function() {
	/* SIMILAR PRODUCTS */
	if ($('similarProds')) {
		$('similarProds').getElements('ul.data').each(function(aProd) {
			aProd.setStyles({
				'display':'block',
				'opacity':'0'
			});
			aProd.getParent('li').getElements('a').set({
				events: {
					'mouseenter': function() {
						this.getParent('li').getElement('ul.data').fade(.85);
					},
					'mouseleave': function() {
						this.getParent('li').getElement('ul.data').fade('out');
					}
				}
			});
		});
	}

	/* USER OPINION SORTING */
	$$('.uoSorting ul').set('reveal', {duration: 'short'});
	$$('.uoSorting span.current').addEvent('click', function() {
		this.getParent('div').getElement('ul').get('reveal').toggle();
	});

	/* THUMB IMAGE SCROLLER */
	if ($('scrollThumbsDown')) {
		new MG.ThumbScroller();
	}

	//new ImgTips($$('.imageTips'));
	
});

function openWindow(url,x,y) {
   if (!x) { x = 480; }
   if (!y) { y = 620; }
   var popUpWin = window.open(url,'popupWin','toolbar=0,location=no,directories=0,status=0,scrollbars=yes,resizable=1,width='+x+',height='+y);
   popUpWin.focus();
};

window.addEvent('load', function(){new ImgTips($$('.imageTips'))});

var SSAHelpfulRating = new Class({
	initialize: function() {
		if ($('fullUO')) {
			if (this.isOwnOpinion()) {
				this.hideAll();
			} else if (this.hasRated()) {
				this.showThanks();
			} else {
				this.initLinks();
			}
		}
	},
	
	initLinks: function() {
		var links = $('isHelpful').getElements('a');
		links.addEvent('click', function(e) {
			e = new Event(e).stop();
			this.sendVote(e.target.get('href'));
			this.showThanks();
		}.bind(this));
		
	},
	
	sendVote: function(voteurl) {
		new Request({url:voteurl, method:'get'}).send();
	},
	
	isOwnOpinion: function() {
		return ($('fullUO').get('userName') == PageVars.get('userName'));
	},

	hasRated: function() {
		return (Browser.qs.helpvote == 'true');
	},
	
	showThanks: function() {
        $('thanksForFeedback').show();
        $('isHelpful').hide();
	},
	
	hideAll: function() {
        $('thanksForFeedback').setStyle('display','none');
        $('isHelpful').setStyle('display','none');
	}

});


window.addEvent('domready', function() {
	new Jlogger({
		ontid: PageVars.get('nodeId','string'),
		siteId: PageVars.get('siteId','string'),
		pId: PageVars.get('pageType','string'),
		tag: 'similarProdsTop',
		event: 'scrollTo',
		scrollTo: {
			top: 'similarProds'
		}
	});
});


/* HistoryBar Loader */
window.addEvent('domready', function() {
	if ([4505,4852,4507,4540,4510,4014,4566,1705,1714,1752,1764].contains(PageVars.get('pageType','number'))) {
		if (!($('historyBarCss'))) new Asset.css('http://publish.cnet.com:8100/css/rb/tron/reviews/historybar.css', {id:'historyBarCss'});
		var historyBarPath = (dbug.debug && $type(dbug.debug) == 'boolean') ? 'http://publish.cnet.com:8100/html/rb/js/tron/reviews/reviews.historybar.js' : 'http://publish.cnet.com:8100/html/rb/js/tron/reviews/reviews.historybar.js';
		if (!($('historyBarJs'))) new Asset.javascript(historyBarPath, {id:'historyBarJs'});
	}
});
