<canvas id="canvas" style="width:960; height:540" width=1920 height=1080></canvas>
<script src="rive.js"></script>
<script src="webgpu_player.js"></script>
<script>
async function loadRiveAsset(args)
{
    const file = RiveLoadFile(await download(args.url));
    let artboard;
    if (args.artboard) {
        artboard = file.artboardNamed(args.artboard);
    } else {
        artboard = file.artboardDefault();
    }
    let asset;
    if (args.stateMachine) {
        asset = artboard.stateMachineNamed(args.stateMachine);
    } else if (args.animation) {
        asset = artboard.animationNamed(args.animation);
    } else {
        asset = artboard.defaultStateMachine();
    }
    asset.artboard = artboard;
    asset.file = file;
    return asset;
}

const data = {};
const assets = {};

async function wgpuDataInitialize(wgpu, canvas, adapter, device)
{
    data.device = device;
    data.queue = device.queue;
    data.width = canvas.width;
    data.height = canvas.height;
    data.wgpu = wgpu;

    // Rive has to be initialized before loading assets.
    const invertY = false
    RiveInitialize(data.device, data.queue, data.width, data.height, invertY, RIVE_PLS_TYPE_NONE);

    assets.skills = await loadRiveAsset({url:"skills_demov1.riv", stateMachine:"Motion"});
    assets.santa = await loadRiveAsset({url:"Santa_Claus.riv"});
    assets.coffee = await loadRiveAsset({url:"Coffee_Cup.riv", animation:"Timeline 1"});
    assets.skull = await loadRiveAsset({url:"skull_404.riv"});
    assets.octopus = await loadRiveAsset({url:"octopus_loop.riv"});
    assets.mercury = await loadRiveAsset({url:"planets.riv", artboard:"Mercury",
                                          animation:"MercuryIdle"});
    assets.timer = await loadRiveAsset({url:"Timer.riv", animation:"Esample"});
    assets.adventureTime = await loadRiveAsset({url:"adventuretime_marceline-pb.riv",
                                                artboard:"AdventureTime_FtMarcelinePB",
                                                stateMachine:"State Machine 1"});
    setInterval(function() {
        // Simulate a mouse click on assets.adventureTime every 2.5 seconds.
        assets.adventureTime.pointerDown(200, 200);
        assets.adventureTime.pointerUp(200, 200);
    }, 2500);
    assets.towers = await loadRiveAsset({url:"towersDemo.riv"});
}

const fps = new function() {
    this.frames = 0;
    this.seconds = 0;
    this.tick = function(elapsed) {
        ++this.frames;
        this.seconds += elapsed;
        if (this.seconds >= 2) {
            console.log((this.frames / this.seconds).toFixed(2) + " FPS");
            this.frames = 0;
            this.seconds = 0;
        }
    };
};

let lastTimestamp = 0;
let totalElapsed = 0;

async function wgpuRender(args)
{

    const elapsed = lastTimestamp ? (args.timestamp - lastTimestamp) / 1000 : 0;
    lastTimestamp = args.timestamp;
    for (asset in assets) {
        assets[asset].advanceAndApply(elapsed);
    }

    const targetTextureView = data.wgpu.getCurrentTexture().createView();
    const renderer = RiveBeginRendering(targetTextureView, RIVE_LOAD_ACTION_CLEAR, 0xff8030ff);
    const middleFrame = [0, data.height * .25, data.width, data.height * .67];
    const dock = [0, data.height * .75, data.width, data.height * .97];

    renderer.save();
    assets.skills.artboard.align(renderer, middleFrame, RIVE_FIT_FIT_HEIGHT, [.38, 0]);
    renderer.transform(1.5, 0, 0, 1.5, 0, -250);
    assets.skills.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.santa.artboard.align(renderer, middleFrame, RIVE_FIT_FIT_HEIGHT, [-.5, 0]);
    assets.santa.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.coffee.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, RIVE_ALIGNMENT_BOTTOM_CENTER);
    renderer.transform(2, 0, 0, 2, -40, -600);
    assets.coffee.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.skull.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, [.565, 1]);
    assets.skull.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.octopus.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, RIVE_ALIGNMENT_BOTTOM_LEFT);
    renderer.transform(1.7, 0, 0, 1.7, 90, -240);
    assets.octopus.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.mercury.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, [-.62, 1]);
    const mercuryCenterX = assets.mercury.artboard.width() / 2;
    const mercuryCenterY = assets.mercury.artboard.height() / 2;
    renderer.translate(mercuryCenterX, mercuryCenterY);
    const cx = Math.cos(totalElapsed) * .7;
    const sx = Math.sin(totalElapsed) * .7;
    renderer.transform(cx, sx, -sx, cx, 0, 0);
    renderer.translate(-mercuryCenterX, -mercuryCenterY);
    assets.mercury.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.timer.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, [.31, 1]);
    renderer.translate(0, -assets.timer.artboard.height() * .125);
    assets.timer.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.adventureTime.artboard.align(
        renderer, dock, RIVE_FIT_FIT_HEIGHT, RIVE_ALIGNMENT_BOTTOM_RIGHT);
    renderer.translate(-160, 0);
    assets.adventureTime.draw(renderer);
    renderer.restore();

    renderer.save();
    assets.towers.artboard.align(renderer, dock, RIVE_FIT_FIT_HEIGHT, [-.28, 1]);
    renderer.transform(.85, 0, 0, .85, 0, 20);
    assets.towers.draw(renderer);
    renderer.restore();

    RiveFlushRendering();
    totalElapsed += elapsed;
    fps.tick(elapsed);
}

function download(url)
{
    return new Promise(function (resolve, reject) {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.responseType = "arraybuffer";
        xhr.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(new Uint8Array(xhr.response));
            } else {
                reject({
                    status: this.status,
                    statusText: xhr.statusText
                });
            }
        };
        xhr.onerror = function () {
            reject({
                status: this.status,
                statusText: xhr.statusText
            });
        };
        xhr.send();
    });
}

async function main()
{
    const canvas = document.getElementById("canvas");
    const wgpu = canvas.getContext("webgpu");

    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
      throw new Error("No appropriate GPUAdapter found.");
    }

    const device = await adapter.requestDevice();

    const canvasFormat = navigator.gpu.getPreferredCanvasFormat();
    wgpu.configure({
      device: device,
      format: canvasFormat,
    });

    await wgpuDataInitialize(wgpu, canvas, adapter, device);

    const mainLoop = async () => {
        await wgpuRender({timestamp:performance.now()});
        requestAnimationFrame(mainLoop);
    };
    requestAnimationFrame(mainLoop);
}

if (Module.calledRun) {
    main();
} else {
    Module.onRuntimeInitialized = main;
}
</script>
