// JavaScript Document
/*************************************************
Star Rating System
First Version: 21 November, 2006
Second Version: 17 May, 2007
Author: Ritesh Agrawal (http://php.scripts.psu.edu/rja171/widgets/rating.php)
Inspiration: Will Stuckey's star rating system (http://sandbox.wilstuckey.com/jquery-ratings/)
Half-Star Addition: Karl Swedberg
Demonstration: http://examples.learningjquery.com/rating/
Usage: $('#rating').rating('url-to-post.php', {maxvalue:5, curvalue:0});

arguments
url : required -- post changes to 
options
    increment : 1, // value to increment by
	maxvalue: number of stars
	curvalue: number of selected stars
	

************************************************/

jQuery.fn.rating = function(url, options) {
	
	if(url == null) return;
	
	var settings = {
		url : url, // post changes to 
		increment : 1, // value to increment by
		maxvalue  : 5,   // max number of stars
		curvalue  : 0,    // number of selected stars
		cancelbutton: true, //with cancel button
		disabled: false, //is disabled
		sendmethod: 'GET', //send method GET or POST
		unload: null, //on stars click function
		onload: null, //ajax send callback function
		datatype: "xml" //ajax send callback function
  };
	
  if(options) {
    jQuery.extend(settings, options);
  };
  jQuery.extend(settings, {cancel: (settings.cancelbutton && settings.maxvalue > 1) ? true : false});
   
  var container = jQuery(this);
	
  jQuery.extend(container, {
    averageRating: settings.curvalue,
    url: settings.url
  });
  settings.increment = (settings.increment < .75) ? .5 : 1;
  var s = 0;
	for(var i= 0; i <= settings.maxvalue ; i++){
    if (i == 0) {
	    if(settings.cancel == true){
        var div = '<div class="cancel"><a href="#0" title="Cancel Rating">Cancel Rating</a></div>';
        container.append(div);
      }
    } else {
      var $div = $('<div class="star"></div>')
        .append('<a href="#'+i+'" title="Give it '+i+'/'+settings.maxvalue+'">'+i+'</a>')
        .appendTo(container);
      if (settings.increment == .5) {
        if (s%2) {
          $div.addClass('star-left');
        } else {
          $div.addClass('star-right');
        }
      }
    }
    i=i-1+settings.increment;
    s++;
  }
	
  var stars = jQuery(container).children('.star');
  var cancel = jQuery(container).children('.cancel');
	
  stars
    .mouseover(function(){
		if(!settings.disabled) {
		  event.drain();
		  event.fill(this);
		}
    })
    .mouseout(function(){
		if(!settings.disabled) {
		  event.drain();
		  event.reset();
		}
    })
    .focus(function(){
		if(!settings.disabled) {
		  event.drain();
		  event.fill(this);
		}
    })
    .blur(function(){
		if(!settings.disabled) {
		  event.drain();
		  event.reset();
		}
    });

  stars.click(function(){
	if(!settings.disabled) {
		if(typeof settings.unload == 'function')
			settings.unload(this);

		if(settings.cancel == true){
			settings.curvalue = (stars.index(this) * settings.increment) + settings.increment;
			send(this);
			return false;
		} else if (settings.maxvalue >= 1) {
			settings.curvalue = (settings.curvalue == 0) ? 1 : 0;
			$(this).toggleClass('on');
			send(this);
			return false;
		}
	}
	return true;
  });

  // cancel button events
	if(cancel){
		cancel
		.mouseover(function(){
			if(!settings.disabled) {
			  event.drain();
			  jQuery(this).addClass('on');
			}
		})
		.mouseout(function(){
			if(!settings.disabled) {
			  event.reset();
			  jQuery(this).removeClass('on');
			}
		})
		.focus(function(){
			if(!settings.disabled) {
			  event.drain();
			  jQuery(this).addClass('on');
			}
		})
		.blur(function(){
			if(!settings.disabled) {
			  event.reset();
			  jQuery(this).removeClass('on');
			}
		});
		  
		// click events.
		cancel.click(function(){
			if(!settings.disabled) {
				if(typeof settings.unload == 'function')
					settings.unload(this);

				event.drain();
				settings.curvalue = 0;
				send(this);
			}
			return false;
		});
	}
        
	var event = {
		fill: function(el){ // fill to the current mouse position.
			var index = stars.index(el) + 1;
			stars
				.children('a').css('width', '100%').end()
				.slice(0,index).addClass('hover').end();
		},
		drain: function() { // drain all the stars.
			stars
				.filter('.on').removeClass('on').end()
				.filter('.hover').removeClass('hover').end();
		},
		reset: function(){ // Reset the stars to the default index.
			stars.slice(0,settings.curvalue / settings.increment).addClass('on').end();
		}
	};    
	event.reset();
	
	var send = function(starObj) {
		if(settings.url) {
			var method = settings.sendmethod
			if(method.toString().toUpperCase() == 'GET')
				jQuery.get(container.url, {
					"rating": jQuery(starObj).children('a')[0].href.split('#')[1] 
				}, settings.onload, settings.datatype);
			else
				jQuery.post(container.url, {
					"rating": jQuery(starObj).children('a')[0].href.split('#')[1] 
				}, settings.onload);
		}
	};

	return(this);	

};

