/*
=============================
Undergroundhouse.net
JavaScript for rating mixes
=============================

Jason Sims (jason@symmetriq.net)

Created: 2005-02-22
Modified: 2006-07-22

*/

// ----------------------------------------------------------
// Mouseover functions for ratings/comments
// ----------------------------------------------------------

// preload "lit up" rating star icon
preload_rating = new Image(14,16); preload_rating.src = UGH.SkinImages + '/rating_star_on.gif';

function rating_mouseover(rating_image) {
	id_parts = rating_image.name.split('_');
	for (i = id_parts[1].substring(1); i > 0; i--) {
		target = id_parts[0] + '_r' + i;
		eval('document.' + target + ".src = UGH.SkinImages + '/rating_star_on.gif'");
	}
	window.status = 'Rate this mix ' + id_parts[1].substring(1) + '/5';
}

function rating_normal(rating_image) {
	id_parts = rating_image.name.split('_');
	for (i = 5; i > 0; i--) {
		target = id_parts[0] + '_r' + i;
		eval('document.' + target + ".src = UGH.SkinImages + '/rating_star_off.gif'");
	}
	window.status = '';
}


// ----------------------------------------------------------
// RPC functions
// ----------------------------------------------------------
// based on code from the following article:
// http://developer.apple.com/internet/webcontent/iframe.html
// ----------------------------------------------------------

/*
---------------------
Important note
---------------------

Instead of passing vars via the query string (as recommended in the above article), we're sticking them in a cookie. The RPC server page (which fortunately still has access to the Cookie class defined below) reads the cookie.

---------------------
Tested and working in
---------------------

Mac:
- OmniWeb 5.1
- Safari 1.2.4
- Firefox 1.0.1
- Internet Explorer 5.2.3

Windows:
- not yet tested

---------------------
Why?
---------------------

We're doing it this way to work around a strange bug in OmniWeb 5.1 that causes it to reload the RPC server page with the most recently used URL (and its query string) as soon as the IFRAME is created after the user reloads the main page that calls this script. It's not supposed to load anything into the IFRAME until we set its location object.

As a result, it was hitting the RPC server page with the previous query string, rather than the new one which reflects the rating the user clicked on this time. It was only doing this the first time after the user manually reloaded the main page. Subsequent ratings (without reloading the page first) were working fine. If the main page is loaded into a new tab, it does not exhibit the problem the first time. It only occurs when the user reloads the main page; perhaps the DOM tree in OW is not really being cleared properly on reload.
*/

// the IFrame object
var IFrameObj;

// response vars
var errorMessage;
var debugMessage;

// debug switch
var debug = false;

