import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"; import { Scorecard, getStoreDAO } from "./models.js"; const storeDao = getStoreDAO(); export class FinskaScorecardController extends Controller { static targets = ["score1Input", "score2Input", "scoreTable"]; static values = { maxScore: Number, overflowScoreTo: Number } connect() { let rules = { maxScore: Math.floor(this.maxScoreValue), overflowScoreTo: Math.floor(this.overflowScoreToValue) }; this._undoStack = []; this._scorecard = storeDao.loadOrCreate(rules); this.updateTable(); } updateTable() { let tableBody = this.scoreTableTarget; let tableRows = tableBody.querySelectorAll("tr"); let pairs = this._scorecard.pairs(); for (let pairIndex = 0; pairIndex < pairs.length; pairIndex++) { let tableRow; if (pairIndex >= tableRows.length) { tableRow = this._appendRow(); } else { tableRow = tableRows[pairIndex]; } this._updateRow(tableRow, pairs[pairIndex]) } // Remove any extra rows for (let i = pairs.length; i < tableRows.length; i++) { tableBody.removeChild(tableRows[i]); } console.log(JSON.stringify(this._scorecard.toJson())); } _updateRow(tableRow, pair) { let tds = tableRow.querySelectorAll("td"); this._updateCell(pair.p1, tds[0], tds[1]); this._updateCell(pair.p2, tds[2], tds[3]); } _updateCell(score, scoreCell, totalCell) { scoreCell.classList.value = ""; totalCell.classList.value = ""; if (score != null) { scoreCell.textContent = score.score; totalCell.textContent = score.total; if (score.score === 0) { scoreCell.classList.add("score-foul"); totalCell.classList.add("score-foul"); } else if (score.wasOverflow) { scoreCell.classList.add("score-overflow"); totalCell.classList.add("score-overflow"); } else if (score.wasWin) { scoreCell.classList.add("score-win"); totalCell.classList.add("score-win"); } } else { scoreCell.textContent = ""; totalCell.textContent = ""; } } _appendRow() { let newRow = document.createElement("tr"); newRow.classList.add("score-entry"); for (let i = 0; i < 4; i++) { newRow.appendChild(document.createElement("td")); } this.scoreTableTarget.appendChild(newRow); return newRow; } addScore1() { this._addScore(this.score1InputTarget, this.score2InputTarget, this._scorecard.addPlayer1Score.bind(this._scorecard), this._scorecard.removeLastPlayer1Score.bind(this._scorecard)); } addScore2() { this._addScore(this.score2InputTarget, this.score1InputTarget, this._scorecard.addPlayer2Score.bind(this._scorecard), this._scorecard.removeLastPlayer2Score.bind(this._scorecard)); } _addScore(inputElem, focusToInputElem, addScoreFn, queueUndoFn) { let score = parseInt(inputElem.value); if (isNaN(score)) { score = 0; } addScoreFn(score); this._undoStack.push(queueUndoFn); inputElem.value = ""; storeDao.save(this._scorecard); this.updateTable(); focusToInputElem.focus(); } score1KeyDown(e) { this._handleKeyDown(e, this.addScore1.bind(this)); } score2KeyDown(e) { this._handleKeyDown(e, this.addScore2.bind(this)); } _handleKeyDown(e, addScoreFn) { if (e.key === "Enter") { e.preventDefault(); addScoreFn(); } } undoLast() { if (this._undoStack.length === 0) { return; } if (!confirm("Really undo last move?")) { return; } (this._undoStack.pop())(); storeDao.save(this._scorecard); this.updateTable(); } resetAll() { if (!confirm("Really reset?")) { return; } this._scorecard.reset(); storeDao.clear(); this._undoStack = []; this.updateTable(); } }