/*****************************************************************/
/**	Pie Chart Add-On											**/
/**	By Jono Bird - I-View Pty Ltd								**/
/**	----------------------------------------------------------- **/
/**	JQuery and Raphael are both licensed under the MIT license: **/
/**	http://www.opensource.org/licenses/mit-license.php			**/
/*****************************************************************/

(function ($) {
	/*	Pie Chart Usage: 
		radius : radius of the circle (float),
		cx : center x (int OR string),
		cy : center y (int OR string),
		shadow : shadow enabled (boolean),
		scale : scale of the resize that occurs when a slice is expanded (float),
		title : title of the pie chart (string),
		question : question text (string),
		stroke : colour of the outline on the pie chart (hex),
		strokeWidth : width of the outline(int),
		strokeHighlight: colour of the stroke highlight (hex),
		strokeHLWidth: width of the stroke highlight (int),
		rainbow : automatically generates colours according to a rainbow gradient (boolean),
		gradient : set whether or not a gradient is applied (boolean),
		speed: set the speed of the animation (int)
		animation: set the type of animation (string - “>”, “<”, “<>”, “backIn”, “backOut”, “bounce”, “elastic”) */
	var defaults = {
			cx: "left",
			cy: "top",
			radius: 200.0,
			shadow: false,
			scale: 1.5,
			title: "",
			question: "",
			stroke: "#FFFFFF",
			strokeWidth: 2,
			strokeHighlight: "#666666",
			strokeHLWidth: 3,
			rainbow: true,
			gradient: true,
			speed: 350,
			animation: "bounce"
		},
		radians = Math.PI/180, // Used for conversion from degrees to radians
		isIE = (navigator.userAgent.toLowerCase().indexOf('msie') != -1);
	
	/* === Helper Functions and Objects === */
	// Calculate the total of all the values
	var calcTotals = function(data) {
		var total = 0;
		
		for(var i in data) {
			if(data[i][2] !== undefined)
			{
				total += data[i][2];
			}
		};
		
		// Return total and subtotals in an array
		return total;
	};
	
	// Divide a Hex number
	var divideHex = function(hex, divisor) {
		var result = (Math.round(parseInt(hex,16)/divisor)).toString(16);
		
		if(result == 0) { 
			return "00";
		} else {
			return result;
		}
	}
	
	// Divide a Colour
	var divideColour = function(colour, divisor) {
		var r,g,b;
			
		r = divideHex(colour.substr(1,2), 2);
		g = divideHex(colour.substr(3,2), 2);
		b = divideHex(colour.substr(5,2), 2);
		
		return "#" + r + g + b;
	}
	
	// Decimal to Hex conversion
	var decToHex = function(value) {
		if(value == 0) {
			return "00";
		} else {
			return value.toString(16);
		}
	}
	
	// Hex to Decimal conversion
	var hexToDec = function(hex) {
		return parseInt(hex,16);
	}
	
	// Automatically get a rainbow colour
	var getColour = function(index, max) {
		var r,g,b,
		thisColour = Math.floor(1530*index/max),
		thisOffset = thisColour%255;
		
		// Calculate the r,g,b values according to the value of index relative to max.
		r = (thisColour<255 || thisColour>=1275)*255 + (thisColour>=255 && thisColour<510)*(255-thisOffset) + (thisColour>=1020 && thisColour<1275)*thisOffset;
		g = (thisColour<255)*thisOffset + (thisColour>=255 && thisColour<765)*255 + (thisColour>=765 && thisColour<1020)*(255-thisOffset);
		b = (thisColour>=510 && thisColour<765)*thisOffset + (thisColour>=765 && thisColour<1275)*255 + (thisColour>=1275)*(255-thisOffset);
		
		return '#' + decToHex(r) + decToHex(g) + decToHex(b);
	}
	
	// Render the actual slice
	var renderSlice = function(canvas, cx, cy, radius, colour, gradient, stroke, strokeWidth, start, end) {
		/*	Calculate the extremeties of the current slice, ie. two lines which are rotated by the appropriate start and end angles, 
			and connect them with an arc */
		var x1 = cx + radius * Math.cos(-start*radians),
			x2 = cx + radius * Math.cos(-end*radians),
			y1 = cy + radius * Math.sin(-start*radians),
			y2 = cy + radius * Math.sin(-end*radians);
		
		var newSlice = canvas.path(["M", cx, cy, "L", x1, y1, "A", radius, radius, 0, +(end - start > 180), 0, x2, y2, "z"]);
		newSlice.attr({ stroke: stroke, "stroke-width" : strokeWidth });
		newSlice.attr({ fill: colour });
		
		if(gradient) {
			newSlice.attr({ gradient: "90-" + divideColour(colour, 2) + "-" + colour });
		}
		
		return newSlice;
	}
	
	// Slice Object
	function Slice(canvas, container, slice, settings, value, total, start, end, index, length) {
		// Create the parent slice
		var $this = this;
		var subSlice = slice[3];
		var colour;
		
		// Generate colour automatically
		if(settings.rainbow) {
			colour = getColour(index, length);
			//colour = "hsb(" + Math.floor(100*index/length) + "%,100%,100%)";
		} else {
			colour = slice[1];
		}
		
		$this.parent = renderSlice(canvas, settings.cx, settings.cy, settings.radius, colour, settings.gradient, settings.stroke, settings.strokeWidth, start, end);
		$this.children = canvas.set();
		$this.hasSubSlice = (subSlice !== undefined) && (subSlice.length > 0);
		$this.index = $('tr.primary-entry', container).length; // Keep track of the current slice's index
		
		// Add parent to the key
		$('.key table', container).append('<tr class="primary-entry"><td class="color-cell"><div class="color"></div></td><td class="label"><span>' + slice[0] + '</span></td><td class="value"><span>' + Math.floor((value/total)*1000)/10 +'%</span></td></tr>');
		$('tr:last td:first div', container).css('background-color', colour);
		
		// Is the slice expanded
		$this.isExpanded = function() {
			// Cheeky way of checking if the slice is already expanded
			return ($this.parent.scale().toString().indexOf(settings.scale) != -1);
		}
		
		// Render sub slices
		if($this.hasSubSlice) {
			var totalAngle = (end - start),
			currStart = start,
			currEnd,
			currOpacity,
			opacityIncrement;
			
			// Add white fill, with incremental opacity (to distinguish between subslices)
			opacityIncrement = (0.5/subSlice.length);
			currOpacity = 0.25;
			
			// Traverse the array
			for(var i in subSlice) {
				if(subSlice[i][0] && subSlice[i][1])
				{
					var percent = (subSlice[i][1]/value);
					currEnd = currStart + percent*totalAngle;
					var newSubSlice = renderSlice(canvas, settings.cx, settings.cy, settings.radius*settings.scale, "#FFFFFF", false, 
						settings.stroke, settings.strokeWidth, currStart, currEnd);
					newSubSlice.attr("fill-opacity", currOpacity);
					
					// Insert subslice to the key table
					$('tr:last', container).after('<tr class="sub-entry sub-row[' + $this.index + ']"><td class="color-cell"><div class="color"><div class="overlay"></div></div></td><td class="label"><span>' + subSlice[i][0] + '</span></td><td class="value"><span>' + (Math.floor(percent*(value/total)*1000)/10) +'%</span></td></tr>');
					$('tr:last div.color', container).css('background-color', colour);
					$('tr:last div.overlay', container).css('opacity', currOpacity);
					$('tr:last', container).hide();
					
					// Increment variables and push new slice onto the set of children
					currOpacity += opacityIncrement;
					currStart = currEnd;
					$this.children.push(newSubSlice);
				}
			}
			$this.children.hide();
		}
		
		// Assign click event
		$this.parent.click(function() {
			$this.toggle();
		});
		
		// Minimise a subSliceSet
		if($this.hasSubSlice) {
			$this.children.click(function () {
				$this.toggle();
			})
		}
		
		// Assign Hover events
		$this.parent.mouseover(function() {
			$('tr.primary-entry:eq(' + $this.index + ')', container).addClass('hoverSlice');
			if(!isIE) {
				$this.parent.attr({ stroke: settings.strokeHighlight, "stroke-width": settings.strokeHLWidth });
				$this.parent.toFront();
			}
		}).mouseout(function() {
			if(!($this.hasSubSlice && $this.isExpanded())) {
				$('tr.hoverSlice').removeClass('hoverSlice');
			}
			$this.parent.attr({ stroke: settings.stroke, "stroke-width": settings.strokeWidth });
		});
		
		$this.children.mouseover(function() {
			if(!isIE) {
				this.attr({ stroke: settings.strokeHighlight, "stroke-width": settings.strokeHLWidth });
				this.toFront();
			}
			$('tr.primary-entry:eq(' + $this.index + ')', container).addClass('hoverSlice');
		}).mouseout(function() {
			$('tr.hoverSlice').removeClass('hoverSlice');
			$this.children.attr({ stroke: settings.stroke, "stroke-width": settings.strokeWidth });
		});
		
		// Toggle slice function
		$this.toggle = function() {
			if($this.isExpanded()) { // Already Expanded
				if($this.hasSubSlice) { 
					$('tr.sub-row\\[' + $this.index + '\\]', container).hide();
					$this.children.hide(); 
				} 
				$this.parent.animate({scale: [1, 1, settings.cx, settings.cy]}, settings.speed, settings.animation);
			} else { // Unexpanded
				$this.parent.animate({scale: [settings.scale, settings.scale, settings.cx, settings.cy]}, settings.speed, settings.animation, 
					function() {
						if($this.hasSubSlice) {
							$this.parent.attr({ stroke: settings.stroke, "stroke-width": settings.strokeWidth });
							
							if(!isIE) {
								$this.children.toFront();
							}
							
							$('tr.sub-row\\[' + $this.index + '\\]', container).show();
							$this.children.show();
						}
					});
			}
		}
		return $this;
	}
	
	/* === Pie Chart Specific Functions === */
	$pc = $.fn.piechart = function(data, options) {
		$pc.container = this;
		$pc.data = data; // Store the array of data
		$pc.settings = $.extend({}, defaults, options); // Load settings
		
		$pc.total = calcTotals(data); // Calculate the total value
		$pc.slices = [];
		
		// Calculate the size of the radius plus scaling plus stroke width
		var offset = $pc.settings.radius + (($pc.settings.scale > 1) * ($pc.settings.scale - 1) * $pc.settings.radius) + $pc.settings.strokeWidth;
		
		// Deal with special center attributes
		if($pc.settings.cx == "center") {
			$pc.settings.cx = this.width()/2;
		} else if($pc.settings.cx == "left") {
			$pc.settings.cx = offset; 
		}
		
		if($pc.settings.cy == "center") {
			$pc.settings.cy = this.height()/2;
			//alert(this.height()/2);
		} else if($pc.settings.cy == "top") {
			$pc.settings.cy = offset; 
		}
		
		// Question Container
		if($pc.settings.question != "") {
			var question_div = $pc.container.append("<div class='question'>" + $pc.settings.question +"</div>");
			question_div.after("<div class='clear'></div>");
		}
		
		// Pie Chart Container
		var currID = 'pc_' + this.attr('id');
		$pc.container.append("<div id='" + currID + "' class='pc_container'></div>");
		$('div#' + currID, $pc.container).css("float","left");
		
		// Create the canvas
		$pc.paper = Raphael(currID, ($pc.settings.cx + offset), ($pc.settings.cy + offset)); // Create the canvas on which to render the Pie Chart
		
		var currStart = 0,
		currEnd = 0;
		
		// Create the Key
		this.append("<div class='key'><p class='title'>" + $pc.settings.title + "</p><table width='100%'></table><p class='total'>Total surveyed: <span>" + $pc.total + "</span></p></div>");
		this.css('position','relative');
		$('.key', this).css({'float': 'left', 'margin-top': (($pc.settings.scale>1)*($pc.settings.scale - 1)*$pc.settings.radius)});
		$('.key', this).after("<div class='clear'></div>");
		
		// Hide Title if non-existent
		if($pc.settings.title == "") {
			$('p.title').hide();
		}
		
		// Create the pie chart (as a collection of slices)
		$.each($pc.data, function(i, value)
		{
			currEnd = currStart + ($pc.data[i][2]/$pc.total)*360; // Calculate the end angle of the current slice
			
			var slice = $pc.createSlice($pc.data[i], $pc.data[i][2], currStart, currEnd, i, $pc.data.length);
			$pc.slices.push(slice);
			
			currStart = currEnd; // Keep track of the starting angle
		});
		
	}
	
	// Based heavily on the Pie Chart demonstration on the Raphael website
	$pc.createSlice = function(slice, value, start, end, index, length) {
		var mySlice = new Slice($pc.paper, $pc.container, slice, $pc.settings, value, $pc.total, start, end, index, length);
		return mySlice;
	}
}(jQuery));


