var FilteredSearch; // Globally scoped variable that can be used by other files
var Paginator;
var FilteredSearchFormatter;

(function ($) {

	var IdSequence = (function() {

	    var sequence = 0;

		IdSequence.prototype.next = function() {
		    sequence += 1;
			return sequence;
		};

		IdSequence.prototype.nextWithPrefix = function(prefix) {
			return [prefix, this.next()].join('-');
		};


		function IdSequence() {

		}
		return IdSequence;
	}());

	var ProductFilter = (function() {

		var uuid = new IdSequence();
		var allFilters = {};
		var appliedFilters = {};

		ProductFilter.prototype.buildFilters = function() {

			$('form.facets').each(function(i, form) {
				$(form).find('.facet').each(function(j, facet) {
					facet = $(facet);
					var groupName = uuid.nextWithPrefix('filter');
					allFilters[groupName] = [];

					facet.attr('data-group-name', groupName)
						.find(':checkbox').each(function(_, checkbox) {
							checkbox = $(checkbox);
							checkbox.attr('data-group-name', groupName);
							allFilters[groupName].push(checkbox.val());
					})


				});
			});

		};

		ProductFilter.prototype.decorateProducts = function() {

			$('.results-list').each(function(_, list) {
				list = $(list);
				list.children().each(function(_, child) {
					child = $(child);
					for (var groupName in allFilters) {
						if (allFilters.hasOwnProperty(groupName)) {
						    for (var i = 0; i < allFilters[groupName].length; i++) {
						    	var primitiveFilterName = allFilters[groupName][i];
						    	if (child.hasClass(primitiveFilterName)) {
						    		var groupedFilterName = [groupName, primitiveFilterName].join('--');
						    		child.addClass(groupedFilterName);
								}
							}
						}
					}
				});

			});

		};

		ProductFilter.prototype.applyFilters = function() {

			var resultsList = $('.results-list');
			var noMatchingItems = $('.no-matching-items');

			noMatchingItems.hide();

			var filtersGroupsApplied = (function() {
			    var count = 0;
				for (var k in appliedFilters) {
					if (appliedFilters.hasOwnProperty(k)) {
						count++;
					}
				}
				return count;
			}());

			if (!filtersGroupsApplied) {
				resultsList.children().removeClass('hide');
				return;
			}

			resultsList.children().addClass('hide');

			var iteration = 1;
			for (var groupName in appliedFilters) {
				if (appliedFilters.hasOwnProperty(groupName)) {
					var a = [], selector;
				    for (var i = 0; i < appliedFilters[groupName].length; i++) {
				    	a.push(['.', groupName, '--', appliedFilters[groupName][i]].join(''));
					}
				    selector = a.join(',');
				    if (iteration++ === 1) {
				    	resultsList.children().filter(selector).removeClass('hide');
					} else {
				    	var notSelector = [':not(', selector, ')'].join('');
						resultsList.children().filter(':not(.hide)').filter(notSelector).addClass('hide');
					}
				}
			}

			if (!resultsList.children().filter(':visible').length) {
				noMatchingItems.show();
			}
		};

		ProductFilter.prototype.listen = function() {
			var self = this;
			$('form.facets').each(function(_, facet) {
			    $(facet).find(':checkbox').click(function(e) {
			    	var checkbox = $(e.target),
						groupName = checkbox.attr('data-group-name'),
						filterName = checkbox.val();

					if (!appliedFilters.hasOwnProperty(groupName)) {
						appliedFilters[groupName] = [];
					}
					var index = appliedFilters[groupName].indexOf(filterName);

			    	if (index === -1 && !checkbox.is(':checked')) {
			    		appliedFilters[groupName].push(filterName);
					} else if (checkbox.is(':checked')) {
			    		appliedFilters[groupName].splice(index, 1);
					}

			    	if (!appliedFilters[groupName].length) {
			    		delete appliedFilters[groupName];
					}

			    	self.applyFilters();

				});
			})
		};

		ProductFilter.prototype.search = function() {
			this.buildFilters();
			this.decorateProducts();
			this.listen();
		};

		function ProductFilter() {

		}

		return ProductFilter;


	}());


	$(document).ready(function() {

		FilteredSearch  = new ProductFilter();
	});

}(window.jQuery));
