requirejs.config({
	paths: {
		d3: "scripts/d3.v3-3.4.1.min",
		nvd3: "scripts/nv.d3-1.7.1.min"
	},
	shim: {
		nvd3: {
		  exports: 'nv',
		  deps: ['d3.global']
		}
	}
});
// workaround for nvd3 using global d3
define("d3.global", ["d3"], function(_) {
	d3 = _;
});

define(['scripts/knockout-3.3.0','scripts/ACTComponent.js','scripts/css','nvd3'], function(ko, ACTComponent, css) {

	css(['css/nv.d3.min']);

	function ChartComponentViewModel(params, element) {
		var self = this;

		self.base = new ACTComponent($(element), params);
		self.element = element;

		self.title = ko.observable("");
		self.type = null;
		self.showLegend = false;
		self.xLabel = "";
		self.yLabel = "";
		self.y2Label = "";
		self.xTickFormat = "";
		self.yTickFormat = "";
		self.y2TickFormat = "";

		self.chart = null;

		self.updateGroups = function() {
			if (self.type == "PIE") {
				// values aren't formatted like other chart for pie chart
				var values = [];
				for (var i = 0; i < self.groups.length; i++) {
					for (var j = 0; j < self.groups[i].values.length; j++) {
						values.push(self.groups[i].values[j]);
					}
				}
				self.groups = values;
			}

			d3.select(element).select('#chart svg')
				.datum(self.groups)
				.transition().duration(0)  // remove animations
				.call(self.chart);
		}

		self.createChart = function() {
			if (!params.baseModel.isVisible())
				return;

			nv.addGraph(function() {
				if (self.type == "LINE") {
					self.chart = nv.models.lineChart()
						.margin({left:50, right:50})
						.showXAxis(true)
						.showYAxis(true)
						.useInteractiveGuideline(true)
						.tooltips(false)
						.showLegend(self.showLegend);
				} else if (self.type == "BAR") {
					self.chart = nv.models.discreteBarChart()
						.showXAxis(true)
						.showYAxis(true)
						.tooltips(false)
						.showValues(true);
				} else if (self.type == "PIE") {
					self.chart = nv.models.pieChart()
						.x(function(d) { return d.label; })
						.y(function(d) { return d.value; })
						.tooltips(true)
						.showLegend(self.showLegend)
						.showLabels(true);
				} else if (self.type == "LINE_BAR") {
					self.chart = nv.models.linePlusBarChart()
						.tooltips(false)
						.showLegend(self.showLegend)
						.focusEnable(false);
				} else if (self.type == "BUBBLE") {
					self.chart = nv.models.scatterChart()
						.margin({left:50, right:50})
						.tooltips(false)
						.showDistX(true)
						.showLegend(self.showLegend)
						.showDistY(true);
				} else {
					return null;
				}

				var xAxis = self.chart.xAxis;
				if (xAxis) {
					xAxis.axisLabel(self.xLabel);
					if (self.xTickFormat != null && self.yTickFormat != "")
						xAxis.tickFormat(d3.format(self.xTickFormat));
				}

				var yAxis = self.chart.yAxis || self.chart.y1Axis;
				if (yAxis) {
					yAxis.axisLabel(self.YLabel);
					yAxis.axisLabelDistance(-15);
					if (self.yTickFormat != null && self.yTickFormat != "")
						yAxis.tickFormat(d3.format(self.yTickFormat));
				}

				var y2Axis = self.chart.y2Axis;
				if (y2Axis) {
					y2Axis.axisLabel(self.y2Label);
					if (self.xTickFormat != null && self.yTickFormat != "")
						y2Axis.tickFormat(d3.format(self.y2TickFormat));
				}

				self.updateGroups();
				return self.chart;
			});
		}

		self.Clear = function() {
			if (self.chart != null) {
				d3.select(element).select('.nvd3').remove();
				self.chart = null;
			}
		}

		self.base.onMessage = function(name, obj) {
			if (name == "Clear")
				self.Clear();
		}

		self.base.onRefresh = function(obj) {
			self.title(obj.Title);
			self.groups = obj.Groups;
			self.showLegend = obj.ShowLegend;
			self.xLabel = obj.XLabel;
			self.yLabel = obj.YLabel;
			self.y2Label = obj.Y2Label;
			self.xTickFormat = obj.XTickFormat;
			self.yTickFormat = obj.YTickFormat;
			self.y2TickFormat = obj.Y2TickFormat;

			if (self.chart == null || self.type != obj.Type) {
				self.Clear();
				self.type = obj.Type;
				self.createChart();
			} else {
				self.updateGroups();
			}
		}

		var updateSVGSize = function() {
			var titleHeight = $(element).find(".title")[0].clientHeight;
			var allHeight = $(element).height();
			$(element).find("svg")[0].style.height = allHeight - titleHeight;
		}
		updateSVGSize();

		params.baseModel.showFunctions.push(function() {
			// only create when visible because of issue with svg and not visible element
			if (self.chart == null)
				self.createChart();
		});

		self.resizeFunction = function(height,width) {
			updateSVGSize();
			if (self.chart)
				self.chart.update();
		}
		params.baseModel.resizeFunctions[params.baseModel.resizeFunctions.length] = self.resizeFunction;

		self.base.initialize();
		params.ready(true);
	}

	return {
		createViewModel: function(params, componentInfo) {
			return new ChartComponentViewModel(params, componentInfo.element);
		}
	};

});

