(function() {
    function createSvgEl(tag) {
        return document.createElementNS("http://www.w3.org/2000/svg", tag);
    }

    function lerp(datax, datay, x) {
        for (let i=0; i<datax.length; i++) {
            const lo = datax[i];
            const hi = datax[i + 1];
            if (lo > x || hi < x)
                continue;
            const loy = datay[i];
            const hiy = datay[i + 1];
            return loy + (hiy-loy) * ((x - lo) / (hi - lo));
        }
    }

    function robinson(lat, lon, radius, centerMeridian, adjX, adjY) {
        const table = [
            // lat a b
            [0,  1.0000, 0.0000],
            [5,  0.9986, 0.0314],
            [10, 0.9954, 0.0629],
            [15, 0.9900, 0.0943],
            [20, 0.9822, 0.1258],
            [25, 0.9730, 0.1572],
            [30, 0.9600, 0.1887],
            [35, 0.9427, 0.2201],
            [40, 0.9216, 0.2515],
            [45, 0.8962, 0.2826],
            [50, 0.8679, 0.3132],
            [55, 0.8350, 0.3433],
            [60, 0.7986, 0.3726],
            [65, 0.7597, 0.4008],
            [70, 0.7186, 0.4278],
            [75, 0.6732, 0.4532],
            [80, 0.6213, 0.4765],
            [85, 0.5722, 0.4951],
            [90, 0.5322, 0.5072],
        ];
        const a = lerp(table.map(r => r[0]), table.map(r => r[1]), Math.abs(lat));
        const b = lerp(table.map(r => r[0]), table.map(r => r[2]), Math.abs(lat));
        const x = 0.8487 * radius * a * ((lon * Math.PI/180) - centerMeridian) * adjX;
        const y = (1.3523 * radius * b * adjY) * (lat < 0 ? -1 : 1);
        return [x, y];
    }

    function hexbyte(n) {
        return Math.round(n).toString(16).padStart(2, '0')
    }

    function ring(x, y, radius, strokeWid, trans) {
        const circle = createSvgEl("circle");
        circle.setAttribute("cx", x);
        circle.setAttribute("cy", y);
        circle.setAttribute("r", radius);
        circle.setAttribute("stroke", "#1c619a" + hexbyte(80 + trans * 5));
        circle.setAttribute("stroke-width", strokeWid);
        circle.setAttribute("fill", "#1c619a" + hexbyte(trans));
        return circle;
    }

    function drawServerLocation(e, data) {
        if (!e || !data) return;

        const svg = e.contentDocument.querySelector("svg");

        const height = svg.height.baseVal.value;
        const width = svg.width.baseVal.value;
        const earthRadius = width / 2.666269758 / 2;
        const center = 0;
        const adjX = 1.02;
        const adjY = 2;
        const offX = -12;
        const offY = 75;

        for (point of data) {
            const xy = robinson(point[0], point[1], earthRadius, center, adjX, adjY);
            const realX = (width / 2) + xy[0] + offX;
            const realY = (height / 2) - (xy[1]) + offY;

            const dot = createSvgEl("circle");
            dot.setAttribute("cx", realX);
            dot.setAttribute("cy", realY);
            dot.setAttribute("r", 5);
            dot.setAttribute("fill", "#1c619a");
            svg.appendChild(dot);

            const rf = 5;
            const rs = 15;

            svg.appendChild(ring(realX, realY, rf + rs * 1, 2,   20));
            svg.appendChild(ring(realX, realY, rf + rs * 2, 1,   15));
            svg.appendChild(ring(realX, realY, rf + rs * 3, 0.5, 10));
        }
    }

    window.addEventListener("load", function() {
        drawServerLocation(
            document.getElementById("map"),
            JSON.parse(document.getElementById('locations-data').textContent)
        );
    });
})();