function ratingsManager( ) {

	this.LAST_GET_REQUEST_TIME = 0;
	this.LAST_GET_CALL_MADE_TIME = 0;
	this.DEADTIME_WAIT_MSEC = 50;
	this.REPEAT_WAIT_MSEC = 500;

	this.url = "/webservice/json/ratings";
	
	this.onGet = function( rcid, value ) { };

	this.ratingsQueue = new Array();
	this.ratingsMapping = new Array();

	this.sendMessage = function(url, content, callback){
		var wrappedCallback = function (requestObj, emptyData) {
			if(requestObj.status == 200){
				var text = requestObj.responseText;
				if (text.substring(0,2) == "[{"){
					var data = eval(text);
				} else {
					var data = eval('('+text+')');
				}
				callback(data);
			} else {
				var data;
				data.exception.message="Bad response from ajax request. "
				data.exception.code=requestObj.status
				data.hasError=true;
				callback(data);
			}
		}

		new Ajax.Request(url,{
			onSuccess: wrappedCallback,
			method: 'get',
			parameters: content.toQueryString()
		});
	}

	this.setRating = function ( rcid, rating ) {
		if(rating == this.getRatingValue(rcid)){
			rating = 0;
		}
		this.ratingsMapping[rcid.toLowerCase()] = rating;
		this.onGet( rcid, rating );
		var content = $H({ rcid:rcid, rating:rating, action:"set-rating" });
		this.sendMessage( rhapsodyUrlJson + this.url, content, this.dataCallback );
	}

	this.getRatingValue = function( rcid ) {
		if( this.ratingsMapping[rcid.toLowerCase()] ) {
			return this.ratingsMapping[rcid.toLowerCase()];
		}
	}

	this.getRating = function( rcid ) {
		if( this.ratingsMapping[rcid.toLowerCase()] ) {
			this.onGet( rcid, this.ratingsMapping[rcid.toLowerCase()] );
		}
		else {
			this.LAST_GET_REQUEST_TIME = new Date().valueOf();
			this.ratingsQueue.push(rcid);
		}
	}

	this.getRatingObjects = function( startIndex, endIndex, type, callbackMethod ) {
		var content = $H({ action:"get-objects", startIndex:startIndex, endIndex:endIndex, type:type });
		this.sendMessage( rhapsodyUrlJson + this.url, content, callbackMethod );
	}

	this.getSummary = function( callbackMethod ) {
		var content = $H({ action:"get-summary" });
		this.sendMessage( rhapsodyUrlJson + this.url, content, callbackMethod );
	}

	this.getNotYetRated = function( callbackMethod ) {
		var content = $H({ action:"recent-not-yet-rated" });
		this.sendMessage( rhapsodyUrlJson + this.url, content, callbackMethod );
	}

	this.getForgotten = function( callbackMethod ) {
		var content = $H({ action:"have-you-forgotten" });
		this.sendMessage( rhapsodyUrlJson + this.url, content, callbackMethod );
	}
	
	this.getRandomPlaylist = function( maxNum, include5, include4, include3, include2, include1, includeNeg1, weight, rcid, callbackMethod ) {
		this.getRandomPlaylistForUser( maxNum, include5, include4, include3, include2, include1, includeNeg1, weight, rcid, null, callbackMethod );
	}
	
	this.getRandomPlaylistForUser = function( maxNum, include5, include4, include3, include2, include1, includeNeg1, weight, rcid, rhapuserid, callbackMethod ) {
		var artistValue = rcid.toLowerCase().indexOf("art.")==0 ? rcid : "";
		var genreValue = rcid.toLowerCase().indexOf("g.")==0 ? rcid : "";
		
		var content = $H({ action:"get-random-playlist", maxnum:maxNum, include5:include5, 
							include4:include4, include3:include3, include2:include2,
							include1:include1, includeNeg1:includeNeg1, weight:weight, 
							artist:artistValue, genre:genreValue, rhapuserid:rhapuserid });
		this.sendMessage( rhapsodyUrlJson + this.url, content, callbackMethod );
	}
	
	this.dataCallback = function( data ) {
		for( var i=0 ; i<data.length ; i++ ) {
			ratingsMgr.ratingsMapping[ data[i].rcid.toLowerCase() ] = data[i].value;
			ratingsMgr.onGet( data[i].rcid, data[i].value );
		}
	}
	
	this.queueWatcherThread = function() {
		var RIGHTNOW = new Date().valueOf();
	
		if( this.ratingsQueue.length 
				&& RIGHTNOW-this.LAST_GET_REQUEST_TIME > this.DEADTIME_WAIT_MSEC 
				&& RIGHTNOW-this.LAST_GET_CALL_MADE_TIME > this.REPEAT_WAIT_MSEC ) {

			this.LAST_GET_CALL_MADE_TIME = RIGHTNOW;
			var content = $H({ rcid:this.ratingsQueue, action:"get-ratings" });
			this.ratingsQueue = new Array();
			this.sendMessage( rhapsodyUrlJson + this.url, content, this.dataCallback );
		}
		
		setTimeout( "ratingsMgr.queueWatcherThread()", 50 );
	}
	
	this.queueWatcherThread();
}

