RatingManager = Class.create({

	initialize: function(element) {
		this.initializeDefaults();
		this.initializeElement(element);
	},
	
	initializeDefaults: function() {
		this.starWidth	= 17;
		this.starCount	= 5;
		this.starHeight	= 20;
		this.maxWidth	= this.starWidth * this.starCount;
	},
	
	initializeElement: function(element) {
		this.element = $(element);
		if (this.element)
		{
			this.url 			= this.element.readAttribute("url");
			this.videoId 		= this.element.readAttribute("videoId");
			this.votesText		= this.element.readAttribute("votesText");
			this.voteCount		= parseInt(this.element.readAttribute("voteCount"));
			this.voteElement	= $(this.element.readAttribute("voteElement"));
			this.alreadyVoted	= this.element.readAttribute("alreadyVotedText");
			this.element.setStyle(
				{
					width	: this.maxWidth + "px", 
					height	: this.starHeight + "px"
				}
			);
			var pos = this.element.positionedOffset();
			var dim	= this.element.getDimensions();
			this.r	= {
				l:pos.left, 
				t:pos.top, 
				r:pos.left + dim.width, 
				b:pos.top + dim.height
			};
			
			this.mouseMoveHandler 	= this.onMouseMove.bindAsEventListener(this);
			this.mouseDownHandler	= this.onMouseDown.bindAsEventListener(this);
			Event.observe(document, "mousemove", 	this.mouseMoveHandler);
			Event.observe(document, "mousedown", 	this.mouseDownHandler);
			
			this.stars = new Stars(this, this.element.down());
		}
	},
	
	isIntersect: function(p) {
		return p.x >= this.r.l && p.x <= this.r.r && p.y >= this.r.t && p.y <= this.r.b;
	},
	
	onMouseMove: function(e) {
		var p = Event.pointer(e);
		if (this.stars)
		{
			if (this.isIntersect(p))
			{
				this.stars.setValueFromPos(p.x - this.r.l);
			} else
			{
				this.stars.resetValue();
			}
		}
	},
	
	onMouseDown: function(e) {
		if (this.stars && this.isIntersect(Event.pointer(e)))
		{
			this.pushVoteToServer(this.stars.value * this.starCount / 100);
		}
	},
	
	stop: function() {
		Event.stopObserving(document, "mousemove", 	this.mouseMoveHandler);
		Event.stopObserving(document, "mousedown", 	this.mouseDownHandler);
	},
	
	pushVoteToServer: function(valueToPush) {
		if (this.url)
		{
			this.stop();
			new Ajax.Request(this.url, {
				method		: 'get',
				parameters	: {videoId:this.videoId,vote:valueToPush}, 
				onComplete 	: this.voteRespond.bind(this)
			});
		}
	},
	
	voteRespond: function(transport) {
		var response = transport.responseText.evalJSON();
		if (response.status == "voted")
		{
			this.voteElement.update((this.voteCount + 1) + " " + this.votesText);
			this.stars.setValue((response.fld_total_value / response.fld_total_votes) * 20);
		} else
		{
			this.stars.resetValue();
			alert(this.alreadyVoted);
		}
	}
});

Stars = Class.create({

	initialize: function(owner, element) {
 		this.owner = owner;
		this.initializeElement(element);
		this.realizeSelection(element.down());
	},
	
	initializeElement: function(element) {
		this.element = element;
		this.element.setStyle(
			{
				width	: this.owner.maxWidth + "px", 
				height	: this.owner.starHeight + "px"
			}
		);
	},
	
	realizeSelection: function(selection) {
		this.selection 		= selection;
		this.value			= this.getValue();
		this.originalValue 	= this.value;

		this.selection.setStyle(
			{
				width	: this.getValueWidth(),
				height	: this.owner.starHeight + "px",
				display	: "block"
			}
		);
	},
	
	getValue: function() {
		var value	= this.selection.readAttribute("title");
		value		= value ? parseInt(value) : 0;
		if (value > 100)
		{
			value = 100;
		} else if (value < 0)
		{
			value = 0;
		}
		return value;
	},
	
	getValueWidth: function() {
		return parseInt((this.value * this.owner.maxWidth) / 100) + "px";
	},
	
	resetWidth: function() {
		this.selection.setStyle(
			{
				width : this.getValueWidth()
			}
		);
	},
	
	setValueFromPos: function(x) {
		this.value 	= ((x * 100) / this.owner.maxWidth);
		this.resetWidth();
	},
	
	resetValue: function() {
		this.value = this.originalValue;
		this.resetWidth();
	},
	
	setValue: function(value) {
		this.value			= value;
		this.originalValue 	= this.value;
		this.resetWidth();
	}
});

function windowLoadedStarRating()
{
	new RatingManager("rating");
}

(function() {
	Event.observe(window, "load", windowLoadedStarRating);
})();

