class Filpper {
    constructor(el, template, startVal = 0, startDir = 'up') {
        this.el = el;
        this.template = template;
        this.startVal = startVal;
        this.startDir = startDir;
        this.templateData = {
            curSize: '',
            curVal: '0',
            nextSize: '',
            nextVal: '0'
        };
        this.templateAsStr = template.innerHTML;
        this.tokens = getSubstitutionTokens(this.templateAsStr);
        this.templateData.curVal = startVal.toString();
        this.setDirection(startDir);
        this.update(startVal);
    }
    update(newVal) {
        this.templateData.nextVal = newVal.toString();
        this.setSizes();
        this.runAnimation();
    }
    setDirection(direction) {
        if (direction.toLowerCase() === 'up') {
            this.el.classList.add('up');
            this.el.classList.remove('down');
        }
        else {
            this.el.classList.add('down');
            this.el.classList.remove('up');
        }
    }
    setSizes() {
        const td = this.templateData;
        this.templateData.curSize = this.getSize(td.curVal);
        this.templateData.nextSize = this.getSize(td.nextVal);
    }
    getSize(val) {
        return val.toString().length > 1 ? 'small' : '';
    }
    runAnimation() {
        const inner = processTemplateSubstitutions(this.templateAsStr, this.tokens, this.templateData);
        this.el.innerHTML = inner;
        window.requestAnimationFrame(() => {
            this.el.classList.remove('changed');
            window.requestAnimationFrame(() => this.el.classList.add('changing'));
        });
        setTimeout(() => {
            this.el.classList.add('changed');
            this.el.classList.remove('changing');
            this.templateData.curVal = this.templateData.nextVal;
        }, this.duration * 0.9);
    }
}
;
// --------------------------------------------------------------------------------------------------------------------
// Teplating Helpers
const processTemplateSubstitutions = (template, tokens, data) => {
    const processedTemplate = tokens.reduce((str, token) => str.replace(new RegExp(`{{\\s${token}\\s+}}`, 'gm'), path(data, token)), template);
    return processedTemplate;
};
const getSubstitutionTokens = (template) => {
    let resArr = [];
    let tempArr;
    const regex = new RegExp('{{\\s+(.*?)\\s+}}', 'g');
    while ((tempArr = regex.exec(template)) !== null) {
        resArr.push(tempArr[1]);
    }
    return Array.from(new Set(resArr));
};
const path = (obj, path, defaultval = '') => {
    // Safely get nested properties without triggering type errors
    // Usage: fetch(obj, 'a.b.c.d')
    // Returns d if d exists, else defaultval or an empty string
    if (typeof defaultval === 'undefined')
        defaultval = null;
    if (typeof obj !== 'object')
        return defaultval;
    if (typeof path !== 'string')
        return defaultval;
    var props = path.split('.');
    var test_first = (obj, props) => {
        if (props.length) {
            var first = props[0];
            if (obj.hasOwnProperty(first)) {
                var rest = props.slice(1);
                return test_first(obj[first], rest); // Recursive chomp
            }
            else {
                return defaultval; // The default value, or null
            }
        }
        else {
            return obj; // The chomped object's last primitive property if it exists
        }
    };
    return test_first(obj, props);
};
// --------------------------------------------------------------------------------------------------------------------
// Run the flipper
var card = document.querySelector('.flipper-card');
var template = document.querySelector('#flipper-card-template');
var c = new Filpper(card, template);
c.update(1);
setTimeout(() => c.update(2), 1000);
setTimeout(() => c.update(3), 2000);
setTimeout(() => c.update(4), 3000);
setTimeout(() => c.update(5), 4000);
setTimeout(() => c.update('A'), 5000);
setTimeout(() => c.update('B'), 6000);
setTimeout(() => c.update('C'), 7000);
setTimeout(() => c.update('D'), 8000);
setTimeout(() => c.update('E'), 9000);
//# sourceMappingURL=index.js.map