/**
 * A selectable starship option displayed in the pre-game screen.
 * It shows the ship thumbnail (cropped from the menu spritesheet), its name,
 * three stat bars (speed, rotation, thrust) and its weapons.
 */
export default class ShipOption extends HTMLElement
{
	static SHIP_SELECT_EVT = 'ship-select';

	// Maximum values used to compute the stat bars fill
	static SPEED_MAX = 200;
	static ROTATION_MAX = 200;
	static THRUST_MAX = 150;

	// Ship thumbnails position/size within the 1024x1024 menu spritesheet.
	// Coordinates are expressed as CSS (top-left) origin.
	static SPRITES = {
		Viking: { x: 779, y: 1, w: 140, h: 84 },
		Astro:  { x: 779, y: 173, w: 132, h: 84 },
		Raptor: { x: 779, y: 87, w: 135, h: 84 }
	};

	static SHEET = { url: './assets/images/spritesheet-menu.png', w: 1024, h: 1024 };

	// The art is natively 2x, so the thumbnails are drawn at their source size
	static SCALE = 1;

	constructor()
	{
		super();

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

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

			<style>
				:host { display: block; }

				.ship-card {
					cursor: pointer;
					transition: box-shadow .15s ease-in-out, border-color .15s ease-in-out;
				}

				.ship-card.selected {
					border-color: var(--bs-primary) !important;
					box-shadow: 0 0 0 .25rem rgba(var(--bs-primary-rgb), .35);
				}

				.thumb-wrap {
					height: 96px;
					display: flex;
					align-items: center;
					justify-content: center;
				}

				.thumb {
					background-image: url('${ShipOption.SHEET.url}');
					background-repeat: no-repeat;
					image-rendering: auto;
				}
			</style>

			<div class="ship-card card h-100 border-2">
				<div class="card-body d-flex flex-column">
					<div class="thumb-wrap">
						<div class="thumb"></div>
					</div>
					<h5 class="ship-name text-center mt-2 mb-3"></h5>
					<div class="vstack gap-2 mt-auto">
						<div>
							<small class="text-body-secondary">Speed</small>
							<div class="progress" role="progressbar"><div class="progress-bar speed-bar"></div></div>
						</div>
						<div>
							<small class="text-body-secondary">Rotation</small>
							<div class="progress" role="progressbar"><div class="progress-bar rotation-bar"></div></div>
						</div>
						<div>
							<small class="text-body-secondary">Thrust</small>
							<div class="progress" role="progressbar"><div class="progress-bar thrust-bar"></div></div>
						</div>
						<div class="text-center mt-1">
							<small class="text-body-secondary">Weapons:</small> <small class="weapons fw-semibold"></small>
						</div>
					</div>
				</div>
			</div>
		`;

		this.card = this._shadowRoot.querySelector('.ship-card');
		this.nameLabel = this._shadowRoot.querySelector('.ship-name');
		this.thumb = this._shadowRoot.querySelector('.thumb');
		this.speedBar = this._shadowRoot.querySelector('.speed-bar');
		this.rotationBar = this._shadowRoot.querySelector('.rotation-bar');
		this.thrustBar = this._shadowRoot.querySelector('.thrust-bar');
		this.weaponsLabel = this._shadowRoot.querySelector('.weapons');

		this.boundOnCardClick = this.onCardClick.bind(this);
	}

	connectedCallback()
	{
		// Display name
		this.nameLabel.innerText = this.getAttribute('name');

		// Display ship thumbnail cropped from the spritesheet
		const sprite = ShipOption.SPRITES[this.ship];
		if (sprite != null)
		{
			const s = ShipOption.SCALE;
			this.thumb.style.width = `${sprite.w * s}px`;
			this.thumb.style.height = `${sprite.h * s}px`;
			this.thumb.style.backgroundSize = `${ShipOption.SHEET.w * s}px ${ShipOption.SHEET.h * s}px`;
			this.thumb.style.backgroundPosition = `-${sprite.x * s}px -${sprite.y * s}px`;
		}

		// Add click listener
		this.card.addEventListener('click', this.boundOnCardClick);
	}

	disconnectedCallback()
	{
		this.card.removeEventListener('click', this.boundOnCardClick);
	}

	get ship()
	{
		return this.getAttribute('ship');
	}

	/**
	 * Display the ship stats received from the server-side Room Extension.
	 */
	setStats(maxSpeed, rotationSpeed, thrustAccel, weapons)
	{
		this.setBarFill(this.speedBar, maxSpeed, ShipOption.SPEED_MAX);
		this.setBarFill(this.rotationBar, rotationSpeed, ShipOption.ROTATION_MAX);
		this.setBarFill(this.thrustBar, thrustAccel, ShipOption.THRUST_MAX);
		this.weaponsLabel.innerText = weapons;
	}

	setBarFill(bar, current, max)
	{
		const perc = Math.max(0, Math.min(100, (current / max) * 100));
		bar.style.width = `${perc}%`;
	}

	setSelected(selected)
	{
		this.card.classList.toggle('selected', selected);
	}

	onCardClick(e)
	{
		this.dispatchEvent(
			new CustomEvent(ShipOption.SHIP_SELECT_EVT, {
				bubbles: true,
				composed: true,
				detail: {
					ship: this.ship
				}
			})
		);
	}
}

customElements.define('ship-option', ShipOption);