var ratingsMgr = new ratingsManager();

/* begin rating widget */
	function canRate(){
		try{
			if(getAccountType() == "RHAPSODY_PREMIUM_USER"){
				return true;
			}
		}catch(e){}
		
		try{
			if((typeof rhapsodyMember != 'undefined' ) && rhapsodyMember.isLoggedIn && rhapsodyMember.isRadioPremiumUser){
				return true;
			}
		}catch(e){}
		return false;
	}
	
	function showRhap25Msg(){
		var isRhap25;
		try{
			if((typeof rhapsodyMember != 'undefined' ) && rhapsodyMember.isLoggedIn && !rhapsodyMember.isRadioPremiumUser && !rhapsodyMember.isAnonymousUser){
				return true;
			}
		}catch(e){}
		
		try{
			if(getAccountType() == "RHAPSODY_FREE_USER"){
				return true;
			}
		}catch(e){}
		return false;
	}
	
	ratingsMgr.onGet = function( rcid, value ) {
		noclickSetRating(rcid,value);
	}

	var defaultRatingClass="ratings_0";
	
	function mouseoverRating(uid,pos,iconsize){
		var theVisRatingClass = "ratings_"+pos+"_"+iconsize;
		document.getElementById(uid).className = theVisRatingClass;
	}
	
	function mouseoutRating(rcid){
		if(canRate()){
			noclickSetRating(rcid,ratingsMgr.getRatingValue(rcid));
		}else{
			noclickSetRating(rcid,0);
		}
	}
	
	function mouseclickRating(rcid,rating,uid){
		if(canRate()){
			noclickSetRating(rcid,rating);
			ratingsMgr.setRating(rcid,rating);
		}else{
			noclickSetRating(rcid,0);
			if( RhapsodyDom.bodyLoaded ) renderRatingUpgrade(rcid,uid);	
			else RhapsodyUtility.addLoadEvent( function() { renderRatingUpgrade(rcid,uid); } );
		}
	}
	
	function noclickSetRating(rcid,rating){
		if(!rating){                     
			rating = 0;
		}
		if(numWidgetsPerRcid[rcid] > 0){
			for(var i = 1; i < numWidgetsPerRcid[rcid]+1; i++){
				var eachRcid = rcid+"."+i;
				if(document.getElementById(eachRcid)){
					document.getElementById(eachRcid).className = "ratings_"+rating+"_"+getSizeByRcid(eachRcid);
				}
			}
		}else{
			document.getElementById(rcid).className = "ratings_"+rating+"_"+getSizeByRcid(rcid);
		}
	}
	
	var numWidgetsPerRcid = new Array();
	function getNextWidgetId( rcid ) {
		if( numWidgetsPerRcid[rcid] ) { 
			numWidgetsPerRcid[rcid]++;
		}else{
			numWidgetsPerRcid[rcid] = 1;
		}
		return rcid+"."+numWidgetsPerRcid[rcid];
	}
	
	var rcidSizeMap = new Array();
	function mapRcidsAndSizes(rcid,iconsize){
		var eachMapItem = rcid+":"+iconsize;
		rcidSizeMap.push(eachMapItem);
	}
	
	function getSizeByRcid(rcid){
		for(var i = 0; i < rcidSizeMap.length; i++){
			var sizeMap = rcidSizeMap[i];
			var theRcid = sizeMap.split(":")[0];
			var theSize = sizeMap.split(":")[1];
			if(rcid == theRcid){
				return theSize;
			}
		}
	}
	
	function getRateType(rcid){
		var type = rcid.substring(0,rcid.indexOf(".")).toLowerCase();
		switch(type){
			case "art":{
				return "artist";
			}case "alb":{
				return "album";
			}case "tra":{
				return "track";
			}case "g":{
				return "genre";
			}
		}
		
	}
	
	function openRatingsUpgradePage(theUrl) {
		var newWin;
		newWin = window.open( theUrl, "_blank", "toolbar=yes,location=yes,directories=yes,resizable=yes,scrollbars=yes" );
		newWin.focus();
		destroyRatingUpgrade();
	}
	
	var ratingsDialog;
	function destroyRatingUpgrade(){
		if(ratingsDialog){
			with( ratingsDialog ){
				toggleMeddlesomeElements();
			}
			ratingsDialog.removeHoldingElement();
			ratingsDialog = null;
		}
	}
	
	  
	function renderRatingUpgrade(rcid,uid){
		destroyRatingUpgrade();
		var baseElement = document.getElementById(uid);
		var messageDiv = document.getElementById("ru_"+uid);
		var upgradeMsg = 'To rate music, please <a href="#" onclick="javascript:signInOut(\'signin\'); destroyRatingUpgrade();">sign in</a> to Rhapsody.<br/><br/>Don\'t have Rhapsody? <a href="javascript:openRatingsUpgradePage(\''+upsellURL+'?src=rcom_rat\');">Try it free</a>.<br/>';
		if(showRhap25Msg()){
			upgradeMsg = 'To rate music, <a href="javascript:openRatingsUpgradePage(\''+upsellURL+'?src=rcom_rat25\');">upgrade for a free trial</a>.<br/>';
		}
		
		var messageDivHTML = '<div class="ratingsUpgrade" id="ru_'+uid+'">'+
		'<strong>Sign in or Upgrade</strong><br/><br/>'+
		upgradeMsg+
		'<a href="#" style="position:absolute; bottom:10px; right:10px;" onclick="destroyRatingUpgrade(); return false;" class="s notBold">close</a></div>';
		
		
		if(DialogBox){
			ratingsDialog = new DialogBox( { spawnFrom:baseElement, spawnFromOffset:[0,0], htmlContent:messageDivHTML} );
			with( ratingsDialog ){
				toggleMeddlesomeElements();
			}
			ratingsDialog.adjustForBleed({alignBottomOnFlip: true});
			ratingsDialog.show();
		}
	}
	
	function getRatingWidget(rcid,iconsize){
		if(!iconsize){ iconsize = "big"; }
		rcid = rcid.replace(rcid.charAt(0),rcid.charAt(0).toUpperCase());
		var uniqueid = getNextWidgetId(rcid);
		mapRcidsAndSizes(uniqueid,iconsize);
		var ratingWidgetHTML='<div style="text-decoration:none;" id="'+uniqueid+'" class="ratings_0_'+iconsize+'" title="Rate this '+getRateType(rcid)+'">'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'-1\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'-1\',\''+uniqueid+'\'); return false;"></a>'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'1\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'1\',\''+uniqueid+'\'); return false;"></a>'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'2\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'2\',\''+uniqueid+'\'); return false;"></a>'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'3\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'3\',\''+uniqueid+'\'); return false;"</a>'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'4\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'4\',\''+uniqueid+'\'); return false;"></a>'+
			'<a href="#" class="ratingslistitem_'+iconsize+'" onmouseover="mouseoverRating(\''+uniqueid+'\',\'5\',\''+iconsize+'\')" onmouseout="mouseoutRating(\''+rcid+'\')" onclick="mouseclickRating(\''+rcid+'\',\'5\',\''+uniqueid+'\'); return false;"></a>'+	
			'</div>';
		if(canRate()){
			setTimeout("ratingsMgr.getRating('"+rcid+"')",500);
		}
		return ratingWidgetHTML;
	}
	
/* end rating widget */


