(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
	typeof define === 'function' && define.amd ? define(['exports'], factory) :
	(factory((global.SPECIFICITY = {})));
}(this, (function (exports) { 'use strict';

	// Calculate the specificity for a selector by dividing it into simple selectors and counting them
	var calculate = function(input) {
		var selectors,
			selector,
			i,
			len,
			results = [];

		// Separate input by commas
		selectors = input.split(',');

		for (i = 0, len = selectors.length; i < len; i += 1) {
			selector = selectors[i];
			if (selector.length > 0) {
				results.push(calculateSingle(selector));
			}
		}

		return results;
	};

	/**
	 * Calculates the specificity of CSS selectors
	 * http://www.w3.org/TR/css3-selectors/#specificity
	 *
	 * Returns an object with the following properties:
	 *  - selector: the input
	 *  - specificity: e.g. 0,1,0,0
	 *  - parts: array with details about each part of the selector that counts towards the specificity
	 *  - specificityArray: e.g. [0, 1, 0, 0]
	 */
	var calculateSingle = function(input) {
		var selector = input,
			findMatch,
			typeCount = {
				'a': 0,
				'b': 0,
				'c': 0
			},
			parts = [],
			// The following regular expressions assume that selectors matching the preceding regular expressions have been removed
			attributeRegex = /(\[[^\]]+\])/g,
			idRegex = /(#[^\#\s\+>~\.\[:\)]+)/g,
			classRegex = /(\.[^\s\+>~\.\[:\)]+)/g,
			pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi,
			// A regex for pseudo classes with brackets - :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-type(), :lang()
			// The negation psuedo class (:not) is filtered out because specificity is calculated on its argument
			// :global and :local are filtered out - they look like psuedo classes but are an identifier for CSS Modules
			pseudoClassWithBracketsRegex = /(:(?!not|global|local)[\w-]+\([^\)]*\))/gi,
			// A regex for other pseudo classes, which don't have brackets
			pseudoClassRegex = /(:(?!not|global|local)[^\s\+>~\.\[:]+)/g,
			elementRegex = /([^\s\+>~\.\[:]+)/g;

		// Find matches for a regular expression in a string and push their details to parts
		// Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
		findMatch = function(regex, type) {
			var matches, i, len, match, index, length;
			if (regex.test(selector)) {
				matches = selector.match(regex);
				for (i = 0, len = matches.length; i < len; i += 1) {
					typeCount[type] += 1;
					match = matches[i];
					index = selector.indexOf(match);
					length = match.length;
					parts.push({
						selector: input.substr(index, length),
						type: type,
						index: index,
						length: length
					});
					// Replace this simple selector with whitespace so it won't be counted in further simple selectors
					selector = selector.replace(match, Array(length + 1).join(' '));
				}
			}
		};

		// Replace escaped characters with plain text, using the "A" character
		// https://www.w3.org/TR/CSS21/syndata.html#characters
		(function() {
			var replaceWithPlainText = function(regex) {
					var matches, i, len, match;
					if (regex.test(selector)) {
						matches = selector.match(regex);
						for (i = 0, len = matches.length; i < len; i += 1) {
							match = matches[i];
							selector = selector.replace(match, Array(match.length + 1).join('A'));
						}
					}
				},
				// Matches a backslash followed by six hexadecimal digits followed by an optional single whitespace character
				escapeHexadecimalRegex = /\\[0-9A-Fa-f]{6}\s?/g,
				// Matches a backslash followed by fewer than six hexadecimal digits followed by a mandatory single whitespace character
				escapeHexadecimalRegex2 = /\\[0-9A-Fa-f]{1,5}\s/g,
				// Matches a backslash followed by any character
				escapeSpecialCharacter = /\\./g;

			replaceWithPlainText(escapeHexadecimalRegex);
			replaceWithPlainText(escapeHexadecimalRegex2);
			replaceWithPlainText(escapeSpecialCharacter);
		}());

		// Remove anything after a left brace in case a user has pasted in a rule, not just a selector
		(function() {
			var regex = /{[^]*/gm,
				matches, i, len, match;
			if (regex.test(selector)) {
				matches = selector.match(regex);
				for (i = 0, len = matches.length; i < len; i += 1) {
					match = matches[i];
					selector = selector.replace(match, Array(match.length + 1).join(' '));
				}
			}
		}());

		// Add attribute selectors to parts collection (type b)
		findMatch(attributeRegex, 'b');

		// Add ID selectors to parts collection (type a)
		findMatch(idRegex, 'a');

		// Add class selectors to parts collection (type b)
		findMatch(classRegex, 'b');

		// Add pseudo-element selectors to parts collection (type c)
		findMatch(pseudoElementRegex, 'c');

		// Add pseudo-class selectors to parts collection (type b)
		findMatch(pseudoClassWithBracketsRegex, 'b');
		findMatch(pseudoClassRegex, 'b');

		// Remove universal selector and separator characters
		selector = selector.replace(/[\*\s\+>~]/g, ' ');

		// Remove any stray dots or hashes which aren't attached to words
		// These may be present if the user is live-editing this selector
		selector = selector.replace(/[#\.]/g, ' ');

		// Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
	 	// Remove non-standard :local and :global CSS Module identifiers because they do not effect the specificity
		selector = selector.replace(/:not/g, '    ');
		selector = selector.replace(/:local/g, '      ');
		selector = selector.replace(/:global/g, '       ');
		selector = selector.replace(/[\(\)]/g, ' ');

		// The only things left should be element selectors (type c)
		findMatch(elementRegex, 'c');

		// Order the parts in the order they appear in the original selector
		// This is neater for external apps to deal with
		parts.sort(function(a, b) {
			return a.index - b.index;
		});

		return {
			selector: input,
			specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(),
			specificityArray: [0, typeCount.a, typeCount.b, typeCount.c],
			parts: parts
		};
	};

	/**
	 * Compares two CSS selectors for specificity
	 * Alternatively you can replace one of the CSS selectors with a specificity array
	 *
	 *  - it returns -1 if a has a lower specificity than b
	 *  - it returns 1 if a has a higher specificity than b
	 *  - it returns 0 if a has the same specificity than b
	 */
	var compare = function(a, b) {
		var aSpecificity,
			bSpecificity,
			i;

		if (typeof a ==='string') {
			if (a.indexOf(',') !== -1) {
				throw 'Invalid CSS selector';
			} else {
				aSpecificity = calculateSingle(a)['specificityArray'];
			}
		} else if (Array.isArray(a)) {
			if (a.filter(function(e) { return (typeof e === 'number'); }).length !== 4) {
				throw 'Invalid specificity array';
			} else {
				aSpecificity = a;
			}
		} else {
			throw 'Invalid CSS selector or specificity array';
		}

		if (typeof b ==='string') {
			if (b.indexOf(',') !== -1) {
				throw 'Invalid CSS selector';
			} else {
				bSpecificity = calculateSingle(b)['specificityArray'];
			}
		} else if (Array.isArray(b)) {
			if (b.filter(function(e) { return (typeof e === 'number'); }).length !== 4) {
				throw 'Invalid specificity array';
			} else {
				bSpecificity = b;
			}
		} else {
			throw 'Invalid CSS selector or specificity array';
		}

		for (i = 0; i < 4; i += 1) {
			if (aSpecificity[i] < bSpecificity[i]) {
				return -1;
			} else if (aSpecificity[i] > bSpecificity[i]) {
				return 1;
			}
		}

		return 0;
	};

	exports.calculate = calculate;
	exports.compare = compare;

	Object.defineProperty(exports, '__esModule', { value: true });

})));
