"use strict";

class CreditsScene extends BaseScene {
    _animation = new Animation();
    _boids;


    // Load resources here
    load(loadingContext) {
        const ctx = loadingContext;
        ctx.loadShader("darkSky", "fullscreen.vert", "darkSky.frag");
        ctx.loadShader("fireEye", "sprite.vert", "fireEye.frag");
        ctx.loadSprite("aldroid", "aldroid.png");
        ctx.loadSprite("iconAldroid", "iconAldroid.png");
        ctx.loadSprite("dragongold", "dragongold.png");
        ctx.loadSprite("iconDragongold", "iconDragongold.png");
        ctx.loadSprite("watcher", "watcher.png");
        ctx.loadSprite("iconWatcher", "iconWatcher.png");
        ctx.loadSprite("kerwin", "kerwin.png");
        ctx.loadSprite("iconKerwin", "iconKerwin.png");

        for (let i = 1; i <= 5; i++) {
            const name = `raven${i}`;
            ctx.loadSprite(name,`${name}.png`);
            this._animation.addSprite(name);
        }
    }

    // One-time initialization at start of scene
    initialize() {
        this._animation.sequence = [0,1,2,1,0,3,4,3];

        const boidOptions = new BoidOptions();
        boidOptions.amount = 150;
        this._boids = new Boids(boidOptions);
        this._boids.each(boid => {
            const xOffset = 200 * Math.random(); 
            boid.x = 240 + xOffset;
            boid.y = -xOffset - 150 + 300 * Math.random();
            boid.speedX = -1.25 + 0.5 * Math.random();
            boid.speedY = 1.25 + 0.5 * Math.random();

            // Custom properties we added because we need them
            boid.animOffset = Math.random();
            boid.animSpeed = 1 + 0.9 * Math.random();
        });
    }

    // This is where the magic happens
    update(renderContext, time, globalTime) {
        const ctx = renderContext;
        ctx.backgroundShader("darkSky");

        this._drawHoodedOne(globalTime, ctx);

        const sin = Math.sin;
        const xAldroid = 40 + 2 * sin(0.3 + time/1.5);;
        const yAldroid = 105 + 2 * sin(2.1 + time/1.1);
        this._creditSprite("iconAldroid", xAldroid + 0.5 * sin(time * 0.9), yAldroid - 17 + 0.5 * sin(time * 1.1), 18, 
            time, ctx);
        this._creditSprite("aldroid", xAldroid, yAldroid, 30, 
            time, ctx);

        const xDragongold = 200 + 2 * sin(time/1.7); 
        const yDragongold = 60 + 2 * sin(time/1.3);
        this._creditSprite("iconDragongold", xDragongold + 0.5 * sin(0.3 + time * 0.9), yDragongold - 17 + 0.5 * sin(time * 1.2), 18, 
            time - 1, ctx);
        this._creditSprite("dragongold", xDragongold, yDragongold, 50, 
            time - 1, ctx);

        const xWatcher = 70 + 2 * sin(0.7 + time/1.1);
        const yWatcher = 30 + 2 * sin(0.1 + time/1.5);
        this._creditSprite("iconWatcher", xWatcher + 0.5 * sin(time * 0.7), yWatcher - 15 + 0.5 * sin(time * 1.15), 22, 
            time - 2, ctx);
        this._creditSprite("watcher", xWatcher, yWatcher, 52, 
            time - 2, ctx);

        const xKerwin = 160 + 2 * sin(0.7 + time/1.1);
        const yKerwin = 120 + 2 * sin(0.1 + time/1.5);
        this._creditSprite("iconKerwin", xKerwin + 0.5 * sin(0.1 +time * 0.7), yKerwin - 18 + 0.5 * sin(time * 1.15), 17, 
            time - 3, ctx);
        this._creditSprite("kerwin", xKerwin, yKerwin, 36, 
            time - 3, ctx);

        if (time < 6)
            return; // No boids for you!
            
        this._boids.update();

        this._boids.each(boid => {
            const sprite = new SpriteItem();
            sprite.name = this._animation.getSprite(boid.animSpeed * time + boid.animOffset);
            sprite.width = 20;
            sprite.position.x = boid.x;
            sprite.position.y = boid.y;
            sprite.rotation = Math.atan2(-boid.speedY, boid.speedX) * 180 / Math.PI;
            sprite.color = {r: 0,  g: 0,  b: 0,  a: 1};
            ctx.sprite(sprite);
        });  

    }

    _creditSprite(name, x, y, width, alphaTime, ctx) {
        const item = new SpriteItem();
        item.width = width;
        item.name = name;
        item.position.x = x;
        item.position.y = y;
        item.rotation = 0;
        item.color = { r: 1, g: 1, b: 1, a: this._clamp(alphaTime / 10, 0, 0.75) }
        ctx.sprite(item);
    }

    _drawHoodedOne(time, ctx) {
        ctx.sprite("hood", 120, 80, 128);
        const anger = 0.8 - 0.35 * Math.abs(Math.sin(time / 5));
        const eyeTransparency = this._clamp((time - 16) / 1, 0, 1);
        const eyeAlpha = eyeTransparency * (1.0 - 0.8 * Math.abs(Math.sin(time / 3)));
        this._drawEye(107, 58, anger, eyeAlpha, 0, ctx);
        this._drawEye(133, 58, anger, eyeAlpha, 0.5, ctx);
        ctx.sprite("hoodMask", 120, 80, 128);
    }

    _drawEye(x, y, anger, alpha, offset, ctx) {
        const item = new SpriteItem();
        item.width = 25;
        item.shaderName = "fireEye";
        item.shaderParameters = {
            anger: anger,
            alpha: alpha,
            offset: offset
        }
        item.position.x = x;
        item.position.y = y;
        ctx.sprite(item);
   }

}