/**
 * active-state.js
 * Script triggers active state on element
 */

import ElementHelpers from '../helpers/element-helpers';

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

export class ActiveState {

	constructor(element) {
		this.element = element;
		this.activeClass = this.element.getAttribute(attributeBase);
		this.toggables = ElementHelpers.getElementsByAttributeWithinElement(this.element, this.attributes.toggable);
		this.addEventHandlers();
	}

	/**
	* Declare attribute constants
	*/
	get attributes() {
		return {
			toggable: 'data-rs-toggable'
		}
	}

	/**
	* Declare events
	*/
	get events() {
		return {
			mousedown: 'mousedown',
			mouseup: 'mouseup',
			dragend: 'dragend',
			touchstart: 'touchstart',
			touchend: 'touchend'
		}
	}

	/**
	 * Add event handlers
	 */
	addEventHandlers() {
		// add active class on mousedown and touchstart, remove this class on mouseup and touchend
		[this.events.mousedown, this.events.touchstart].forEach((event) => {
			const isMouseDown = event == this.events.mousedown;
			this.element.addEventListener(event, () => {
				this.element.classList.add(this.activeClass);
				window.addEventListener(isMouseDown ? this.events.mouseup : this.events.touchend, () => {
					this.removeActiveClass(this.element);
				}, { once: true });
				// add dragend event to remove active class, when event is mousedown
				if (isMouseDown) {
					window.addEventListener(this.events.dragend, () => {
						this.removeActiveClass(this.element);
					}, { once: true });
				}
			});
		});

		// on mousedown on toggable, prevent adding active class
		this.toggables.forEach(toggable => {
			toggable.addEventListener(this.events.mousedown, (event) => {
				event.stopPropagation();
			});
		});
	}

	/**
	 * Remove active class from element
	 * @param element - element containing the class 
	 */
	removeActiveClass(element) {
		element.classList.remove(this.activeClass);
	}

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