function setRating(mixID, rating, userID) {
	if (!document.createElement) { return true };
	var IFrameDoc;

	// let's see if we can fix this stupid omniweb thing with a cookie

	var ratingCookie = new Cookie(document, 'ughRating', null, '/');
	ratingCookie.mixID = mixID;
	ratingCookie.rating = rating;
	ratingCookie.userID = userID;
	//if (debug) ratingCookie.debug = '1';
	ratingCookie.store();

	// pass vars by query string (disabled due to OmniWeb IFRAME bug)
	//var URL = UGH.SiteURL + '/include/rpc_rating.php?MixID=' + mixID + '&Rating=' + rating + '&UserID=' + userID;

	var URL = UGH.SiteURL + '/include/rpc_rating.php';

	//alert("Going to access RPC script with this URL:\n" + URL);

	if (!IFrameObj && document.createElement) {

		if (debug) alert("We're going to create an iframe (don't have one yet)");

		// create the IFrame and assign a reference to the object to our global variable
		// IFrameObj. this will only happen the first time setRating() is called
		try {
			var tempIFrame = document.createElement('iframe');

			if (debug) alert("we just created the tempIFrame element; it hasn't been added to the DOM yet");

			tempIFrame.setAttribute('id','RSIFrame');
			tempIFrame.style.border = '0px';
			tempIFrame.style.width = '0px';
			tempIFrame.style.height = '0px';

			IFrameObj = document.body.appendChild(tempIFrame);

			if (debug) alert("we just added the tempIFrame to the DOM");

			if (document.frames) {
				// this is for IE5 Mac, because it will only allow access to the document 
				// object of the IFrame if we access it through the document.frames array
				IFrameObj = document.frames['RSIFrame'];
			}
		} catch(exception) {
			// This is for IE5 PC, which does not allow dynamic creation and manipulation
			// of an iframe object. Instead, we'll fake it up by creating our own objects.
			iframeHTML = '\<iframe id="RSIFrame" style="';
			iframeHTML += 'border:0px;';
			iframeHTML += 'width:0px;';
			iframeHTML += 'height:0px;';
			iframeHTML += '"></iframe>';
			document.body.innerHTML += iframeHTML;
			IFrameObj = new Object();
			IFrameObj.document = new Object();
			IFrameObj.document.location = new Object();
			IFrameObj.document.location.iframe = document.getElementById('RSIFrame');
			IFrameObj.document.location.replace = function(location) {
				this.iframe.src = location;
			}
		}

	}

	// something is fishy about this bit
	if (navigator.userAgent.indexOf('Gecko') != -1 && !IFrameObj.contentDocument) {
		// we have to give NS6 a fraction of a second to recognize the new IFrame
		setTimeout('doNothing()',10);
		return false;
	}

	if (IFrameObj.contentDocument) {
		if (debug) alert("We have IFrameObj.contentDocument");
		// For NS6, Safari, OmniWeb
		IFrameDoc = IFrameObj.contentDocument; 
	} else if (IFrameObj.contentWindow) {
		if (debug) alert("We have IFrameObj.contentWindow");
		// For IE5.5 and IE6
		IFrameDoc = IFrameObj.contentWindow.document;
	} else if (IFrameObj.document) {
		if (debug) alert("We have IFrameObj.document");
		// For IE5
		IFrameDoc = IFrameObj.document;
	} else {
		if (debug) alert("we don't have an iframe object!");
		return true;
	}

	IFrameDoc.location.replace(URL);
	return false;
}

function doNothing() {
	return;
}

function handleResponse(mixID, rating, result) {
	if (errorMessage) alert(errorMessage);
	if (debugMessage) alert(debugMessage);

	if (result) {
		// succeeded; update page accordingly

		// User Rating

		var stars = 5;
		var ratingHTML = '';

		// full stars
		for (var i = 0; i < rating; i++) {
			ratingHTML += '<img src="' + UGH.SkinImages + '/rating_star_on.gif" alt="" class="rating_star" />';
			stars--;
		}

		// make the rest of the stars empty (if any)
		while (stars > 0) {
			ratingHTML += '<img src="' + UGH.SkinImages + '/rating_star_off.gif" alt="" class="rating_star" />';
			stars--;
		}


		// Average Rating

		// calculate new average
		var NewAverageRating = (AverageRating[mixID] * RatingCount[mixID] + rating) / (++RatingCount[mixID]);
		// round it to one decimal place
		NewAverageRating = Math.round(NewAverageRating * 10)/10;
		// get the integer and decimal values separately
		var ARString = NewAverageRating.toString();
		var ARBits = ARString.split('.');

		var stars = 5;
		var voteword = (AverageRating[mixID] > 1 ? 'votes' : 'vote');

		var avgRatingHTML = '';

		// full stars
		for (i = 0; i < ARBits[0]; i++) {
			avgRatingHTML += '<img src="' + UGH.SkinImages + '/rating_star_full.gif" class="rating_star" />';
			stars--;
		}

		// decimals?
		if (ARBits[1]) {
			if (ARBits[1] >= 5) {
				avgRatingHTML += '<img src="' + UGH.SkinImages + '/rating_star_half.gif" class="rating_star" />';
			} else {
				avgRatingHTML += '<img src="' + UGH.SkinImages + '/rating_star_empty.gif" class="rating_star" />';
			}
			stars--;
		} else {
			ARString += '.0';
		}

		// make the rest of the stars empty (if any)
		while (stars > 0) {
			avgRatingHTML += '<img src="' + UGH.SkinImages + '/rating_star_empty.gif" class="rating_star" />';
			stars--;
		}

		// Now update the page
		document.getElementById('m' + mixID).innerHTML = ratingHTML;
		document.getElementById('ar' + mixID).innerHTML = avgRatingHTML;
		document.getElementById('ar' + mixID).title = ARString + ' (' + RatingCount[mixID] + ' ' + voteword + ')';

	}
}

