const selectedClass = 'selected';
function dataSelector({ dataset: { allegiance, number }}) {
return `[data-number="${number}"][data-allegiance="${allegiance}"]`;
}
function traceSelector(counter) {
return `polyline.move-trace${dataSelector(counter)}`;
}
function getCellPosition(cell) {
const [x, y] = cell.getAttributeNS(null, 'transform').match(/-?\d+\.?\d*/g);
return { x, y };
}
function getClones(svg, counter) {
return svg.querySelectorAll(`.counter.clone${dataSelector(counter)}`);
}
function addMoveToHistory(selected) {
const clone = selected.cloneNode(true);
clone.classList.remove(selectedClass);
clone.classList.add('clone');
selected.parentElement.appendChild(clone);
return clone;
}
function updatePlacement(cell, selected, clone) {
const { q, r, s, t } = clone.parentElement.dataset;
selected.dataset.previous = [q, r, s, t];
cell.appendChild(selected);
Array.from(selected.children).forEach(n => {
if (n.classList.contains('removed')) {
n.remove();
} else if ('preexisting' in n.dataset) {
delete n.dataset.preexisting;
}
});
}
function createTrace(previous, current, selected) {
const trace = document.createElementNS(svgns, 'polyline');
trace.dataset.number = selected.dataset.number;
trace.dataset.allegiance = selected.dataset.allegiance;
trace.classList.add('move-trace');
trace.setAttributeNS(null, 'points', `${previous.x},${previous.y} ${current.x},${current.y}`);
return trace;
}
export function createCounter(selected) {
const use = document.createElementNS(svgns, 'use');
const g = document.createElementNS(svgns, 'g');
// use.setAttributeNS(null, 'href', `#t-${selected.dataset.number}`);
use.setAttributeNS(null, 'href', `counters.svg#rifle`);
use.classList.add('primary-weapon');
g.classList.add('counter');
g.dataset.allegiance = selected.dataset.allegiance;
g.dataset.number = selected.dataset.number;
g.appendChild(use);
return g;
}
export function handleTrace(svg, selected, clone, current) {
let trace = getTrace(svg, selected);
if (!trace) {
trace = createTrace(getCellPosition(clone.parentElement), current, selected);
svg.querySelector('.grid').before(trace);
} else {
const points = `${trace.getAttribute('points')} ${current.x},${current.y}`;
trace.setAttributeNS(null, 'points', points);
}
}
export function getAllCounters(container) {
return container.querySelectorAll('g.counter[data-allegiance][data-number]');
}
export function getCounter(svg, selected) {
return svg.querySelector(`.counter${dataSelector(selected)}:not(.clone)`);
}
export function getTrace(svg, counter) {
return svg.querySelector(traceSelector(counter));
}
export function place(svg, selected, cell) {
if (svg.querySelector('.grid').contains(selected)) {
const clone = addMoveToHistory(selected);
updatePlacement(cell, selected, clone)
handleTrace(svg, selected, clone, getCellPosition(cell));
} else {
selected.removeAttribute('data-x');
cell.appendChild(selected);
}
}
export function removeClones(svg, counter) {
getClones(svg, counter).forEach(c => c.remove());
}
export function endMove(svg, counter) {
Array.from(counter.children).forEach(n => {
if (n.classList.contains('removed')) {
n.remove();
} else {
n.dataset.preexisting = '';
}
});
svg.querySelector(traceSelector(counter))?.remove();
delete counter.dataset.previous;
removeClones(svg, counter);
}
export function hasProne(counter) {
return !!counter.querySelector('[href="#counter-prone"]:not(.removed)');
}
export function toggleProne(counter) {
let proneCounter = counter.querySelector('[href="#counter-prone"]');
if (!proneCounter) {
proneCounter = document.createElementNS(svgns, 'use');
proneCounter.setAttributeNS(null, 'href', '#counter-prone');
counter.appendChild(proneCounter);
} else if ('preexisting' in proneCounter.dataset) {
proneCounter.classList.toggle('removed');
} else {
proneCounter.remove();
}
}
export function getSelectedClass() {
return selectedClass;
}