var Rating = new Class({
	
	Implements: Options,
	
	options: {
		url: null,
		elements: '.rating',
		percent: true,
		steps: 5
	},
	
	initialize: function(options) {
		
		this.setOptions(options);
		$$(this.options.elements).each(function(el) {
			el.id = el.getAttribute('id');
			el.wrapper = el.getElement('.wrapper');
			el.active = el.getElement('.rating-active');
			if (el.active == null) {
				el.active = el.getElement('.rating-rated');
			}
			el.rated = el.getElement('.rating-rated');
			el.rtext = el.getElement('.rating-text');
			el.width = el.wrapper.getStyle('width').toInt();
			el.startRate = el.active.getStyle('width').toInt();
			if (this.options.percent == true) {
				el.startRate *= el.width / 100;
			}
			el.percent = el.width / this.options.steps;
			
			if (this.options.url == null || el.rated != null) {
				this.disable(el);
				return;
			}
			
			el.rateMove = function(e) {
				el.active.setStyle('width', this.calcPos(e, el) * el.percent);
			}.bind(this);
			
			el.wrapper.addEvent('mouseover', function(e) {
				el.wrapper.addEvent('mousemove', el.rateMove);
			});
			
			el.wrapper.addEvent('mouseout', function(e) {
				el.removeEvent(el.rateMove);
				el.active.tween('width', el.startRate);
			});
			
			el.wrapper.addEvent('click', function(e) {
				$(document.body).getElements('div').each(function(item, index) {
					if (item.match('div[id=' + el.id + ']')) {
						item.wrapper = item.getElement('.wrapper');
						item.wrapper.removeEvents();
					}
				});
				var rating = this.calcPos(e, el);
				if (this.options.url != null) {
					var id = el.id.split('-');
					var request = new Request.JSON({
						url: this.options.url,
						onComplete: el.updateText.bind(this)
					}).post({
						id: id[1],
						type: id[0],
						rating: rating
					});
				}
			}.bind(this));
			
			el.updateText = function(result) {
				this.setStartRate(result.rating, el);
				$(document.body).getElements('div').each(function(item, index) {
					if (item.match('div[id=' + el.id + ']')) {
						item.rtext = item.getElement('.rating-text');
						if (item.rtext != null) {
							item.rtext.innerHTML = result.rating;
						}
					}
				});
			};
			
		}.bind(this));
	},
	
	disable: function(el) {
		el.wrapper.setStyle('cursor', 'default');
		if (Browser.Engine.trident == true) {
			el.active.set('class', 'rating-rated');
		} else {
			el.active.set('morph', {duration: 0});
			el.active.morph(this.options.elements + ' .rating-rated');
		}
	},
	
	calcPos: function(e, el) {
		var pos = e.client.x - el.wrapper.getPosition().x;
		pos = Math.floor(pos / el.percent) + 1;
		return pos.round(2);
	},
	
	setStartRate: function(rate, el) {
		this.options.percent = true;
		el.startRate = rate / this.options.steps;
		el.startRate *= el.width;
		$(document.body).getElements('div').each(function(item, index) {
			if (item.match('div[id=' + el.id + ']')) {
				item.getElement('.wrapper').removeEvents();
				var fx = new Fx.Tween(item.getElement('.rating-active'), {link: 'chain', duration: 'short'});
				fx.start('width', el.startRate).chain(function() {
					item.wrapper = item.getElement('.wrapper');
					item.active = item.getElement('.rating-active');
					this.disable(item);
				}.bind(this));
			}
		}.bind(this));
	}
});
window.addEvent('domready', function(e) {
	var rating = new Rating({url: '/rating/add'});
});