//----------------------------------------------------------------------
// Cookie class
//----------------------------------------------------------------------
// taken from JavaScript: The Definitive Guide (4th Edition) (O'Reilly)
// David Flanagan
//----------------------------------------------------------------------

function Cookie(document, name, hours, path, domain, secure)
{
    // All the predefined properties of this object begin with '$'
    // to distinguish them from other properties which are the values to
    // be stored in the cookie.
    this.$document = document;
    this.$name = name;
    if (hours)
        this.$expiration = new Date((new Date()).getTime() + hours*3600000);
    else this.$expiration = null;
    if (path) this.$path = path; else this.$path = null;
    if (domain) this.$domain = domain; else this.$domain = null;
    if (secure) this.$secure = true; else this.$secure = false;
}

// This function is the store() method of the Cookie object.
Cookie.prototype.store = function () {
    // First, loop through the properties of the Cookie object and
    // put together the value of the cookie. Since cookies use the
    // equals sign and semicolons as separators, we'll use colons
    // and ampersands for the individual state variables we store 
    // within a single cookie value. Note that we escape the value
    // of each state variable, in case it contains punctuation or other
    // illegal characters.
    var cookieval = "";
    for(var prop in this) {
        // Ignore properties with names that begin with '$' and also methods.
        if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function')) 
            continue;
        if (cookieval != "") cookieval += '&';
        cookieval += prop + ':' + escape(this[prop]);
    }

    // Now that we have the value of the cookie, put together the 
    // complete cookie string, which includes the name and the various
    // attributes specified when the Cookie object was created.
    var cookie = this.$name + '=' + cookieval;
    if (this.$expiration)
        cookie += '; expires=' + this.$expiration.toGMTString();
    if (this.$path) cookie += '; path=' + this.$path;
    if (this.$domain) cookie += '; domain=' + this.$domain;
    if (this.$secure) cookie += '; secure';

    // Now store the cookie by setting the magic Document.cookie property.
    this.$document.cookie = cookie;
}

// This function is the load() method of the Cookie object.
Cookie.prototype.load = function() { 
    // First, get a list of all cookies that pertain to this document.
    // We do this by reading the magic Document.cookie property.
    var allcookies = this.$document.cookie;
    if (allcookies == "") return false;

    // Now extract just the named cookie from that list.
    var start = allcookies.indexOf(this.$name + '=');
    if (start == -1) return false;   // Cookie not defined for this page.
    start += this.$name.length + 1;  // Skip name and equals sign.
    var end = allcookies.indexOf(';', start);
    if (end == -1) end = allcookies.length;
    var cookieval = allcookies.substring(start, end);

    // Now that we've extracted the value of the named cookie, we've
    // got to break that value down into individual state variable 
    // names and values. The name/value pairs are separated from each
    // other by ampersands, and the individual names and values are
    // separated from each other by colons. We use the split method
    // to parse everything.
    var a = cookieval.split('&');    // Break it into array of name/value pairs.
    for(var i=0; i < a.length; i++)  // Break each pair into an array.
        a[i] = a[i].split(':');

    // Now that we've parsed the cookie value, set all the names and values
    // of the state variables in this Cookie object. Note that we unescape()
    // the property value, because we called escape() when we stored it.
    for(var i = 0; i < a.length; i++) {
        this[a[i][0]] = unescape(a[i][1]);
    }

    // We're done, so return the success code.
    return true;
}

// This function is the remove() method of the Cookie object.
Cookie.prototype.remove = function() {
    var cookie;
    cookie = this.$name + '=';
    if (this.$path) cookie += '; path=' + this.$path;
    if (this.$domain) cookie += '; domain=' + this.$domain;
    cookie += '; expires=Fri, 02-Jan-1970 00:00:00 GMT';

    this.$document.cookie = cookie;
}