StarRating = function() {
	var me = this;

	this.options = {
		divtotalrateid : "rate1",
		divuserrateid : "rate2",
		datatype : "xml", //xml or text or json
		urlselect : 'getartrating.php?',
		urlinsert : 'setartrating.php?',
		urlupdate : 'setartrating.php?',
		answered : false,
		unload: null,
		onload: null,
		flag: 0
	};
	
	this.init = function() {
		if(me.options.urlselect.toString().indexOf('?') == -1) me.options.urlselect += '?';
		if(me.options.urlinsert.toString().indexOf('?') == -1) me.options.urlinsert += '?';
		if(me.options.urlupdate.toString().indexOf('?') == -1) me.options.urlupdate += '?';
		
		me.refresh();
	}

	this.update = function(obj, status) {
		var status = me.getDataType(obj, "STATUS");
		var userrate = me.getDataType(obj, "USERRATE");
		
		me.refresh(userrate);
	}
	
	this.refresh = function(userrate) {
		if(me.options.urlselect) {
			if(userrate)
				jQuery.get(me.options.urlselect + '&rating=' + userrate, {}, me.createStarRating, me.options.datatype);		
			else
				jQuery.get(me.options.urlselect, {}, me.createStarRating, me.options.datatype);
		}
	}
	
	this.createStarRating = function(obj, status) {
		var total = me.getDataType(obj, "TOTAL");
		var rate = me.getDataType(obj, "RATE");
		var userrate = me.getDataType(obj, "USERRATE");
		//alert(total+'--'+rate+'--'+userrate);
		
		$('#' + me.options.divtotalrateid).empty();
		$('#' + me.options.divuserrateid).empty();
	
		var url = me.options.answered ? me.options.urlupdate + '&oldrating=' + userrate + '&update=' + me.options.answered + '&' : me.options.urlinsert;
		me.options.answered = true;

		$('#' + me.options.divtotalrateid).rating(false, {maxvalue:5, curvalue:rate, increment:1, disabled:true, cancelbutton:false});
		$('#' + me.options.divuserrateid).rating(url, {maxvalue:5, curvalue:userrate, increment:1, cancelbutton:false, unload: me.options.unload, onload: me.update, datatype: me.options.datatype});

		if(typeof me.options.onload == 'function')
			me.options.onload(me, {total:total, rate:rate, userrate:userrate});
		
		me.options.flag = me.options.flag == 0 ? 1 : 2;//1 para init, 2 para update, 3 nao deve chamar funcao onload.
	}
	
	this.getDataType = function(obj, type) {
		var data = 0;
		var datatype = me.options.datatype ? me.options.datatype.toString().toLowerCase() : '';


		if(datatype == "xml") {
			var xmlDoc = obj;
			if(xmlDoc && xmlDoc.childNodes) {
				for(var i = 0; i < xmlDoc.childNodes.length; ++i) {
					if(xmlDoc.childNodes[i].nodeName.toUpperCase() == 'RESULTADO') {
						result = xmlDoc.childNodes[i];
						for(var j = 0; j < result.childNodes.length; ++j) {
							if(result.childNodes[j].nodeName.toUpperCase() == type && result.childNodes[j].firstChild) {
								data = result.childNodes[j].firstChild.data;
								break;
							}
						}
						break;
					}
				}
			}
		}
		else if(datatype == "text") {
			var result = obj;
			if(result && result.length > 0) {
				eval("var reg = /<" + type + ">([0-9\\.]*)<\\/" + type + ">/i;");
				var ar = reg.exec(result);
				if(ar && ar.length > 0)
					data = ar[1];
			}
		}
		else if(datatype == "json") {
			data = eval("obj.RESULTADO." + type);
		}

		return data;
	}
};

var StarRatingObjs = new Array();
