/// <reference path="../Elements.ts" />
/// <reference path="../Classes/AnimationLayer.ts" />

// Animations must have 200x200 frames, placed in a spritesheet with a single row
// Use https://github.com/williammalone/HTML5-Photoshop-Sprite-Sheet-Creator
// To make animations of varying Frames Per Second fit, we will have breakpoints in percentage that delimitate what is to be expected.
// Example: at 25% animation length, that's the Back-Thrust moment, so all the animations should expect and behave as if that was happening right then.
// 75% would be front-thrust, etc.
// The idea is to have the base animation look "ok" without anything going on, but to also have things going on just fit mathmagically.
// Support to animations that contain the WHOLE of the events should be possible as to make it so we can make special animations for special circumstances. e.g. only encounter with the ogre
enum AnimationLayerLevel {
    BACKGROUND = 1,
    MIDDLE = 150,
    FRONT = 300
}

interface AnimationInstruction {
    name: string;
    layer?: AnimationLayerLevel | number;
}

module Elements.AnimationHandler {
    var container = document.getElementById("sceneAnimation");
    var background = document.createElement("a");
    var stop = true;
    export var spriteSize = 200;
    export var animations : Array<AnimationLayer> = [];
    export var animationSpeed = 1500; // how long to complete in ms
    export var lastTime = 0;
    export var percentage;

    export function clearAnimations () {
        while (container.firstChild != undefined) {
            container.removeChild(container.firstChild);
        }
        animations = [];
    }

    export function addAnimations (...names : Array<AnimationInstruction>) {
        fixVerticalPosition();
        for (let i = 0; i < names.length; i++) {
            addAnimation(names[i].name);
        }
    }

    export function addAnimation (name : string, layer = 1) {
        let newAnim = new AnimationLayer(name, layer);
        container.appendChild(newAnim.getElement());
        animations.push(newAnim);
        return newAnim;
    }

    export function setBackground (name : string) {
        background.className = "";

        background.classList.add("bg-" + name);
        background.classList.add("sceneAnimation");
        background.style.zIndex = "0";

        container.appendChild(background);
    }

    export function beginAnimate (targetAnimationSpeed? : number) {
        animationSpeed = targetAnimationSpeed == undefined ? 1500 : targetAnimationSpeed;
        lastTime = (new Date()).getTime();
        percentage = 0;
        container.style.display = "";

        fixVerticalPosition();
        stop = false;
        animate();
    }

    export function animate () {
        let time = (new Date()).getTime();
        let percGain = (time - lastTime) / animationSpeed;
        percentage += percGain;
        while (percentage > 1) {
            percentage -= 1;
        }
        for (let i = 0; i < animations.length; i++) {
            animations[i].updateSprite(percentage);
        }
        lastTime = time;
        if (!stop) {
            window.requestAnimationFrame(Elements.AnimationHandler.animate);
        }
    }

    export function fixVerticalPosition () {
        spriteSize = getSize(true);
        //container.style.marginBottom = (availHeight - 200) + "px";
        container.style.width = spriteSize + "px";
        container.style.marginLeft = "-" + (spriteSize / 2) + "px";
        container.style.height = spriteSize + "px";

        animations.forEach((anim) => {
            anim.updateSize();
        });

        if (background.parentElement == container) {
            background.style.transform = "";
            let height = background.offsetHeight;
            let width = background.offsetWidth;
            if (height != 0 && width != 0) {
                background.style.transform = "scale(" + (spriteSize / height) + ")";
                background.style.marginLeft = (-width / 2) + "px";
                background.style.marginTop = (-height / 2) + "px";
            }
        }
    }

    export function getSize (fixMin = true) {
        let tab = document.getElementById("currentTurn");
        //let tab1 = document.getElementById("roomName");
        //tab1.style.marginTop = "";
        let height = window.innerHeight - tab.clientHeight;
        return height;
    }

    export function stopAnimate () {
        stop = true;
        container.style.display = "none";
        clearAnimations();
        getSize(false);
    }
    stopAnimate();
}

window.addEventListener("resize", () => { Elements.AnimationHandler.fixVerticalPosition(); });