/**
 * AJAXy Star-rating Script For Yahoo! UI Library (YUI)
 *
 * By Ville Säävuori <Ville@Unessa.net>
 * http://www.unessa.net/en/hoyci/projects/yui-star-rating/
 * 
 * Based loosely on Wil Stuckeys jQuery Star Rating Plugin:
 * http://sandbox.wilstuckey.com/jquery-ratings/
 * 
 * Respecting the original licence, this script is also
 * dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Version history
 * 0.1 - First version (2007-04-06)
 */

function Rating(){};

Rating.prototype = {
	rowIndex: "",
	recordKey: "", //key of the assosiated row in the datatable
	name: "",
	ratingdiv:null,
	stardiv:null,
	notifytext:null,
	average:null,
	submitted:null,
	starElements:null, //array of star elements, used inside reset_star because the stars are added to document (YUI datatable) only after all the rows are processed. So immediate call to document.getElementById will not return anything

    init: function(index, key, average_score, n) {
		this.rowIndex = index;
		this.recordKey = key;
		this.name = n;
		if (average_score.indexOf(".") <0)
			average_score += ".0";
        this.average = average_score.split(".");
        this.submitted = false;
		this.starElements = [];
		return this.make_stardiv(rowIndex);
    },

    make_stardiv: function() {
        /* Replaces original form with the star images */

		this.ratingdiv = document.createElement('div');
		YAHOO.util.Dom.addClass(this.stardiv, 'ratingdiv'); 
        
		this.stardiv = document.createElement('div');
		YAHOO.util.Dom.addClass(this.stardiv, 'rating');        

        // make the stars
        for (var i=1; i<=5; i++) {
            // first, make a div and then an a-element in it
            var star = document.createElement('div');
            star.id = 'star_' + this.rowIndex + '_' + i;
            var a = document.createElement('a');
            a.href = '#' + i;
            a.innerHTML = i;
            YAHOO.util.Dom.addClass(star, 'star');
            star.appendChild(a);
            this.stardiv.appendChild(star);

            // add needed listeners to every star
			//setting true in the last parameter to define the scope of the callback functions
			//from help -> If true, the obj passed in becomes the execution scope of the listener. If an object, this object becomes the execution scope.
            YAHOO.util.Event.addListener(star, 'mouseover', this.hover_star, {p:this, star:i}, true);
            YAHOO.util.Event.addListener(star, 'mouseout', this.reset_stars, this, true);
            YAHOO.util.Event.addListener(star, 'click', this.submit_rating, {p:this, star:i}, true);

			//store it for further reference
			this.starElements[i] = star;
        }        
        this.ratingdiv.appendChild(this.stardiv);

        // add the statustext div and hide it
        this.notifytext = document.createElement('div');
        YAHOO.util.Dom.addClass(this.notifytext, 'notifytext');
        YAHOO.util.Dom.setStyle(this.notifytext, 'opacity', 0);
        this.ratingdiv.appendChild(this.notifytext);
		
		//this should be added as a child to the YUI data table cell
		return this.ratingdiv;
    },
    
    hover_star: function(e, obj) {
        /* hovers the selected star plus every star before it */
        for (var i=1; i<= this.star; i++) {
            var star = YAHOO.util.Dom.get('star_' + this.p.rowIndex + '_' + i);
            var a = star.firstChild;
            YAHOO.util.Dom.addClass(star, 'hover');
            YAHOO.util.Dom.setStyle(a, 'width', '100%');
        }
    },
    
    reset_stars: function() {
        /* Resets the status of each star */
        
        // if form is not submitted, the number of stars on depends on the 
        // given average value
		var stars_on, last_star_width;
        if (this.submitted == false) {
            stars_on = this.average[0];
            if (this.average[1] >= 0)
			{
                stars_on = parseInt(this.average[0]) + 1;
				last_star_width = this.average[1] + '0%';
			}
        } else {
            // if the form is submitted, then submitted number stays on
            stars_on = this.submitted;
            last_star_width = '100%';
        }

        // cycle trought 1..5 stars
        for (var i=1; i<=5; i++) {
            var star = this.starElements[i];
            var a = star.firstChild;
            
            // first, reset all stars
            YAHOO.util.Dom.removeClass(star, 'hover');
            YAHOO.util.Dom.removeClass(star, 'on');

            // for every star that should be on, turn them on
            if (i<=stars_on && !YAHOO.util.Dom.hasClass(star, 'on'))
                YAHOO.util.Dom.addClass(star, 'on');

            // and for the last one, set width if needed
            if (i == stars_on)
                YAHOO.util.Dom.setStyle(a, 'width', last_star_width);
        }
    },
    
    submit_rating: function(e, obj) {
        // If the form has not been submitted yet 
        // and submission is not in progress
		num = obj.star;
        if (this.p.submitted == false) {
            this.p.submitted = num;
            // After the form is submitted, instead of old average, show
            // submitted number of stars selected
            this.p.average = [num, 0];
            
            // change the statustext div and show it
            this.p.notifytext.innerHTML = 'Rating is being saved.';
            var notify_display = new YAHOO.util.Anim(this.p.notifytext, { opacity: { to: 1 } }, 0.25, YAHOO.util.Easing.easeIn);
            notify_display.animate();      
			
			//update the data in datatable structure
			var oRecord = YAHOO.example.EnhanceFromMarkup.myDataTable.getRecord(this.p.recordKey);
			oRecord.setData('ratingScore', num + ''); //preserve the type (string) for proper sorting
			oRecord.setData('ratingCount', (oRecord.getData('ratingCount') + 1) + '');

			//Get the row id of the spreadsheet form datatable
			rowKey = YAHOO.example.EnhanceFromMarkup.myDataTable.getRecord(this.p.recordKey).getData()['rowKey'];
            
            // change the rating-value for the form and submit the form
            //this.p.ratingform.elements[0].value = num;
            //Get the unique id (name) from the datatable
			//addGrid.myDataTable.getRecord.recordKey
            var c = YAHOO.util.Connect.asyncRequest('POST', "rate.php", {
						scope:this.p, 
						success:this.p.submitSuccess,
						failure:this.p.submitFailure
					}, 
					"row=" + rowKey + "&rating=" + num, this.p);
        }
    },
    
    submitSuccess: function(o) {
		try
		{
			json = YAHOO.lang.JSON.parse(o.responseText);	
		}
		catch (x) {
			alert(o.responseText);
			this.notifytext.innerHTML = 'Rating not saved.';
			return;
		}

		if (json.status)
		{
			// release the form to normal status and change the statustext
			this.submitted = false;
			this.notifytext.innerHTML = 'Rating saved.';
		}
		else
			this.notifytext.innerHTML = 'Rating not saved.';
		
	},
	submitFailure: function(o) { // we shouldn't ever go down this path.
		alert('Error: ' + o.status + " " + o.statusText );
	}
};

generateRatingForms = function() {
	rowIndex = 0;
	while(YAHOO.util.Dom.get('rating_' + rowIndex))
	{
		rating = new Rating();
		rating.init(rowIndex, "");
		rowIndex++;
	};
};

//YAHOO.util.Event.addListener(window, 'load', generateRatingForms);