const wordElem = document.querySelector("#word");
const inputElem = document.querySelector("#input");
const candidateListElem = document.querySelector("#candidate-list");
const candidateContainerElem = document.querySelector("#candidate-container");
const reportElem = document.querySelector("#report")
const nextElem = document.querySelector("#next");
const hintElem = document.querySelector("#hint");
const showAnswerElem = document.querySelector("#show-answer");
const answerElem = document.querySelector("#answer");
const albumElem = document.querySelector("#album");
const trackElem = document.querySelector("#track");
const linesElem = document.querySelector("#lines");
let currentWord = {};
let hintsLeft = 2;
let songsPicked = 0;
function newWord() {
if (WORDS.length == 0) {
// what the hell
// why would anyone click Next a thousand times
wordElem.innerHTML = "There are no more words."
return;
}
if (songsPicked && songsPicked % 50 == 0) {
alert(`You have played this ${songsPicked} times. Consider taking a rest?`);
}
const idx = Math.floor(Math.random() * WORDS.length);
currentWord = WORDS[idx];
WORDS.splice(idx, 1); // remove word from WORDS so it will not show again
for (let album in ALBUMS) {
if (ALBUMS[album].tracks.includes(currentWord.track)) {
currentWord.album = album;
}
}
wordElem.innerHTML = currentWord.word;
hintsLeft = 2;
hintElem.innerHTML = "Hint (2)";
// clean after the mess
for (let elem of [inputElem, nextElem, hintElem, showAnswerElem]) {
elem.disabled = false;
}
for (let elem of [candidateContainerElem, reportElem, answerElem]) {
elem.hidden = true;
}
for (let elem of [candidateListElem, reportElem, albumElem, trackElem, linesElem]) {
elem.innerHTML = "";
}
inputElem.focus();
}
function acronymOf(track) {
// special case
if (track.toLowerCase() === "heavydirtysoul") {
return "hds";
}
let acronym = "";
for (let word of track.split(" ")) {
acronym += word[0].toLowerCase();
}
return acronym;
}
function makeCandidate(track, album) {
/*
*
* |
* Track Title |
*
*/
const candidate = document.createElement("tr");
candidate.setAttribute("class", "candidate");
candidate.addEventListener("click", pickSong);
const albumCoverCell = document.createElement("td");
const albumCover = document.createElement("img");
albumCover.setAttribute("class", "album-cover");
albumCover.setAttribute("src", album.cover);
albumCoverCell.appendChild(albumCover);
const trackTitleCell = document.createElement("td");
const trackTitle = document.createElement("span");
trackTitle.innerHTML = track;
trackTitleCell.appendChild(trackTitle);
candidate.appendChild(albumCoverCell);
candidate.appendChild(trackTitleCell);
return candidate;
}
inputElem.oninput = () => {
// clear candidates
candidateContainerElem.hidden = true;
candidateListElem.innerHTML = "";
const input = inputElem.value.toLowerCase();
if (!input) { return; }
let candidates = [];
for (let albumTitle in ALBUMS) {
album = ALBUMS[albumTitle];
for (let track of album.tracks) {
if (acronymOf(track).startsWith(input)) {
candidates.unshift(makeCandidate(track, album));
} else if (track.toLowerCase().startsWith(input)) {
candidates.push(makeCandidate(track, album));
}
}
}
// display candidates if they exist and don't take forever to scroll
if (candidates.length > 0 && candidates.length <= 5) {
for (let candidate of candidates) {
candidateListElem.appendChild(candidate);
}
candidateContainerElem.hidden = false;
}
}
inputElem.onkeyup = (event) => {
if (event.key == "Enter") {
pickSong(); // no arguments passed, pick first option
}
}
function pickSong(event) {
const candidate = event ? event.currentTarget : candidateListElem.firstChild;
const trackTitleElem = candidate.querySelector("span");
if (trackTitleElem.innerText === currentWord.track) {
// the guess is correct
reportElem.innerHTML = "Correct!";
reportElem.style.color = "#7faa55";
for (let elem of [inputElem, hintElem, showAnswerElem]) {
elem.disabled = true;
}
showAnswer();
nextElem.focus();
} else {
if (hintsLeft > 0) {
reportElem.innerHTML = "Sorry, not this song :)
Try a hint?";
} else {
reportElem.innerHTML = "Not this oneā¦";
}
reportElem.style.color = "#aa5555";
}
inputElem.value = "";
reportElem.hidden = false;
songsPicked++;
}
function hint() {
if (hintsLeft == 0) { return; }
answerElem.hidden = false;
if (hintsLeft == 2) {
// reveal album title
albumElem.innerHTML = currentWord.album;
} else if (hintsLeft == 1) {
// reveal part of a line surrounding the word
// thanks for the idea, u/Tarnoo
const lines = currentWord.lines;
const randLine = lines[Math.floor(Math.random() * lines.length)];
const wordsInLine = randLine.split(" ");
// normalize line and word, then locate word
const normWordsInLine = randLine.toLowerCase().replace(/[,\.\"\?!]/g, "").split(" ");
const wordIdx = normWordsInLine.indexOf(currentWord.word.toLowerCase());
let hint = "";
wordsInLine.forEach((word, idx) => {
if (Math.abs(idx - wordIdx) <= 1) {
hint += word;
} else {
hint += "_".repeat(word.length);
}
hint += " ";
});
linesElem.innerHTML = hint;
hintElem.disabled = true;
}
hintsLeft--;
hintElem.innerHTML = `Hint (${hintsLeft})`;
}
function showAnswer() {
answerElem.hidden = false;
albumElem.innerHTML = currentWord.album;
trackElem.innerHTML = currentWord.track;
linesElem.innerHTML = currentWord.lines.join("
");
hintElem.disabled = true;
}
window.onload = newWord;
nextElem.onclick = newWord;
hintElem.onclick = hint;
showAnswerElem.onclick = showAnswer;