
const blockSeconds = 12 * 3600; // must match config.GraphBlockSize.Seconds()

var tileWidth = 1024;
var tileHeight = 288;

const timeStep = 2 * 3600; // one label every 2 hours

const isMobile = window.matchMedia("(hover: none) and (pointer: coarse)").matches;
if (isMobile) {
  tileWidth *= 4;
  tileHeight *= 4;
}

const track = document.getElementById("graph-track");
const scroll = document.getElementById("graph-scroll");

let loaded = new Set();

let centerTime = Math.floor(Date.now()/1000);

// round to block boundary
function snap(t) {
    return Math.floor(t / blockSeconds) * blockSeconds;
}


function formatLocalTime(unix) {
    return new Date(unix * 1000).toLocaleString(undefined, {
        day: "2-digit",
        month: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        hour12: false
    });
}

function getBlockTimestamp(block)
{
    let img = block.querySelector(".graph-tile");

    return Number(
        img.src
        .split("/")
        .pop()
        .split(".")[0]
    );
}

function addBlock(timestamp, before=false)
{
    timestamp = snap(timestamp);

    if(loaded.has(timestamp))
        return;

    loaded.add(timestamp);


    let block = document.createElement("div");
    block.className = "graph-block";


    let img = document.createElement("img");

    img.className = "graph-tile";

    img.width = tileWidth;
    img.height = tileHeight;

    img.src =
        `https://caffeine.ontake.dev/graph/${timestamp}.png`;


  block.appendChild(img);


    // add time labels
    for(let t = timestamp; t < timestamp + blockSeconds; t += timeStep)
    {
        let label = document.createElement("div");

        label.className = "time-label";

        let x =
            ((t - timestamp) / blockSeconds) * tileWidth;


        label.style.left = `${x}px`;


        label.textContent = formatLocalTime(t);


        block.appendChild(label);
    }


    if(before)
        track.prepend(block);
    else
        track.appendChild(block);
}


function loadAround(t)
{
    // Older tiles: add in reverse chronological order
    for (let i = -1; i >= -3; i--)
    {
        addBlock(
            t + i * blockSeconds,
            true
        );
    }

    // Current + future tiles
    for (let i = 0; i <= 3; i++)
    {
        addBlock(
            t + i * blockSeconds,
            false
        );
    }
}


loadAround(centerTime);


// initial position
setTimeout(()=>{

    scroll.scrollLeft =
        scroll.scrollWidth/2 - scroll.clientWidth/2;

},100);



scroll.addEventListener(
"scroll",
()=>{


    let left =
        scroll.scrollLeft;


    let max =
        scroll.scrollWidth -
        scroll.clientWidth;



    // near left edge
    if(left < tileWidth / 2)
    {
        let first =
            track.firstChild;


        if(first)
        {
            let ts = getBlockTimestamp(first);

            let oldWidth = scroll.scrollWidth;

            addBlock(ts - blockSeconds, true);

            requestAnimationFrame(() => {
                let newWidth = scroll.scrollWidth;
                scroll.scrollLeft += newWidth - oldWidth;
            });
        }
    }



    // near right edge
    if(max-left < tileWidth / 2)
    {

        let last =
            track.lastChild;


        if(last)
        {
          let ts = getBlockTimestamp(last);


            addBlock(
                ts+blockSeconds
            );
        }

    }


});
