colors = ['blue', 'yellow', 'green', 'pink', 'black'];
function parse(e) {
    var entry = {
        'type': null,
        'player': '',
        'cards': [],
    };
    var text = '';
    for (const c of e.childNodes) {
        if (c.nodeType == 3 /*text*/) text += c.nodeValue;
        if (colors.indexOf(c.className) > -1) {
            entry.cards.push({ 'color': c.className, 'value': toint(c.innerText) });
        }
    }
    textToType = new Map([
        // English.
        ['plays', 'plays'],
        ['new mission', 'new mission'],
        ['wins the trick', 'wins the trick'],
        // Russian.
        ['играет', 'plays'],
        ['новую миссию', 'new mission'],
        ['выигрывает взятку', 'wins the trick'],
        // French.
        ['joue', 'plays'],
        ['nouvelle mission', 'new mission'],
        ['remporte le pli', 'wins the trick'],
    ]);
    for (let [key, value] of textToType.entries()) {
        if (text.indexOf(key) < 0) continue;
        entry.type = value;
        break;
    }
    if (entry.type == null) return null; // Unknown action.
    if (entry.type == 'plays' && entry.cards.length == 0) return null; // Mismatch of 'play'.
    if (e.querySelector('.playername')) {
        entry.player = e.querySelector('.playername').innerText;
    }
    return entry;
}
class State {
    constructor() {
        this.players = new Set();
        this.reset();
    }
    reset() {
        this.cards = new Map();
        this.missing = new Map();
        for (const p of this.players) this.missing.set(p, new Set());
        this.currentColor = '';
        for (const c of colors) {
            this.cards.set(c, c == 'black' ? [1, 2, 3, 4] : [1, 2, 3, 4, 5, 6, 7, 8, 9]);
        }
    }
    run(action) {
        switch (action.type) {
            case 'new mission':
                this.reset();
                break;
            case 'plays':
                if (!this.players.has(action.player)) {
                    this.missing.set(action.player, new Set());
                    this.players.add(action.player);
                }
                const card = action.cards[0];
                this.cards.get(card.color)[card.value - 1] = 0;
                if (this.currentColor == '') {
                    this.currentColor = card.color;
                } else {
                    if (this.currentColor != card.color) this.missing.get(action.player).add(this.currentColor);
                }
                break;
            case 'wins the trick':
                this.currentColor = '';
                break;
            default:
                console.error('unknown action type', action.type);
        }
    }
}
function drawState(s) {
    area = document.querySelector('#customTable');
    if (!area) {
        area = document.createElement('div');
        area.id = 'customTable';
        area.style = 'width: 280px; height: 150px; padding: 5px; font-weight: bold;';
        document.getElementById('playertable_central').appendChild(area);
    }
    area.innerHTML = '';
    for (const c of colors) {
        row = document.createElement('div');
        row.style = 'display: flex;';
        for (const i of s.cards.get(c)) {
            tile = document.createElement('div');
            tile.innerText = i;
            dc = (i < 1) ? 'transparent' : c;
            tile.style = `display: block; min-height: 25px; min-width: 25px; margin: 2px; line-height: 25px; color: ${dc}; border: 1px solid ${dc};`;
            row.appendChild(tile);
        }
        area.appendChild(row);
    }
    for (const p of s.players) {
        document.querySelectorAll('.playertablename').forEach(c => {
            if (c.innerText.trim().indexOf(p) == -1) return;
            m = c.querySelector('.missing');
            if (!m) {
                m = document.createElement('div');
                m.className = 'missing';
                m.style = 'display: inline-block; font-size: 14px; ';
                c.appendChild(m);
            }
            m.innerHTML = '';
            for (const c of s.missing.get(p)) {
                tile = document.createElement('div');
                tile.innerText = 'X';
                tile.style = `display: inline-block; min-height: 15px; margin: 2px; min-width: 15px; line-height: 15px; color: ${c}; border: 1px solid ${c};`;
                m.appendChild(tile);
            }
        });
    }
}
function crewTable() {
    logs = Array.from(document.querySelectorAll('#logs .log > div'));
    logs = logs.reverse();
    const actions = logs.map(parse).filter(a => a);
    let s = new State();
    actions.forEach(a => {
        s.run(a);
    });
    drawState(s);
};
window.setInterval(crewTable, 500);