181 lines
5.5 KiB
JavaScript
181 lines
5.5 KiB
JavaScript
// Main application logic
|
|
|
|
let debounceTimer = null;
|
|
const EXAMPLE_CODE = 'DC2.Dw Gm L W T+ Phvwalt Sk? Cbk--^\\bl+lum B- A+ N? M+++!1 O/ H+++ $ F+o R++ Ac+++! J++ S U- I-- V- Q--- Tc+++[SE] E++';
|
|
|
|
// DOM elements
|
|
const input = document.getElementById('dragon-code-input');
|
|
const welcomeMessage = document.getElementById('welcome-message');
|
|
const decodedOutput = document.getElementById('decoded-output');
|
|
const loadExampleBtn = document.getElementById('load-example');
|
|
const clearInputBtn = document.getElementById('clear-input');
|
|
|
|
// Category sections
|
|
const sections = {
|
|
species: document.getElementById('species-content'),
|
|
physical: document.getElementById('physical-content'),
|
|
appearance: document.getElementById('appearance-content'),
|
|
abilities: document.getElementById('abilities-content'),
|
|
life: document.getElementById('life-content'),
|
|
personality: document.getElementById('personality-content'),
|
|
other: document.getElementById('other-content'),
|
|
errors: document.getElementById('errors-content')
|
|
};
|
|
|
|
// Event listeners
|
|
input.addEventListener('input', handleInput);
|
|
loadExampleBtn.addEventListener('click', loadExample);
|
|
clearInputBtn.addEventListener('click', clearInput);
|
|
|
|
function handleInput() {
|
|
// Debounce input to avoid excessive processing
|
|
clearTimeout(debounceTimer);
|
|
debounceTimer = setTimeout(() => {
|
|
const code = input.value.trim();
|
|
if (code) {
|
|
processCode(code);
|
|
} else {
|
|
showWelcome();
|
|
}
|
|
}, 500);
|
|
}
|
|
|
|
function loadExample() {
|
|
input.value = EXAMPLE_CODE;
|
|
processCode(EXAMPLE_CODE);
|
|
}
|
|
|
|
function clearInput() {
|
|
input.value = '';
|
|
showWelcome();
|
|
}
|
|
|
|
function showWelcome() {
|
|
welcomeMessage.classList.remove('hidden');
|
|
decodedOutput.classList.add('hidden');
|
|
}
|
|
|
|
function processCode(code) {
|
|
try {
|
|
// Parse the Dragon Code
|
|
const parsed = parseDragonCode(code);
|
|
|
|
// Decode to human-readable format
|
|
const decoded = decodeDragonCode(parsed);
|
|
|
|
// Render the results
|
|
renderResults(decoded, parsed.errors);
|
|
|
|
} catch (error) {
|
|
console.error('Error processing code:', error);
|
|
showError('An unexpected error occurred while processing the code.');
|
|
}
|
|
}
|
|
|
|
function renderResults(decoded, errors) {
|
|
// Clear all sections
|
|
Object.values(sections).forEach(section => {
|
|
section.innerHTML = '';
|
|
});
|
|
|
|
// Hide welcome, show output
|
|
welcomeMessage.classList.add('hidden');
|
|
decodedOutput.classList.remove('hidden');
|
|
|
|
// Render each category
|
|
renderCategory('species', decoded.species);
|
|
renderCategory('physical', decoded.physical);
|
|
renderCategory('appearance', decoded.appearance);
|
|
renderCategory('abilities', decoded.abilities);
|
|
renderCategory('life', decoded.life);
|
|
renderCategory('personality', decoded.personality);
|
|
renderCategory('other', decoded.other);
|
|
|
|
// Render errors if any
|
|
if (errors && errors.length > 0) {
|
|
document.getElementById('errors-section').classList.remove('hidden');
|
|
errors.forEach(error => {
|
|
const errorElement = createTraitItem('Warning', error, '', 'warning');
|
|
sections.errors.appendChild(errorElement);
|
|
});
|
|
} else {
|
|
document.getElementById('errors-section').classList.add('hidden');
|
|
}
|
|
|
|
// Hide empty sections
|
|
hideEmptySections();
|
|
}
|
|
|
|
function renderCategory(categoryName, items) {
|
|
if (!items || items.length === 0) return;
|
|
|
|
const section = sections[categoryName];
|
|
items.forEach(item => {
|
|
const element = createTraitItem(item.label, item.value, item.tag, item.type || 'normal');
|
|
section.appendChild(element);
|
|
});
|
|
}
|
|
|
|
function createTraitItem(label, value, tag, type = 'normal') {
|
|
const div = document.createElement('div');
|
|
div.className = `trait-item ${type}`;
|
|
|
|
const labelDiv = document.createElement('div');
|
|
labelDiv.className = 'trait-label';
|
|
labelDiv.textContent = label;
|
|
|
|
const valueDiv = document.createElement('div');
|
|
valueDiv.className = 'trait-value';
|
|
valueDiv.textContent = value;
|
|
|
|
div.appendChild(labelDiv);
|
|
div.appendChild(valueDiv);
|
|
|
|
if (tag) {
|
|
const tagSpan = document.createElement('span');
|
|
tagSpan.className = 'trait-tag';
|
|
tagSpan.textContent = tag;
|
|
div.appendChild(tagSpan);
|
|
}
|
|
|
|
return div;
|
|
}
|
|
|
|
function hideEmptySections() {
|
|
const sectionElements = {
|
|
species: document.getElementById('species-section'),
|
|
physical: document.getElementById('physical-section'),
|
|
appearance: document.getElementById('appearance-section'),
|
|
abilities: document.getElementById('abilities-section'),
|
|
life: document.getElementById('life-section'),
|
|
personality: document.getElementById('personality-section'),
|
|
other: document.getElementById('other-section')
|
|
};
|
|
|
|
Object.keys(sectionElements).forEach(key => {
|
|
const content = sections[key];
|
|
const section = sectionElements[key];
|
|
|
|
if (content.children.length === 0) {
|
|
section.classList.add('hidden');
|
|
} else {
|
|
section.classList.remove('hidden');
|
|
}
|
|
});
|
|
}
|
|
|
|
function showError(message) {
|
|
welcomeMessage.classList.add('hidden');
|
|
decodedOutput.classList.remove('hidden');
|
|
|
|
Object.values(sections).forEach(section => {
|
|
section.innerHTML = '';
|
|
});
|
|
|
|
document.getElementById('errors-section').classList.remove('hidden');
|
|
const errorElement = createTraitItem('Error', message, '', 'error');
|
|
sections.errors.appendChild(errorElement);
|
|
|
|
hideEmptySections();
|
|
}
|