/* Add on by Owen for login loading */
$(document).ready(function()
{
	var hash = $(location).attr('hash');
	if(hash === "#login")
	{
		//alert(hash);
		$("a#loginShadowBox").click();
	}
	
	/* Added to pass Affiliate information through if they click off the page */
	
	var parms = $(location).attr("search").slice(1).split("&");
	var urlAppendString = "";
	var AcceptableParms = ["a","s1","s2","s3","pid","rid","tid"];
	$.each(parms, function(index, value)
	{
		if(value !== "")
		{
			var pair = value.split("=");
			if(pair.length === 2)
			{
				if(AcceptableParms.o_contains(pair[0].toLowerCase()))
				{
					urlAppendString += value + "&";
				}
			}
		}
	});
	
	if(urlAppendString[urlAppendString.length -1] === "&")
	{
		urlAppendString = urlAppendString.slice(0,urlAppendString.length - 1);
	}
	if(urlAppendString.length > 0)
	{	
		$("a").each(function()
		{
			var thisUrlAppendString;
			if($(this).attr("href").indexOf("?") !== -1)
			{
				thisUrlAppendString = "&" + urlAppendString
			}else
			{
				thisUrlAppendString = "?" + urlAppendString;
			}
			
			$(this).attr("href", $(this).attr("href") + thisUrlAppendString);
		});
	}
});

/*Extension made by owen*/
Array.prototype.o_contains = function(term)
{
	var i;
	var found = false;
	for(i = 0; i < this.length && !found; i++)
	{
		if(this[i] === term)
		{
			found = true;
		}
	}
	
	return found;
}
