text: "use strict";
  
  module.exports = function (Chart) {
  
  	var helpers = Chart.helpers;
  
  	Chart.defaults.radar = {
  		scale: {
  			type: "radialLinear"
  		},
  		elements: {
  			line: {
  				tension: 0 // no bezier in radar
  			}
  		}
  	};
  
  	Chart.controllers.radar = Chart.DatasetController.extend({
  
  		datasetElementType: Chart.elements.Line,
  
  		dataElementType: Chart.elements.Point,
  
  		linkScales: helpers.noop,
  
  		addElementAndReset: function (index) {
  			Chart.DatasetController.prototype.addElementAndReset.call(this, index);
  
  			// Make sure bezier control points are updated
  			this.updateBezierControlPoints();
  		},
  
  		update: function update(reset) {
  			var meta = this.getMeta();
  			var line = meta.dataset;
  			var points = meta.data;
  			var custom = line.custom || {};
  			var dataset = this.getDataset();
  			var lineElementOptions = this.chart.options.elements.line;
  			var scale = this.chart.scale;
  
  			// Compatibility: If the properties are defined with only the old name, use those values
  			if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
  				dataset.lineTension = dataset.tension;
  			}
  
  			helpers.extend(meta.dataset, {
  				// Utility
  				_datasetIndex: this.index,
  				// Data
  				_children: points,
  				_loop: true,
  				// Model
  				_model: {
  					// Appearance
  					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
  					backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
  					borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
  					borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
  					fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
  					borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
  					borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
  					borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
  					borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
  
  					// Scale
  					scaleTop: scale.top,
  					scaleBottom: scale.bottom,
  					scaleZero: scale.getBasePosition()
  				}
  			});
  
  			meta.dataset.pivot();
  
  			// Update Points
  			helpers.each(points, function (point, index) {
  				this.updateElement(point, index, reset);
  			}, this);
  
  
  			// Update bezier control points
  			this.updateBezierControlPoints();
  		},
  		updateElement: function (point, index, reset) {
  			var custom = point.custom || {};
  			var dataset = this.getDataset();
  			var scale = this.chart.scale;
  			var pointElementOptions = this.chart.options.elements.point;
  			var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
  
  			helpers.extend(point, {
  				// Utility
  				_datasetIndex: this.index,
  				_index: index,
  				_scale: scale,
  
  				// Desired view properties
  				_model: {
  					x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
  					y: reset ? scale.yCenter : pointPosition.y,
  
  					// Appearance
  					tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, this.chart.options.elements.line.tension),
  					radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
  					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor),
  					borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
  					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
  					pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
  
  					// Tooltip
  					hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius)
  				}
  			});
  
  			point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
  		},
  		updateBezierControlPoints: function () {
  			var chartArea = this.chart.chartArea;
  			var meta = this.getMeta();
  
  			helpers.each(meta.data, function (point, index) {
  				var model = point._model;
  				var controlPoints = helpers.splineCurve(
  					helpers.previousItem(meta.data, index, true)._model,
  					model,
  					helpers.nextItem(meta.data, index, true)._model,
  					model.tension
  				);
  
  				// Prevent the bezier going outside of the bounds of the graph
  				model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
  				model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
  
  				model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
  				model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
  
  				// Now pivot the point for animation
  				point.pivot();
  			}, this);
  		},
  
  		draw: function (ease) {
  			var meta = this.getMeta();
  			var easingDecimal = ease || 1;
  
  			// Transition Point Locations
  			helpers.each(meta.data, function (point, index) {
  				point.transition(easingDecimal);
  			});
  
  			// Transition and Draw the line
  			meta.dataset.transition(easingDecimal).draw();
  
  			// Draw the points
  			helpers.each(meta.data, function (point) {
  				point.draw();
  			});
  		},
  
  		setHoverStyle: function (point) {
  			// Point
  			var dataset = this.chart.data.datasets[point._datasetIndex];
  			var custom = point.custom || {};
  			var index = point._index;
  			var model = point._model;
  
  			model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
  			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
  			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
  			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
  		},
  
  		removeHoverStyle: function (point) {
  			var dataset = this.chart.data.datasets[point._datasetIndex];
  			var custom = point.custom || {};
  			var index = point._index;
  			var model = point._model;
  			var pointElementOptions = this.chart.options.elements.point;
  
  			model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius);
  			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor);
  			model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
  			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
  		}
  	});
  };
  