(function(){

	"use strict";



	var root = this,

		Chart = root.Chart,

		//Cache a local reference to Chart.helpers

		helpers = Chart.helpers;



	var defaultConfig = {

		//Boolean - Show a backdrop to the scale label

		scaleShowLabelBackdrop : true,



		//String - The colour of the label backdrop

		scaleBackdropColor : "rgba(255,255,255,0.75)",



		// Boolean - Whether the scale should begin at zero

		scaleBeginAtZero : true,



		//Number - The backdrop padding above & below the label in pixels

		scaleBackdropPaddingY : 2,



		//Number - The backdrop padding to the side of the label in pixels

		scaleBackdropPaddingX : 2,



		//Boolean - Show line for each value in the scale

		scaleShowLine : true,



		//Boolean - Stroke a line around each segment in the chart

		segmentShowStroke : true,



		//String - The colour of the stroke on each segement.

		segmentStrokeColor : "#fff",



		//Number - The width of the stroke value in pixels

		segmentStrokeWidth : 2,



		//Number - Amount of animation steps

		animationSteps : 100,



		//String - Animation easing effect.

		animationEasing : "easeOutBounce",



		//Boolean - Whether to animate the rotation of the chart

		animateRotate : true,



		//Boolean - Whether to animate scaling the chart from the centre

		animateScale : false,



		//String - A legend template

		legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"

	};





	Chart.Type.extend({

		//Passing in a name registers this chart in the Chart namespace

		name: "PolarArea",

		//Providing a defaults will also register the deafults in the chart namespace

		defaults : defaultConfig,

		//Initialize is fired when the chart is initialized - Data is passed in as a parameter

		//Config is automatically merged by the core of Chart.js, and is available at this.options

		initialize:  function(data){

			this.segments = [];

			//Declare segment class as a chart instance specific class, so it can share props for this instance

			this.SegmentArc = Chart.Arc.extend({

				showStroke : this.options.segmentShowStroke,

				strokeWidth : this.options.segmentStrokeWidth,

				strokeColor : this.options.segmentStrokeColor,

				ctx : this.chart.ctx,

				innerRadius : 0,

				x : this.chart.width/2,

				y : this.chart.height/2

			});

			this.scale = new Chart.RadialScale({

				display: this.options.showScale,

				fontStyle: this.options.scaleFontStyle,

				fontSize: this.options.scaleFontSize,

				fontFamily: this.options.scaleFontFamily,

				fontColor: this.options.scaleFontColor,

				showLabels: this.options.scaleShowLabels,

				showLabelBackdrop: this.options.scaleShowLabelBackdrop,

				backdropColor: this.options.scaleBackdropColor,

				backdropPaddingY : this.options.scaleBackdropPaddingY,

				backdropPaddingX: this.options.scaleBackdropPaddingX,

				lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,

				lineColor: this.options.scaleLineColor,

				lineArc: true,

				width: this.chart.width,

				height: this.chart.height,

				xCenter: this.chart.width/2,

				yCenter: this.chart.height/2,

				ctx : this.chart.ctx,

				templateString: this.options.scaleLabel,

				valuesCount: data.length

			});



			this.updateScaleRange(data);



			this.scale.update();



			helpers.each(data,function(segment,index){

				this.addData(segment,index,true);

			},this);



			//Set up tooltip events on the chart

			if (this.options.showTooltips){

				helpers.bindEvents(this, this.options.tooltipEvents, function(evt){

					var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];

					helpers.each(this.segments,function(segment){

						segment.restore(["fillColor"]);

					});

					helpers.each(activeSegments,function(activeSegment){

						activeSegment.fillColor = activeSegment.highlightColor;

					});

					this.showTooltip(activeSegments);

				});

			}



			this.render();

		},

		getSegmentsAtEvent : function(e){

			var segmentsArray = [];



			var location = helpers.getRelativePosition(e);



			helpers.each(this.segments,function(segment){

				if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);

			},this);

			return segmentsArray;

		},

		addData : function(segment, atIndex, silent){

			var index = atIndex || this.segments.length;



			this.segments.splice(index, 0, new this.SegmentArc({

				fillColor: segment.color,

				highlightColor: segment.highlight || segment.color,

				label: segment.label,

				value: segment.value,

				outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),

				circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),

				startAngle: Math.PI * 1.5

			}));

			if (!silent){

				this.reflow();

				this.update();

			}

		},

		removeData: function(atIndex){

			var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;

			this.segments.splice(indexToDelete, 1);

			this.reflow();

			this.update();

		},

		calculateTotal: function(data){

			this.total = 0;

			helpers.each(data,function(segment){

				this.total += segment.value;

			},this);

			this.scale.valuesCount = this.segments.length;

		},

		updateScaleRange: function(datapoints){

			var valuesArray = [];

			helpers.each(datapoints,function(segment){

				valuesArray.push(segment.value);

			});



			var scaleSizes = (this.options.scaleOverride) ?

				{

					steps: this.options.scaleSteps,

					stepValue: this.options.scaleStepWidth,

					min: this.options.scaleStartValue,

					max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)

				} :

				helpers.calculateScaleRange(

					valuesArray,

					helpers.min([this.chart.width, this.chart.height])/2,

					this.options.scaleFontSize,

					this.options.scaleBeginAtZero,

					this.options.scaleIntegersOnly

				);



			helpers.extend(

				this.scale,

				scaleSizes,

				{

					size: helpers.min([this.chart.width, this.chart.height]),

					xCenter: this.chart.width/2,

					yCenter: this.chart.height/2

				}

			);



		},

		update : function(){

			this.calculateTotal(this.segments);



			helpers.each(this.segments,function(segment){

				segment.save();

			});

			

			this.reflow();

			this.render();

		},

		reflow : function(){

			helpers.extend(this.SegmentArc.prototype,{

				x : this.chart.width/2,

				y : this.chart.height/2

			});

			this.updateScaleRange(this.segments);

			this.scale.update();



			helpers.extend(this.scale,{

				xCenter: this.chart.width/2,

				yCenter: this.chart.height/2

			});



			helpers.each(this.segments, function(segment){

				segment.update({

					outerRadius : this.scale.calculateCenterOffset(segment.value)

				});

			}, this);



		},

		draw : function(ease){

			var easingDecimal = ease || 1;

			//Clear & draw the canvas

			this.clear();

			helpers.each(this.segments,function(segment, index){

				segment.transition({

					circumference : this.scale.getCircumference(),

					outerRadius : this.scale.calculateCenterOffset(segment.value)

				},easingDecimal);



				segment.endAngle = segment.startAngle + segment.circumference;



				// If we've removed the first segment we need to set the first one to

				// start at the top.

				if (index === 0){

					segment.startAngle = Math.PI * 1.5;

				}



				//Check to see if it's the last segment, if not get the next and update the start angle

				if (index < this.segments.length - 1){

					this.segments[index+1].startAngle = segment.endAngle;

				}

				segment.draw();

			}, this);

			this.scale.draw();

		}

	});



}).call(this);