/**
 * slider.js
 * handles slider input field
 * 
 */
import ElementHelpers from '../helpers/element-helpers';

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

export class Slider {

	constructor(element) {
		this.element = element;
		this.rangeSlider = null;
		this.init();
	}

	/**
	* Declare attribute constants
	*/
	get attributes() {
		return {
			rangeLine: `${attributeBase}-range-line`,
			bullet: `${attributeBase}-label`,
			tooltip: `${attributeBase}-tooltip`,
			format: `${attributeBase}-format`,
			output: {
				min: `${attributeBase}-min`,
				max: `${attributeBase}-max`,
				label: `${attributeBase}-label-value`
			}
		}
	}

	init() {
		this.rangeSlider = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.rangeLine);
		this.bullet = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.bullet);
		this.label = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.label);
		this.tooltip = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.tooltip);
		this.format = this.element.getAttribute(this.attributes.format);
		this.addEventHandlers();
		this.setOutputValues();
	}

	/**
	 * Add event handlers
	 */
	addEventHandlers() {
		// ie11 check, ie11 reacts to "change" event instead of "input" event
		let eventType = !ElementHelpers.isIE11() ? 'input' : 'change';
		
		this.rangeSlider.addEventListener(eventType, () => {
			this.setBulletPosition();
		});
	}

	setOutputValues() {
		ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.min).innerText = this.formatNumber(this.rangeSlider.min);
		ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.max).innerText = this.formatNumber(this.rangeSlider.max);
		this.setBulletPosition();
	}

	/**
	 * Set bullet position
	 */
	setBulletPosition() {
		let bulletWidth = 13;
		let offsetSides = 11;
		// handle bullet based on current current slider value
		let sliderValue = parseInt(this.rangeSlider.value);
		if (isNaN(sliderValue)) {
			this.bullet.setAttribute('hidden', '');
			return;
		}
		// write current value to bullet
		this.label.innerText = this.formatNumber(sliderValue);
		// set bullet position
		const sliderWidth = this.rangeSlider.offsetWidth - bulletWidth;
		const min = this.rangeSlider.min;
		const max = this.rangeSlider.max;
		let bulletOffsetX = (this.bullet.offsetWidth - offsetSides) / 2;
		let newLeft = (sliderWidth * ((this.rangeSlider.value - min) / (max - min))) - bulletOffsetX;
		let newLeftMax = sliderWidth - this.bullet.offsetWidth + bulletWidth + offsetSides;
		if (newLeft < -1 * offsetSides) {
			this.tooltip.style.marginLeft = newLeft + ((this.bullet.offsetWidth + offsetSides) / 2) + 'px';
			newLeft = -1 * offsetSides;
		} else if (newLeft > newLeftMax) {
			this.tooltip.style.marginRight = offsetSides + (sliderWidth - newLeft) - (this.bullet.offsetWidth / 2) + (offsetSides / 2) + 'px';
			newLeft = newLeftMax;
		} else {
			this.tooltip.style.marginRight = 'auto';
			this.tooltip.style.marginLeft = 'auto'
		}
		this.bullet.style.left = newLeft + 'px';
	}

	formatNumber(number) {
		let output = number;
		if (typeof this.format === 'undefined' || this.format === null) { // attribute not set
			return output;
		} else if (this.format.trim() === '') { // attribute set, no value
			// default format
			output = new Intl.NumberFormat().format(number)
		} else { //attribute set with value
			// render for given format (nl-NL / ar-EG)
			output = new Intl.NumberFormat(this.format).format(number);
		}
		return output;
	}

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