/*
 * Control.RatingBar
 * 
 * Create a click-a-star style rating bar.
 *
 * Written and maintained by Jeremy Jongsma (jeremy@jongsma.org)
 */
if (window.Control == undefined) Control = {};

Control.RatingBar = Class.create();
Control.RatingBar.prototype = {
	initialize: function (element, options) {
		this.element = $(element);
		this.stars = [];
		this.options = Object.extend({
				min: 1,
				max: 5,
				rating: 0,
				starClass: 'rating_star',
				starActiveClass: 'rating_star_a',
				waitForUpdate: false,
				onclick: Prototype.K,
				onhover: Prototype.K
			}, options || {});
		this.rating = this.options.rating;
        this.lock = false;
		this.loading = new Element('div');
		this.loading.className = 'rating_loading';
		this.animating = false;
		this.createRatingBar();
		this.element.onmouseout = function() {
			if (!this.animating) this.resetRating();
			}.bind(this)
	},
	createRatingBar: function() {
		this.element.cleanWhitespace();
		if (!this.element.childNodes.length) {
			// Not prepopulated, setup the star divs
			for (var i = this.options.min; i <= this.options.max; ++i) {
				var star = new Element('div');
				star.addClassName(this.options.starClass);
				this.element.appendChild(star);
			}	
		} else {
			// Guess current rating
			this.rating = this.options.min;
			for (var i = 1; i < this.element.childNodes.length; ++i) {
				var child = $(this.element.childNodes[i]); 
				if (child.hasClassName(this.options.starActiveClass))
					this.rating++;
			}
		}
		for (var i = 0; i < this.element.childNodes.length; ++i) {
			var child = $(this.element.childNodes[i]); 
			if (child.hasClassName(this.options.starClass)) {
				this.setStarBehavior(child, i + this.options.min)
				this.stars.push(child);
			}
		}
		if (this.options.rating)
			this.showRating(this.options.rating);
	},
	setStarBehavior: function(star, rating) {
		star.onmouseover = this.hoverRating.bind(this, rating);
		star.onclick = this.doRating.bind(this, rating);
	},
	hoverRating: function(rating) {
		rating = Math.ceil(rating);
		for (var i = 0; i < this.stars.length; ++i) {
			this.stars[i].className = this.options.starClass;
			var current = i + this.options.min;
			if (current <= rating)
				this.stars[i].addClassName(this.options.starActiveClass);
		}
		if (this.options.onhover)
			this.options.onhover(this);
	},
	doRating:  function(rating) {
		this.rating = rating;
		this.animateBar(rating, 1, 150, this.resetRating.bind(this));
		if (this.options.onclick)
			this.options.onclick(this);
	},
	animateBar: function(rating, times, delay, complete, iteration, dohover) {
		this.animating = true;
		if (!iteration) iteration = 0;
		if (iteration < times) {
			if (dohover) {
				this.hoverRating(rating);
				iteration++;
			} else {
				this.showRating(rating);
			}
			setTimeout(this.animateBar.bind(this, rating, times, delay, complete, iteration, !dohover), delay);
		} else if (iteration >= times) {
			setTimeout(function() { this.animating = false; complete(); }.bind(this), 500);
		}
	},
	showRating: function(rating) {
		for (var i = 0; i < this.stars.length; ++i) {
			this.stars[i].className = this.options.starClass;
			var current = i + this.options.min;
			if (current <= rating)
				this.stars[i].addClassName(this.options.starActiveClass);
		}
	},
	resetRating: function() {
		if (!this.animating) {
			this.showRating(this.rating);
			if (this.options.input)
				$(this.options.input).value = this.rating;
		}
	},
	setLoading: function(loading) {
		if (loading) {
			if (!this.loading.parentNode)
				this.element.appendChild(this.loading);
		} else {
			$(this.loading).remove();
		}
	}
}; 

function rateImage (imgID, url) 
{
    return function (ratingbar) 
    {
        if(ratingbar.lock == true)
            return;
            
        ratingbar.lock = true;
        var rating = ratingbar.rating;
        new Ajax.Request(url, {
            parameters:{'rating': rating, 'id':imgID}, 
            onSuccess: function (transport) 
            {
                try{
                var response = transport.responseText.evalJSON();
                if(response.errno == 1)
                {   
                    //hide ratebox
                    $('rate_word').hide();         
                    $('rate_'+imgID).hide();
                                            
                    $('rate_'+imgID+'_rating').update(response.rating); //update rating
                    $('rate_'+imgID+'_votes').update(response.votes); //update votes  
                    $('rate_'+imgID+'_score').update(response.score); //update score
                }
                }catch(e){}
            }, 
            onFailure: function (transport) 
            {   
                ratingbar.resetRating();
            }
        });
    };
}
