var Rate = Class.create({
	//expects an array of elements that are the 'stars', in order
	initialize: function(ratings) {
		this.ratings = ratings;
		this.options = Object.extend({
			onActivate: function() {},
			activeClass: false,
			onDeactivate: function() {},
			onRate: function() {},
			ratedClass: false,
			callbackOnInit: false,
			rating: 0
		}, arguments[1] || {});
		this.setupRatings();
		this.rate(this.options.rating, {callback: this.options.callbackOnInit});
	},

	setupRatings: function() {
		for (var i=0;i<this.ratings.length;i++) {
			Event.observe(this.ratings[i], 'mouseover', this.hover.bind(this));
			Event.observe(this.ratings[i], 'mouseout', this.unhover.bind(this));
			Event.observe(this.ratings[i], 'click', this.rateFromClick.bind(this));
		}
	},

	hover: function(event) {
		this.activate({rating: this.getRatingFromElement(Event.element(event))});
	},

	unhover: function(event) {
		this.activate({rated: true});
	},
	
	rateFromClick: function(event) {
		this.rate(this.getRatingFromElement(Event.element(event)));
	},

	rate: function(rating) {
		var options = Object.extend({
			callback: true
		}, arguments[1] || {});
		this.currentRating = rating;
		this.activate({rated: true});
		if (options.callback) {
			this.options.onRate(this.currentRating);
		}
	},
	
	activate: function(options) {
		options = Object.extend({
			rating: false,
			rated: false
		}, options || {});
		rating = options.rating || this.currentRating;
		this.deactivate();
		for (var i=0;i<rating;i++) {
			if ((this.ratings[i]) && (this.options.activeClass || (options.rated && this.options.ratedClass))) {
				$(this.ratings[i]).addClassName((options.rated && this.options.ratedClass) ? this.options.ratedClass:this.options.activeClass);
			}
			this.options.onActivate(this.ratings[i]);
		}
	},

	deactivate: function() {
		for (var i=0;i<this.ratings.length;i++) {
			if (this.options.activeClass) {
				$(this.ratings[i]).removeClassName(this.options.activeClass);
			}
			if (this.options.ratedClass) {
				$(this.ratings[i]).removeClassName(this.options.ratedClass);
			}
			this.options.onDeactivate(this.ratings[i]);
		}
	},

	getRatingFromElement: function(elem) {
		for (var i=0;i<this.ratings.length;i++) {
			if (elem == this.ratings[i] || elem.descendantOf(this.ratings[i])) {
				return i+1;
			}
		}
		return 0;
	}
});
