/**
 * A 5-star input used to set the player "experience" (an integer from 0 to 5).
 * It is used as a custom matchmaking parameter (User Variable) when inviting players to a game.
 */
export default class ExperienceInput extends HTMLElement
{
	static EXPERIENCE_CHANGE_EVT = 'experience-change';

	static observedAttributes = ['value'];

	constructor()
	{
		super();

		this._shadowRoot = this.attachShadow({ mode: 'closed' });

		this._shadowRoot.innerHTML = `
			<link href="./assets/css/bootstrap.min.css" rel="stylesheet" />
			<link href="./assets/icons/css/fontawesome.min.css" rel="stylesheet" />
			<link href="./assets/icons/css/solid.min.css" rel="stylesheet" />

			<i class="fa-solid fa-star text-primary"></i>
			<i class="fa-solid fa-star text-primary"></i>
			<i class="fa-solid fa-star text-primary"></i>
			<i class="fa-solid fa-star text-primary"></i>
			<i class="fa-solid fa-star text-primary"></i>
		`;

		this.stars = this._shadowRoot.querySelectorAll('.fa-star');

		// Add click listeners to stars
		this.stars.forEach((star, index) => {
			star.addEventListener('click', () => {
				this.onStarToggle(star, index);
			});
		});
	}

	attributeChangedCallback(name, oldValue, newValue)
	{
		switch (name)
		{
			case 'value':
				if (newValue != oldValue)
					this.update(Number(newValue));
				break;
		}
	}

	update(value)
	{
		const index = value - 1;

		for (let i = 0; i < this.stars.length; i++)
		{
			const star = this.stars[i];

			if (!this.isStarOn(star) && i <= index)
				this.setStarOn(star, true);

			if (this.isStarOn(star) && i > index)
				this.setStarOn(star, false);
		}
	}

	isStarOn(star)
	{
		return !star.classList.contains('text-secondary');
	}

	setStarOn(star, toOn)
	{
		if (toOn)
			star.classList.remove('text-secondary');
		else
			star.classList.add('text-secondary');
	}

	onStarToggle(star, index)
	{
		// Evaluate new value
		let value;

		if (this.isStarOn(star))
			value = index;
		else
			value = index + 1;

		// Set attribute
		this.setAttribute('value', value);

		// Fire custom event
		this.dispatchEvent(
			new CustomEvent(ExperienceInput.EXPERIENCE_CHANGE_EVT, {
				detail: {
					experience: value
				}
			})
		);
	}
}

customElements.define('experience-input', ExperienceInput);
