'use strict';

/**
 * Fonctions globales
 * @constructor
 */
function Helper() {

	/**
	 * Récupère les éléments par le sélecteur CSS querySelector
	 * Utilisé dans {@link View}.
	 */
	Helper.prototype.qs = function (selector, scope) {
		return (scope || document).querySelector(selector);
	};


	/**
	 * Récupère les éléments par le sélecteur CSS querySelectorAll
	 * Utilisé dans {@link View}.
	 */
	Helper.prototype.qsa = function (selector, scope) {
		return (scope || document).querySelectorAll(selector);
	};


	/**
	 * Encapsule l'addEventListener.
	 * Utilisé dans {@link View}.
	 * Utilisé dans {@link App}.
	 * @param {object} (target)  La cible.
	 * @param {bolean} (type) Focus ou Blur.
  	 * @param {function} (callback) La fonction de rappel.
	 * @param {object} (useCapture) L' élément capturé.
	 */
	Helper.prototype.$on = function (target, type, callback, useCapture) {
		target.addEventListener(type, callback, !!useCapture);
	};


	/**
	 * Délègue un eventListener à un parent.
	 * Utilisé dans {@link View}.
	 * @param  {object} (target)  La cible.
	 * @param  {function} (selector) Vérifie qu'il y a match entre enfants et parents.
	 * @param {bolean} (type) Le type d' event.
	 * @param  {function} (handler)  Un callback exécuté si il y a une certaine condition.
	 */
	Helper.prototype.$delegate = function (target, selector, type, handler) {
		function dispatchEvent(event) {
			var targetElement = event.target;
			var potentialElements = window.qsa(selector, target);
			var hasMatch = Array.prototype.indexOf.call(potentialElements, targetElement) >= 0;

			if (hasMatch) {
				handler.call(targetElement, event);
			}
		}
		var useCapture = type === 'blur' || type === 'focus';
		window.$on(target, type, dispatchEvent, useCapture);
	};


	/**
	 * Recherche le parent de l'élément avec le nom de tag : $parent(qs('a'), 'div');
	 * Utilisé dans {@link View}.
	 * @param {object} (element) L'élément actif.
	 * @param {string} (tagName) Le tagName de l'élément.
	 */
	Helper.prototype.$parent = function (element, tagName) {
		if (!element.parentNode) {
			return;
		}
		if (element.parentNode.tagName.toLowerCase() === tagName.toLowerCase()) {
			return element.parentNode;
		}
		return window.$parent(element.parentNode, tagName);
	};

	NodeList.prototype.forEach = Array.prototype.forEach;

}