text: 'use strict';
  
  import Chart from 'chart.js';
  
  var helpers = Chart.helpers;
  
  // Element models are always reset when hovering in Chart.js 2.7.2 or earlier
  var hoverReset = Chart.DatasetController.prototype.removeHoverStyle.length === 2;
  
  var EXPANDO_KEY = '$colorschemes';
  
  // pluginBase snippet fixes the chartjs 3 incompatibility, and is backwards-compatible
  // by Github user gebrits (https://github.com/gebrits/chartjs-plugin-colorschemes)
  //
  // Chartjs 2 => Chart.defaults.global
  // Chartjs 3 => Chart.defaults
  const pluginBase = Chart.defaults.global || Chart.defaults;
  pluginBase.plugins.colorschemes = {
  	scheme: 'brewer.Paired12',
  	fillAlpha: 0.5,
  	reverse: false,
  	override: false
  };
  
  function getScheme(scheme) {
  	var colorschemes, matches, arr, category;
  
  	if (helpers.isArray(scheme)) {
  		return scheme;
  	} else if (typeof scheme === 'string') {
  		colorschemes = Chart.colorschemes || {};
  
  		// For backward compatibility
  		matches = scheme.match(/^(brewer\.\w+)([1-3])-(\d+)$/);
  		if (matches) {
  			scheme = matches[1] + ['One', 'Two', 'Three'][matches[2] - 1] + matches[3];
  		} else if (scheme === 'office.Office2007-2010-6') {
  			scheme = 'office.OfficeClassic6';
  		}
  
  		arr = scheme.split('.');
  		category = colorschemes[arr[0]];
  		if (category) {
  			return category[arr[1]];
  		}
  	}
  }
  
  var ColorSchemesPlugin = {
  	id: 'colorschemes',
  
  	beforeUpdate: function(chart, args, options) {
  		// Please note that in v3, the args argument was added. It was not used before it was added,
  		// so we just check if it is not actually our options object
  		if (options === undefined) {
  			options = args;
  		}
  
  		var scheme = getScheme(options.scheme);
  		var fillAlpha = options.fillAlpha;
  		var reverse = options.reverse;
  		var override = options.override;
  		var custom = options.custom;
  		var schemeClone, customResult, length, colorIndex, color;
  
  		if (scheme) {
  
  			if (typeof custom === 'function') {
  				// clone the original scheme
  				schemeClone = scheme.slice();
  
  				// Execute own custom color function
  				customResult = custom(schemeClone);
  
  				// check if we really received a filled array; otherwise we keep and use the original scheme
  				if (helpers.isArray(customResult) && customResult.length) {
  					scheme = customResult;
  				} else if (helpers.isArray(schemeClone) && schemeClone.length) {
  					scheme = schemeClone;
  				}
  			}
  
  			length = scheme.length;
  
  			// Set scheme colors
  			chart.config.data.datasets.forEach(function(dataset, datasetIndex) {
  				colorIndex = datasetIndex % length;
  				color = scheme[reverse ? length - colorIndex - 1 : colorIndex];
  
  				// Object to store which color option is set
  				dataset[EXPANDO_KEY] = {};
  
  				switch (dataset.type || chart.config.type) {
  				// For line, radar and scatter chart, borderColor and backgroundColor (50% transparent) are set
  				case 'line':
  				case 'radar':
  				case 'scatter':
  					if (typeof dataset.backgroundColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].backgroundColor = dataset.backgroundColor;
  						dataset.backgroundColor = helpers.color(color).alpha(fillAlpha).rgbString();
  					}
  					if (typeof dataset.borderColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].borderColor = dataset.borderColor;
  						dataset.borderColor = color;
  					}
  					if (typeof dataset.pointBackgroundColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].pointBackgroundColor = dataset.pointBackgroundColor;
  						dataset.pointBackgroundColor = helpers.color(color).alpha(fillAlpha).rgbString();
  					}
  					if (typeof dataset.pointBorderColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].pointBorderColor = dataset.pointBorderColor;
  						dataset.pointBorderColor = color;
  					}
  					break;
  				// For doughnut and pie chart, backgroundColor is set to an array of colors
  				case 'doughnut':
  				case 'pie':
  				case 'polarArea':
  					if (typeof dataset.backgroundColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].backgroundColor = dataset.backgroundColor;
  						dataset.backgroundColor = dataset.data.map(function(data, dataIndex) {
  							colorIndex = dataIndex % length;
  							return scheme[reverse ? length - colorIndex - 1 : colorIndex];
  						});
  					}
  					break;
  				// For bar chart backgroundColor (including fillAlpha) and borderColor are set
  				case 'bar':
  					if (typeof dataset.backgroundColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].backgroundColor = dataset.backgroundColor;
  						dataset.backgroundColor = helpers.color(color).alpha(fillAlpha).rgbString();
  					}
  					if (typeof dataset.borderColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].borderColor = dataset.borderColor;
  						dataset.borderColor = color;
  					}
  					break;
  				// For the other chart, only backgroundColor is set
  				default:
  					if (typeof dataset.backgroundColor === 'undefined' || override) {
  						dataset[EXPANDO_KEY].backgroundColor = dataset.backgroundColor;
  						dataset.backgroundColor = color;
  					}
  					break;
  				}
  			});
  		}
  	},
  
  	afterUpdate: function(chart) {
  		// Unset colors
  		chart.config.data.datasets.forEach(function(dataset) {
  			if (dataset[EXPANDO_KEY]) {
  				if (dataset[EXPANDO_KEY].hasOwnProperty('backgroundColor')) {
  					dataset.backgroundColor = dataset[EXPANDO_KEY].backgroundColor;
  				}
  				if (dataset[EXPANDO_KEY].hasOwnProperty('borderColor')) {
  					dataset.borderColor = dataset[EXPANDO_KEY].borderColor;
  				}
  				if (dataset[EXPANDO_KEY].hasOwnProperty('pointBackgroundColor')) {
  					dataset.pointBackgroundColor = dataset[EXPANDO_KEY].pointBackgroundColor;
  				}
  				if (dataset[EXPANDO_KEY].hasOwnProperty('pointBorderColor')) {
  					dataset.pointBorderColor = dataset[EXPANDO_KEY].pointBorderColor;
  				}
  				delete dataset[EXPANDO_KEY];
  			}
  		});
  	},
  
  	beforeEvent: function(chart, event, options) {
  		if (hoverReset) {
  			this.beforeUpdate(chart, options);
  		}
  	},
  
  	afterEvent: function(chart) {
  		if (hoverReset) {
  			this.afterUpdate(chart);
  		}
  	}
  };
  
  // Chart.js v3 uses "Chart.register", while v2 uses "Chart.plugins.register"
  const registerPlugin = Chart.register || Chart.plugins.register;
  registerPlugin(ColorSchemesPlugin);
  
  export default ColorSchemesPlugin;
  