
var GRID_PUBLIC_ID
    ,KNOWN_VERSION = 0
    ,GRID

    ,SELECTED = []
    ,CURRENTINPUT = null;

function doGet(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(e) {
        if (xhr.readyState === 4) {
            var resp = null;

            if (xhr.status === 200) {
                resp = xhr.response;
                try {
                    resp = JSON.parse(/** @type {string} */ (resp));
                } catch (e) {
                    resp = null;
                }
            }
            callback(xhr.status, resp);
        }
    };
    xhr.open('GET', url, true);
    xhr.send(null);
}

function initPolling() {
    doGet("/api/poll?grid=" +GRID_PUBLIC_ID +"&v=" +KNOWN_VERSION, function(status, resp) {
        if (resp) {
            GRID = new Grid(resp);
            if (resp["grid"]) {
                KNOWN_VERSION = Math.max(GRID.update(resp["grid"]) || 0, KNOWN_VERSION);
                uiCreateGrid();
            }
            KNOWN_VERSION = Math.max(KNOWN_VERSION, resp["v"] || 0);
        } // TODO else cannot init party
    });
}

function pollNow() {
    // TODO avoid duplicate call / abort planned poll
    doGet("/api/poll?grid=" +GRID_PUBLIC_ID +"&v=" +KNOWN_VERSION, function(status, resp) {
        if (resp && resp["grid"]) {
            var newVersion = Math.max(GRID.update(resp["grid"]) || 0, KNOWN_VERSION);
            if (newVersion !== KNOWN_VERSION) {
                onGridUpdated();
                KNOWN_VERSION = newVersion;
            }
        }
        // TODO plan next poll
    });
}

function keyPressHandler(cell, key) {
    cell.dom.classList.add(R.klass.cell.pending);
    doGet("/api/put?grid=" +GRID_PUBLIC_ID +"&key=" +key +"&x=" +cell.x +"&y=" +cell.y, function(status, resp) {
        cell.dom.classList.remove(R.klass.cell.pending);
        if (status === 403 && !cell.data.found) {
            cell.dom.classList.add(R.klass.cell.wrong);
            // TODO wrong
        } else if (status === 204) {
            cell.dom.classList.remove(R.klass.cell.wrong);
            cell.data.letter = key;
            cell.data.found = true;
            onGridUpdated();
        } else {
            // out of sync ?
            pollNow();
        }
    });
}

function unselect() {
    SELECTED.forEach(function (cell) {
        cell.dom.classList.remove(R.klass.cell.selected);
    });
    if (CURRENTINPUT) {
        CURRENTINPUT.dom.classList.remove(R.klass.cell.currentInput);
        CURRENTINPUT = null;
    }
    SELECTED = [];
}

function select(x, y) {
    var cell = UI_CELLS[x +y *GRID.width];
    SELECTED.push(cell);
    cell.dom.classList.add(R.klass.cell.selected);
}

document.addEventListener('DOMContentLoaded', function() {
    GRID_PUBLIC_ID = (document.location.hash.substr(1));

    if (GRID_PUBLIC_ID == "") {
        document.location.href = "/";
        return;
    }

    document.addEventListener('click', gridClickDelegate);
    document.addEventListener('keypress', function(e) {
        if (CURRENTINPUT && !CURRENTINPUT.data.found) {
            var key = e.key.charAt(0).toUpperCase();
            if (key.match(/[A-Z]/)) {
                CURRENTINPUT.data.letter = key;
                keyPressHandler(CURRENTINPUT, key);
                onGridUpdated();
            }
        }
    });
    initPolling();
});

