const Memory = {
    memoryId: "memory",
    wonId: "won",
    inputMemoryPairsCountId: "memory-pair-count",
    inputMemoryPairsId: "memory-pairs",
    inputMemorySizeId: "memory-size",
    selectFrontStyleId: "front-style-select",
    selectBackStyleId: "back-style-select",
    selectSpeedId: "speed-select",
    countId: "tries-counter",
    countWrapId: "tries-counter-wrap",
    displayNoneClass: Css.classes.displayNone,
    foundPairClass: "found",
    activePairClass: "active",
    memoryCardIdPrefix: "memory-card-",
    memoryCardClass: "memory-flip-card",
    memoryCardInnerClass: "inner",
    memoryCardFrontClass: "front",
    memoryCardBackClass: "back",
    generateMemoryBtnId: "generate-memory",
    memoryLoaderId: "memory-loader",
    highscorePairsCountId: "highscore-pairs-count",
    highscorePairsId: "highscore-pairs",
    highscoreCountId: "highscore-count",
    imageUrl: "./config/images.json",
    emojiUrl: "./config/emojis.min.json",
    emojiCategoriesUrl: "./config/emoji-categories.min.json",
    emojis: null,
    emojiCategories: null,
    amountPairs: 5,
    countPairs: 2,
    speed: 3,
    size: 14,
    backStyle: 0,
    frontStyle: 0,
    foundPairs: 0,
    counter: 0,
    highscorePairsCount: 0,
    highscorePairs: 0,
    highscoreCount: 0,
    memoryDom: null,
    countDom: null,
    wonDom: null,
    loaderDom: null,
    selectFrontStyleDom: null,
    selectBackStyleDom: null,
    images: null,
    intervalIds: [],
    colors: [],
    actives: [],
    activeFlipTimeoutId: 0,
    cookies: false,
    speedMap: [
        6000,
        4500,
        3000,
        1700,
        850,
        650,
        300
    ],
    MAP: {
        frontStyle2Class: {
            0: Css.classes.memoryCardStyleTwo + " " + Css.classes.bgBlack,
            1: Css.classes.memoryCardStyleTwo + " " + Css.classes.bgWhite,
            2: Css.classes.memoryCardStyleTwo + " " + Css.classes.bgOrange,
            3: Css.classes.memoryCardStyleTwo + " " + Css.classes.bgGreen,
            4: Css.classes.memoryCardStyleTwo + " " + Css.classes.bgBlue,

            5: Css.classes.memoryCardStyleOne + " " + Css.classes.bgBlack,
            6: Css.classes.memoryCardStyleOne + " " + Css.classes.bgWhite,
            7: Css.classes.memoryCardStyleOne + " " + Css.classes.bgOrange,
            8: Css.classes.memoryCardStyleOne + " " + Css.classes.bgGreen,
            9: Css.classes.memoryCardStyleOne + " " + Css.classes.bgBlue,

            10: Css.classes.bgBlack,
            11: Css.classes.bgWhite,
            12: Css.classes.bgOrange,
            13: Css.classes.bgGreen,
            14: Css.classes.bgBlue
        },
        backStyle2Emoji: {
            1: 0,
            2: 0,
            10: 1,
            11: 1,
            12: 2,
            13: 2,
            14: 3,
            15: 3,
            16: 4,
            17: 4,
            18: 5,
            19: 5,
            20: 6,
            21: 6,
            22: 7,
            23: 7,
            24: 8,
            25: 8,
            26: 9,
            27: 9
        },
        backStyleHasColor: [
            1, 3, 5, 7, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28
        ]
    },
    timeoutEffectId: 0,
    preFetchImages: false,
    cookieSaveHighscore: 1,
    cookieStartValue: 2,
    randomize: function (values) {
        let index = values.length, randomIndex;
        while (index !== 0) {
            randomIndex = Math.floor(Math.random() * index);
            index--;
            [values[index], values[randomIndex]] = [values[randomIndex], values[index]];
        }
    },
    fillArr: function (_this) {
        let arr = [];
        _this.colors = ["F09130", "bcce43", "308ff0"];
        for (let i = 0; i < _this.countPairs; i++) {
            for (let j = 0; j < _this.amountPairs; j++) {
                arr.push(j);
                if (j > _this.colors.length - 1) {
                    let newColor = Math.random().toString(16).substr(2, 3);
                    while (_this.colors.indexOf(newColor) > -1) {
                        newColor = Math.random().toString(16).substr(2, 3);
                    }
                    _this.colors.push(newColor);
                }
            }
        }
        if (_this.amountPairs < 5) {
            _this.randomize(arr);
        }
        _this.randomize(arr);
        _this.randomize(_this.colors);
        return arr;
    },
    winActionHelper(_this) {
        _this.highscorePairs = _this.amountPairs;
        _this.highscorePairsCount = _this.countPairs;
        _this.highscoreCount = _this.counter;
        
        if (_this.cookies && _this.cookieSaveHighscore === 1) {
            _this.setCookie("highscorePairs", _this.highscorePairs);
            _this.setCookie("highscorePairsCount", _this.highscorePairsCount);
            _this.setCookie("highscoreCount", parseInt(_this.highscoreCount));
        }
        _this.showHighscore(_this);
        if (typeof Firework === "object") {
            Firework.start();
        }
    },
    showHighscore: function (_this) {
        if (document.getElementById(_this.highscoreCountId) !== null) {
            document.getElementById(_this.highscoreCountId).innerHTML = _this.highscoreCount;
        }
        if (document.getElementById(_this.highscorePairsId) !== null) {
            document.getElementById(_this.highscorePairsId).innerHTML = _this.highscorePairs;
        }
        if (document.getElementById(_this.highscorePairsCountId) !== null) {
            document.getElementById(_this.highscorePairsCountId).innerHTML = _this.highscorePairsCount;
        }
    },
    winAction: function (_this) {
        if (_this.highscorePairsCount === _this.countPairs
                && _this.highscorePairs === _this.amountPairs
                && _this.highscoreCount > _this.counter) {
            _this.winActionHelper(_this);
        } else if (_this.highscorePairsCount === _this.countPairs
                && _this.highscorePairs < _this.amountPairs) {
            _this.winActionHelper(_this);
        } else if (_this.highscorePairsCount < _this.countPairs) {
            _this.winActionHelper(_this);
        }
        document.body.scrollIntoView({behavior: "smooth"});
        if (_this.wonDom !== null) {
            _this.wonDom.classList.remove(_this.displayNoneClass);
        }
    },
    closeAllActiveCards: function (_this) {
        let stillActives = _this.memoryDom.getElementsByClassName(_this.activePairClass);
        for (let i = 0; i < stillActives.length; i++) {
            if (stillActives[i] !== this) {
                stillActives[i].classList.remove(_this.activePairClass);
            }
        }
    },
    compareActivesWith: function (_this, card) {
        if (_this.actives.length === 0) {
            return true;
        } else {
            return (_this.actives[0].innerHTML === card.innerHTML && card.id !== _this.actives[0].id);
        }
    },
    cardAction: function (e) {
        if (e.type === "click" || e.keyCode === 13) {
            let _this = Memory;
            if (this.classList.contains(_this.foundPairClass)
                    || this.classList.contains(_this.activePairClass)
                    ) {
                return 0;
            } else {
                if (_this.actives.length === 0 && _this.memoryDom.getElementsByClassName(_this.activePairClass).length > 0) {
                    // START lol some strange behavior without the while i think p
                    while (_this.memoryDom.getElementsByClassName(_this.activePairClass).length > 0) {
                        _this.closeAllActiveCards(_this);
                    }
                    clearTimeout(_this.activeFlipTimeoutId);
                    // END
                }

                this.classList.add('active');
                if (_this.compareActivesWith(_this, this) && _this.actives.length < _this.countPairs - 1) {
                    _this.actives.push(this);
                } else {
                    _this.counter++;

                    if (_this.countDom !== null) {
                        if(document.getElementById(_this.countWrapId) !== null){
                            document.getElementById(_this.countWrapId).classList.remove(_this.displayNoneClass);
                        }
                        _this.countDom.innerHTML = _this.counter;
                    }
                    if (_this.compareActivesWith(_this, this)) {
                        this.removeAttribute("tabindex");
                        this.classList.add(_this.foundPairClass);
                        this.classList.remove(_this.activePairClass);
                        this.removeEventListener("click", _this.cardAction, false);
                        this.removeEventListener("keyup", _this.cardAction, false);

                        for (let i = 0; i < _this.actives.length; i++) {
                            _this.actives[i].removeAttribute("tabindex");
                            _this.actives[i].classList.add(_this.foundPairClass);
                            _this.actives[i].classList.remove(_this.activePairClass);
                            _this.actives[i].removeEventListener("click", _this.cardAction, false);
                            _this.actives[i].removeEventListener("keyup", _this.cardAction, false);
                        }
                        _this.foundPairs++;
                        if (_this.foundPairs === _this.amountPairs) {
                            _this.actives = [];
                            _this.winAction(_this);
                        }
                    } else {
                        let second = this, firsts = _this.actives;
                        _this.activeFlipTimeoutId = setTimeout(function () {
                            for (let i = 0; i < firsts.length; i++) {
                                if (second.classList.contains(_this.activePairClass)) {
                                    firsts[i].classList.remove(_this.activePairClass);
                                }
                            }
                            if (second.classList.contains(_this.activePairClass)) {
                                second.classList.remove(_this.activePairClass);
                            }
                            firsts = [];
                            second = null;
                        }, _this.speedMap[_this.speed]);
                    }
                    _this.actives = [];
                }
            }
        }
    },
    cardClick: function (_this, card) {
        card.addEventListener("click", _this.cardAction, false);
        card.addEventListener("keyup", _this.cardAction, false);
    },
    getCharCode: function (value) {
        if (value === null || value === "undefined") {
            return "";
        }
        if (value < 26) {
            return String.fromCharCode(65 + value);
        }
        return (Memory.getCharCode(Number(value / 26) - 1) + String.fromCharCode(65 + (value % 26)));
    },
    toHex: function (string) {
        var s = unescape(encodeURIComponent(string));
        var h = '';
        for (var i = 0; i < s.length; i++) {
            h += s.charCodeAt(i).toString(16);
        }
        return String(h);
    },
    simpleHashCode: function (string) {
        var a = 1, c = 0, h, o;
        if (string) {
            a = 0;
            for (h = string.length - 1; h >= 0; h--) {
                o = string.charCodeAt(h);
                a = (a << 6 & 268435455) + o + (o << 14);
                c = a & 266338304;
                a = c !== 0 ? a ^ c >> 21 : a;
            }
        }
        return String(a);
    },
    getSaltetString(_this, arr, i) {
        switch (arr[i] % 3) {
            case 1:
                return _this.amountPairs + ".a!" + _this.emojis[arr[i]] + _this.highscoreCount + "t" + arr[i] + "Rt" + ".a!" + _this.highscorePairs;
                break;
            case 2:
                return _this.amountPairs + ".T!" + +_this.highscorePairs + "t" + _this.emojis[arr[i]] + "t" + ".R!" + _this.highscoreCount;
                break;
            default:
                return _this.amountPairs + _this.emojis[arr[i]] + ".Ec" + arr[i] + _this.highscoreCount + "t" + "t" + ".a#" + _this.highscorePairs;
                break;
        }
    },
    randomLongString: function (_this, arr, i) {
        return _this.getCharCode(_this.toHex(_this.simpleHashCode(_this.getSaltetString(_this, arr, i))));
    },
    randomShortString: function (_this, arr, i) {
        return _this.getCharCode(_this.simpleHashCode(_this.getSaltetString(_this, arr, i)));
    },
    randomizeShortStringForMemorie: function (_this, arr, i) {
        return _this.getCharCode(_this.simpleHashCode(_this.getSaltetString(_this, arr, i)));
    },
    getContrastYIQ: function (hexcolor) {
        if (hexcolor.length === 3) {
            hexcolor = hexcolor.split('').map(function (hex) {
                return hex + hex;
            }).join('');
        }
        let r = parseInt(hexcolor.substr(0, 2), 16);
        let g = parseInt(hexcolor.substr(2, 2), 16);
        let b = parseInt(hexcolor.substr(4, 2), 16);
        let yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
        return (yiq >= 128) ? 'black' : 'white';
    },
    createCardBackDom: function (_this, arr, i, emojiSize) {
        let back = document.createElement("div");
        _this = Memory;
        back.className = _this.memoryCardBackClass;
        if (_this.MAP.backStyleHasColor.indexOf(_this.backStyle) > -1) {
            back.style = "background-color: #" + _this.colors[arr[i]] + ";";
            back.classList.add("text-" + _this.getContrastYIQ(_this.colors[arr[i]]));
        }
        switch (_this.backStyle) {
            case 0:
                if (typeof (_this.images[arr[i]]) === "undefined") {
                    back.style = "background-color: #" + _this.colors[arr[i]] + ";";
                    back.innerHTML = "<div style=\"font-size: " + emojiSize + "em;\">" + _this.emojis[_this.emojiCategories[0][arr[i]]] + "<div>";
                } else {
                    back.style = "background-image: url(" + _this.images[arr[i]] + ");";
                }
                break;
            case 3:
            case 4:
                back.innerHTML = "<div class=\"h1 text-wrap\">" + _this.randomShortString(_this, arr, i) + "<div>";
                break;
            case 5:
            case 6:
                back.innerHTML = "<div class=\"h1 text-wrap\">" + _this.randomLongString(_this, arr, i) + "<div>";
                break;
            case 7:
            case 8:
                back.innerHTML = "<div class=\"h1\">" + arr[i] + "<div>";
                break;
            case 28:
            case 29:
                back.innerHTML = "<div class=\"h1 text-wrap\">" + _this.simpleHashCode(arr[i] + "") + "<div>";
                break;
            case 9:
                break;
            default:
                if (typeof (_this.MAP.backStyle2Emoji[_this.backStyle]) === "undefined") {
                    if (typeof (_this.images[arr[i]]) === "undefined") {
                        back.style = "background-color: #" + _this.colors[arr[i]] + ";";
                        back.innerHTML = "<div style=\"font-size: " + emojiSize + "em;\">" + _this.emojis[_this.emojiCategories[0][arr[i]]] + "<div>";
                    } else {
                        back.style = "background-image: url(" + _this.images[arr[i]] + ");";
                    }
                } else {
                    back.innerHTML = "<div style=\"font-size: " + emojiSize + "em;\">" + _this.emojis[_this.emojiCategories[_this.MAP.backStyle2Emoji[_this.backStyle]][arr[i]]] + "<div>";
                }
                break;
        }
        return back;
    },
    drawSingleMemoryCard: function (_this, arr, i) {
        let card = document.createElement("div");
        card.id = _this.memoryCardIdPrefix + i;
        card.className = _this.memoryCardClass;
        card.setAttribute("tabindex", 0);

        card.style = "width: " + _this.size + "em; height: " + _this.size + "em";

        let inner = document.createElement("div");
        inner.className = _this.memoryCardInnerClass;
        let front = document.createElement("div");
        front.className = _this.memoryCardFrontClass + " " + _this.MAP.frontStyle2Class[_this.frontStyle];

        inner.appendChild(front);
        inner.appendChild(_this.createCardBackDom(_this, arr, i, _this.size * 0.8));
        card.appendChild(inner);
        _this.cardClick(_this, card);
        _this.memoryDom.appendChild(card);
    },
    draw: function (_this) {
        // if someone put somthing else into the memory 
        while (_this.memoryDom.firstChild) {
            _this.memoryDom.removeChild(_this.memoryDom.firstChild);
        }
        if (_this.images !== null) {
            _this.randomize(_this.images);
        }
        for (let i = 0; i < _this.emojiCategories.length; i++) {
            _this.randomize(_this.emojiCategories[i]);
        }


        let arr = _this.fillArr(_this);
        for (let i = 0; i < arr.length; i++) {
            _this.drawSingleMemoryCard(_this, arr, i);
        }
        arr = [];
    },
    reset: function (_this) {
        if (_this.wonDom !== null && !_this.wonDom.classList.contains(_this.displayNoneClass)) {
            _this.wonDom.classList.add(_this.displayNoneClass);
        }
        if (typeof Firework === "object") {
            Firework.stop();
        }
        let cards = document.getElementsByClassName(_this.memoryCardClass);
        for (let i = 0; i < cards.length; i++) {
            cards[i].removeEventListener("click", _this.cardAction, false);
            cards[i].removeEventListener("keyup", _this.cardAction, false);
            cards[i].remove();
        }
        cards = null;
        _this.foundPairs = 0;
        _this.actives = [];

    },
    hideWelcomeMessages: function (_this) {
        let doms = document.getElementsByClassName("welcome");
        for (let i = 0; i < doms.length; i++) {
            if (!doms[i].classList.contains(_this.displayNoneClass)) {
                doms[i].classList.add(_this.displayNoneClass);
            }
        }
    },
    showLoader: function (_this) {
        if (_this.loaderDom.classList.contains(_this.displayNoneClass)) {
            _this.loaderDom.classList.remove(_this.displayNoneClass);
        }
        if (!_this.memoryDom.classList.contains(_this.displayNoneClass)) {
            _this.memoryDom.classList.add(_this.displayNoneClass);
        }
    },
    hideLoader: function (_this) {
        if (!_this.loaderDom.classList.contains(_this.displayNoneClass)) {
            _this.loaderDom.classList.add(_this.displayNoneClass);
        }
        if (_this.memoryDom.classList.contains(_this.displayNoneClass)) {
            _this.memoryDom.classList.remove(_this.displayNoneClass);
        }
    },
    setCookieSaveHighscore: function (value) {
        Memory.cookieSaveHighscore = parseInt(value);
        Memory.setCookie("cookieSaveHighscore", Memory.cookieSaveHighscore);
    },
    setCookieStartValue: function (value) {
        if (parseInt(value) > 0) {
            Memory.cookieStartValue = parseInt(value);
            Memory.setCookie("cookieStartValue", Memory.cookieStartValue);
            Memory.setCooiesFromForm();
        }
    },
    setCooiesFromForm: function () {
        let _this = Memory;
        if (_this.cookies && _this.cookieStartValue === 1) {
            if (document.getElementById(_this.inputMemoryPairsId) !== null) {
                _this.setCookie("amountPairs", parseInt(document.getElementById(_this.inputMemoryPairsId).value));
            }
            if (document.getElementById(_this.inputMemoryPairsCountId) !== null) {
                _this.setCookie("countPairs", parseInt(document.getElementById(_this.inputMemoryPairsCountId).value));
            }
            if (document.getElementById(_this.selectSpeedId) !== null) {
                _this.setCookie("speed", parseInt(document.getElementById(_this.selectSpeedId).value));
            }
            if (_this.selectFrontStyleDom !== null) {
                _this.setCookie("frontStyle", parseInt(_this.selectFrontStyleDom.options[_this.selectFrontStyleDom.selectedIndex].value));
            }
            if (_this.selectBackStyleDom !== null) {
                _this.setCookie("backStyle", parseInt(_this.selectBackStyleDom.options[_this.selectBackStyleDom.selectedIndex].value));
            }
            if (document.getElementById(_this.inputMemorySizeId) !== null) {
                _this.setCookie("size", parseInt(document.getElementById(_this.inputMemorySizeId).value));
            }
        }
    },
    setCookieStartAction: function (_this) {
        if (_this.cookies && _this.cookieStartValue === 2) {
            _this.setCookie("amountPairs", _this.amountPairs);
            _this.setCookie("countPairs", _this.countPairs);
            _this.setCookie("speed", _this.speed);
            _this.setCookie("size", _this.size);
            _this.setCookie("frontStyle", _this.frontStyle);
            _this.setCookie("backStyle", _this.backStyle);
        }
    },
    startAction(_this) {
        document.getElementById(_this.generateMemoryBtnId).addEventListener("click", function () {
            _this.showLoader(_this);
            _this.hideWelcomeMessages(_this);
            _this.reset(_this);

            if (document.getElementById(_this.inputMemoryPairsId) !== null) {
                _this.amountPairs = parseInt(document.getElementById(_this.inputMemoryPairsId).value);
            }
            if (document.getElementById(_this.inputMemoryPairsCountId) !== null) {
                _this.countPairs = parseInt(document.getElementById(_this.inputMemoryPairsCountId).value);
            }
            if (document.getElementById(_this.selectSpeedId) !== null) {
                _this.speed = parseInt(document.getElementById(_this.selectSpeedId).value);
            }
            if (_this.selectFrontStyleDom !== null) {
                _this.frontStyle = parseInt(_this.selectFrontStyleDom.options[_this.selectFrontStyleDom.selectedIndex].value);
            }
            if (_this.selectBackStyleDom !== null) {
                _this.backStyle = parseInt(_this.selectBackStyleDom.options[_this.selectBackStyleDom.selectedIndex].value);
            }
            if (document.getElementById(_this.inputMemorySizeId) !== null) {
                _this.size = parseInt(document.getElementById(_this.inputMemorySizeId).value);
            }
            _this.setCookieStartAction(_this);
            _this.draw(_this);
            _this.counter = 0;
            setTimeout(function () {
                _this.hideLoader(_this);
                _this.memoryDom.scrollIntoView({behavior: "smooth"});
            }, 750);
        }, false);
    },
    setPrefilledCardActions: function (_this) {
        // require same amount as in the pressetings for success on the init or u override the variables and create own inits
        if (_this.memoryDom.getElementsByClassName(_this.memoryCardClass).length === (_this.amountPairs * _this.countPairs)) {
            let cards = _this.memoryDom.getElementsByClassName(_this.memoryCardClass);
            for (let i = 0; i < cards.length; i++) {
                _this.cardClick(_this, cards[i]);
            }
        }
    },
    initDomVariables: function (_this) {
        if (_this.memoryDom === null) {
            _this.memoryDom = document.getElementById(_this.memoryId);
        }
        if (_this.countDom === null) {
            _this.countDom = document.getElementById(_this.countId);
        }
        if (_this.selectFrontStyleDom === null) {
            _this.selectFrontStyleDom = document.getElementById(_this.selectFrontStyleId);
        }
        if (_this.selectBackStyleDom === null) {
            _this.selectBackStyleDom = document.getElementById(_this.selectBackStyleId);
        }
        if (_this.wonDom === null) {
            _this.wonDom = document.getElementById(_this.wonId);
        }
        if (_this.loaderDom === null) {
            _this.loaderDom = document.getElementById(_this.memoryLoaderId);
        }
    },
    fetchEmojis: function (_this) {
        if (_this.emojis === null) {
            fetch(_this.emojiUrl)
                    .then(function (response) {
                        return response.json();
                    })
                    .then(function (data) {
                        _this.emojis = data;
                    })
                    .catch(function (error) {
                        _this.emojis = [];
                    });
        }
        if (_this.emojiCategories === null) {
            fetch(_this.emojiCategoriesUrl)
                    .then(function (response) {
                        return response.json();
                    })
                    .then(function (data) {
                        _this.emojiCategories = data;
                    })
                    .catch(function (error) {
                        _this.emojiCategories = [];
                    });
        }
    },
    fetchSingleImages: function (_this) {
        if (_this.preFetchImages === true) {
            document.addEventListener("DOMContentLoaded", async function () {
                for (let i = 0; i < _this.images.length; i++) {
                    if (_this.images[i].indexOf('http') === 0) {
                        fetch(_this.images[i]);
                    }
                }
            }, false);
        }
    },
    fetchImages: function (_this) {
        if (typeof (_this.memoryDom.dataset.imagesSrc) !== "undefined") {
            _this.imageUrl = _this.memoryDom.dataset.imagesSrc;
        }
        if (_this.images === null) {
            fetch(_this.imageUrl)
                    .then(function (response) {
                        return response.json();
                    })
                    .then(function (data) {
                        _this.images = data;
                        _this.fetchSingleImages(_this);
                    })
                    .catch(function (error) {
                        _this.images = [];
                    });
        }
    },
    initDomActions: function (_this) {
        _this.initDomVariables(_this);
        _this.startAction(_this);
        _this.setPrefilledCardActions(_this);
    },
    eraseCookie: function (name) {
        let d = new Date;
        d.setTime(d.getTime() - 24 * 60 * 60 * 1000 * 1);
        document.cookie = name + "=;secure=true;path=/;expires=" + d.toGMTString();
    },
    eraseAllCookies: function () {
        let _this = Memory;
        _this.cookies = false;
        _this.cookieSaveHighscore = 0;
        _this.cookieStartValue = 0;

        _this.eraseCookie("amountPairs");
        _this.eraseCookie("countPairs");
        _this.eraseCookie("speed");
        _this.eraseCookie("size");
        _this.eraseCookie("frontStyle");
        _this.eraseCookie("backStyle");
        _this.eraseCookie("highscorePairs");
        _this.eraseCookie("highscorePairsCount");
        _this.eraseCookie("highscoreCount");
        _this.eraseCookie("cookieStartValue");
        _this.eraseCookie("cookieSaveHighscore");
        
    },
    getCookie: function (name) {
        let v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
        return v ? v[2] : null;
    },
    setCookie: function (name, value, days = 365) {
        let d = new Date;
        d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
        document.cookie = name + "=" + value + ";secure=true;path=/;expires=" + d.toGMTString();
    },
    getInt: function (value, defaultValue = 0) {
        return isNaN(parseInt(value)) ? defaultValue : parseInt(value);
    },
    fillForm: function (_this) {
        if (document.getElementById(_this.inputMemoryPairsId) !== null) {
            document.getElementById(_this.inputMemoryPairsId).value = _this.amountPairs;
        }
        if (document.getElementById(_this.inputMemoryPairsCountId) !== null) {
            document.getElementById(_this.inputMemoryPairsCountId).value = _this.countPairs;
        }
        if (document.getElementById(_this.selectSpeedId) !== null) {
            document.getElementById(_this.selectSpeedId).value = _this.speed;
        }
        if (_this.selectFrontStyleDom !== null) {
            _this.selectFrontStyleDom.value = _this.frontStyle;
        }
        if (_this.selectBackStyleDom !== null) {
            _this.selectBackStyleDom.value = _this.backStyle;
        }
        if (document.getElementById(_this.inputMemorySizeId) !== null) {
            document.getElementById(_this.inputMemorySizeId).value = _this.size;
        }
    },
    loadFromCookies(_this) {
        _this.cookieSaveHighscore = _this.getInt(_this.getCookie("cookieSaveHighscore"));
        _this.cookieStartValue = _this.getInt(_this.getCookie("cookieStartValue"));

//
//gulp.task('copy-resources', [ 'copy-media', 'copy-data', 'copy-favicon', 'copy-fonts']);
        if (_this.cookieStartValue > 0) {
            _this.cookies = true;
            _this.amountPairs = _this.getInt(_this.getCookie("amountPairs"));
            _this.countPairs = _this.getInt(_this.getCookie("countPairs"));
            _this.speed = _this.getInt(_this.getCookie("speed"));
            _this.size = _this.getInt(_this.getCookie("size"));
            _this.frontStyle = _this.getInt(_this.getCookie("frontStyle"));
            _this.backStyle = _this.getInt(_this.getCookie("backStyle"));
        }

        if (_this.cookieSaveHighscore > 0) {
            _this.cookies = true;
            _this.highscorePairs = _this.getInt(_this.getCookie("highscorePairs"));
            _this.highscorePairsCount = _this.getInt(_this.getCookie("highscorePairsCount"));
            _this.highscoreCount = _this.getInt(_this.getCookie("highscoreCount"));
        }
    },
    init: function (preFetchImages = false, enforceCookies = false) {
        let _this = this;
        if (preFetchImages) {
            _this.preFetchImages = true;
        }
        _this.loadFromCookies(_this);
        if (!_this.cookies && enforceCookies) {
            _this.cookies = true;
            _this.setCookieSaveHighscore(1);
            _this.setCookieStartValue(2);
        }
        if (document.getElementById(_this.memoryId) === null) {
            document.addEventListener("DOMContentLoaded", function () {
                if (document.getElementById(Memory.memoryId) === null) {
                    _this.initDomActions();
                    _this.showHighscore(_this);
                    _this.fillForm(_this);
                }
            }, false);
        } else {
            _this.initDomActions(_this);
            _this.showHighscore(_this);
            _this.fillForm(_this);
        }
        _this.fetchEmojis(_this);
        _this.fetchImages(_this);
    }
};


//Memory.init();
