/**
 * conditional.js
 * set classnames based on condition
 */

/**
* Declare constants
*/
const attributeBase = 'data-rs-conditional';

export class Conditional {

	constructor(element) {
		this.element = element;
		this.triggerElement = document.querySelector(this.element.getAttribute(this.attributes.trigger));
		this.condition = this.element.getAttribute(this.attributes.condition);
		this.match = null;
		this.addEventHandlers();
		this.validate();
	}

	/**
	* Declare attribute constants
	*/
	get attributes() {
		return {
			trigger: `${attributeBase}-trigger`,
			condition: `${attributeBase}-condition`,
			success: {
				class: `${attributeBase}-success-class`
			},
			failure: {
				class: `${attributeBase}-failure-class`

			}
		}
	}

	/**
	* Declare classes
	*/
	get classes() {
		return {
			success: this.getClassList('success'),
			failure: this.getClassList('failure')
		}
	}
	/**
	 * get result classes from attribute
	 * @param {string} type
	 */
	getClassList(type) {
		let classNamesRaw = this.element.getAttribute(this.attributes[type].class);
		return (classNamesRaw === null)
			? []
			: classNamesRaw.split(',').map(value => value.trim())
	}

	/**
	 * Add event handlers
	 */
	addEventHandlers() {
		this.triggerElement.addEventListener('change', () => {
			this.validate();
		});

		window.addEventListener('load', () => {
			this.validate();
		});
	}

	/**
	 * validate if the given condition is true
	 */
	validate() {
		this.match = document.querySelector(this.condition) !== null;
		if (this.match === true) {
			this.success();
		} else {
			this.failure();
		}
	}

	/**
	 * Handle validation result on success
	 */
	success() {
		// add success classes
		this.addClassList(this.classes.success);
		// remove failure classes
		this.removeClassList(this.classes.failure);
	}

	/**
	 * Handle validation result on failure
	 */
	failure() {
		// add failure classes
		this.addClassList(this.classes.failure);
		// remove success classes
		this.removeClassList(this.classes.success);
	}

	/**
	 * add classList to conditional element
	 * @param {array} classList
	 */
	addClassList(classList) {
		for (let i = 0; i < classList.length; i++) {
			this.element.classList.add(classList[i]);
		}
	}

	/**
	 * remove classList from conditional element
	 * @param {array} classList
	 */
	removeClassList(classList) {
		for (let i = 0; i < classList.length; i++) {
			this.element.classList.remove(classList[i]);
		}
	}


	/**
	 * Get selector
	 */
	static getSelector() {
		return `[${attributeBase}]`;
	}
}
