/* jshint ignore:start */
document.querySelector(".container").innerHTML += ['<form class="searchbox" onclick="onFormClick(event);">',
    '<input type="text" name="search" class="searchbox-input" autocomplete="off" onkeyup="onInputKeyUp();" required>',
    '<span class="searchbox-close" onclick="closeSearchBar();">',
    '<svg id="buttonClose" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">',
    '<rect id="Rectangle_4" data-name="Rectangle 4" width="24" height="24" rx="8" fill="#eee" opacity="0" />',
    '<path id="Path_10" data-name="Path 10"',
    'd="M3.53-2.03a.751.751,0,0,1,0,1.062.751.751,0,0,1-1.062,0L0-3.438-2.47-.97a.751.751,0,0,1-1.062,0,.751.751,0,0,1,0-1.062L-1.062-4.5-3.53-6.97a.751.751,0,0,1,0-1.062.751.751,0,0,1,1.062,0L0-5.562,2.47-8.03a.751.751,0,0,1,1.062,0,.751.751,0,0,1,0,1.062L1.062-4.5,3.53-2.03Z"',
    'transform="translate(12 7) rotate(180)" fill="#707070" />',
    '</svg>',
    '</span>',
    '<button type="submit" class="searchbox-down"',
    'onclick="findInPage(false, false);">',
    '<svg id="iconArrowDown" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">',
    '<rect id="Rectangle_3" data-name="Rectangle 3" width="24" height="24" rx="8" fill="#eee" opacity="0" />',
    '<path id="Path_7" data-name="Path 7"',
    'd="M-.53-8.03a.751.751,0,0,1,1.062,0l4.5,4.5a.751.751,0,0,1,0,1.062.751.751,0,0,1-1.062,0L0-6.438-3.97-2.47a.751.751,0,0,1-1.062,0,.751.751,0,0,1,0-1.062l4.5-4.5Z"',
    'transform="translate(12 7) rotate(180)" fill="#aaa" />',
    '</svg>',
    '</button>',
    '<button type="submit" class="searchbox-up"',
    'onclick="findInPage(true, false);">',
    '<svg id="iconArrowUp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">',
    '<rect id="Rectangle_2" data-name="Rectangle 2" width="24" height="24" rx="8" fill="#eee" opacity="0" />',
    '<path id="Path_6" data-name="Path 6"',
    'd="M-.53-8.03a.751.751,0,0,1,1.062,0l4.5,4.5a.751.751,0,0,1,0,1.062.751.751,0,0,1-1.062,0L0-6.438-3.97-2.47a.751.751,0,0,1-1.062,0,.751.751,0,0,1,0-1.062l4.5-4.5Z"',
    'transform="translate(12 17.5)" fill="#aaa" />',
    '</svg>',
    '</button>',
    '<span class="searchbox-track"><span class="searchbox-count"></span></span>',
    '<span class="searchbox-icon" onclick="openSearchBar();">',
    '<svg xmlns="http://www.w3.org/2000/svg" width="23.999" height="100%" viewBox="0 0 23.999 24.004"',
    'style="display:block; margin:auto; filter: invert(1);">',
    '<path id="searchIcon-Expanded"',
    'd="M7.5-11.25A9.726,9.726,0,0,1,5.625-5.5L11.559.441A1.5,1.5,0,1,1,9.436,2.564L3.5-3.375A9.694,9.694,0,0,1-2.25-1.5,9.749,9.749,0,0,1-12-11.25,9.749,9.749,0,0,1-2.25-21,9.749,9.749,0,0,1,7.5-11.25ZM-2.25-4.5A6.752,6.752,0,0,0,4.5-11.25,6.752,6.752,0,0,0-2.25-18,6.752,6.752,0,0,0-9-11.25,6.752,6.752,0,0,0-2.25-4.5Z"',
    'transform="translate(12 21)" fill="#ddd" />',
    '</svg>',
    '</span>',
    '</form>'
].join("\n");


let _allNodes = [];
let _totalResults = 0;
let _currentResult = 0;
let _dataSet = false;

let _page;
//we need to set the data on a click-event since the div will be empty at runtime until the ixf beforeShowStage is triggered.
function setUpData() {
    if (this.isPaytable()) {
        _page = document.getElementById("paytable");
    } else {
        _page = document.getElementById("gameRules");
    }
    this.findAllTextNodes(_page.childNodes);
}

function findAllTextNodes(childNodes) {
    for (let i = 0; i < childNodes.length; i++) {
        const childNodeItem = childNodes[i];
        const id = childNodeItem["id"] ? ? "";

        if (childNodeItem.nodeType === Node.TEXT_NODE) {
            _allNodes.push({
                node: childNodeItem,
            });
        } else if (childNodeItem.hasChildNodes()) {
            findAllTextNodes(childNodeItem.childNodes);
        }
    }
}

function resetCounters() {
    _totalResults = 0;
    _currentResult = 0;

    if (lastSearch !== "") {
        lastSearch = "";
    }
}

function escapeSpecialChars(text) {
    const specialChars = ["\\", "^", "$", ".", "|", "?", "*", "+", "(", ")", "[", "]", "{", "}", " "];
    const escapedPattern = text.replace(new RegExp(`[${specialChars.join("\\")}]`, "g"), "\\$&");

    return escapedPattern;
}

function findText(text, backwards, ignoreCounting) {
    _totalResults = 0;
    const resultItems = [];

    // find text in DOM nodes and calculate number of total results
    for (let i = 0; i < _allNodes.length; i++) {
        const nodeItem = _allNodes[i];
        const nodeItemText = nodeItem.node.textContent ? ? "";
        const regExp = new RegExp(escapeSpecialChars(text), "gi");
        const results = nodeItemText.match(regExp);

        if (results !== null) {
            _totalResults += results.length;
            resultItems.push({
                node: nodeItem.node,
                results,
            });
        }
    }

    // calculate current result index
    if (_totalResults > 0 && ignoreCounting === false) {
        _currentResult = backwards === false ?
            _currentResult += 1 :
            _currentResult -= 1;

        if (backwards === false) {
            if (_currentResult > _totalResults) {
                _currentResult = 1;
            }
        } else {
            if (_currentResult < 1) {
                _currentResult = _totalResults;
            }
        }
    }

    // select current result
    let counter = 0;

    for (let i = 0; i < resultItems.length; i++) {
        const resultItem = resultItems[i];
        const searchingArea = resultItem.node.textContent ? ? "";

        let lastFindIndex = 0;
        let shouldBreak = false;

        for (let j = 0; j < resultItem.results.length; j++) {
            const searchingFor = resultItem.results[j];
            const beginIndex = searchingArea.indexOf(searchingFor, lastFindIndex);
            const endIndex = beginIndex + text.length;

            if (++counter === _currentResult) {
                selectText(resultItem.node, beginIndex, endIndex);
                shouldBreak = true;
                break;
            } else {
                lastFindIndex = endIndex;
            }
        }

        if (shouldBreak === true) {
            break;
        }
    }
}

function selectText(node, startOffset, endOffset) {
    var thisWindow;
    if (this.isPaytable()) {
        thisWindow = document.getElementById("paytableArticle");
    } else {
        thisWindow = document.getElementById("gameRulesArticle");
    }
    const selection = window.getSelection();

    if (selection !== null) {
        const range = new Range();
        range.setStart(node, startOffset);
        range.setEnd(node, endOffset);

        selection.removeAllRanges();
        selection.addRange(range);
        var _offsetY = -80;
        var top = range.endContainer.parentElement.offsetTop;
        let nextScrollTopPos = top - thisWindow.offsetTop;
        thisWindow.scrollTo({
            top: nextScrollTopPos + _offsetY
        });
    }
}

function getCounters() {
    return {
        currentResult: _currentResult,
        totalResults: _totalResults,
    };
}


/* _____________________________________________ */

const MIN_CHARS_TO_SEARCH = 1;
const TIME_AFTER_KEY_UP = 1500;

let inputBox = document.querySelector(".searchbox-input");
let searchBox = document.querySelector(".searchbox");
let searchBoxTrack = document.querySelector(".searchbox-track");
let searchBoxCount = document.querySelector(".searchbox-count");
let closeBtns = document.getElementsByClassName("closeBtn");

var gameRulesHeader = document.getElementById('gameRulesHeader');
var payTableHeader = document.getElementById('paytableHeader');

let lastSearch = "";
let timeout = undefined;

closeBtns[0].addEventListener("click", function() {
    closeSearchBar();
    _dataSet = false;
    _allNodes = [];
});
closeBtns[1].addEventListener("click", function() {
    closeSearchBar();
    _dataSet = false;
    _allNodes = [];
});

function onInputKeyUp() {
    if (timeout !== undefined) {
        window.clearTimeout(timeout);
        timeout = undefined;
    }

    if (inputBox !== null) {
        const inputVal = inputBox.value.trim();

        if (inputVal.length >= MIN_CHARS_TO_SEARCH && inputVal !== lastSearch) {
            timeout = window.setTimeout(() => {
                findInPage(false, false);
            }, TIME_AFTER_KEY_UP);
        }

        if (inputVal.length < MIN_CHARS_TO_SEARCH) {
            showSearchBoxTrack(false);
            resetCounters();
        }
    }
}

function findInPage(backwards, ignoreCounting) {
    if (inputBox !== null) {
        const inputVal = inputBox.value.trim();

        if (inputVal.length >= MIN_CHARS_TO_SEARCH) {
            if (inputVal !== lastSearch) {
                resetCounters();
            }

            findText(inputVal, backwards, ignoreCounting);
            showSearchBoxTrack(true);

            lastSearch = inputVal;
        }
    }
}

function showSearchBoxTrack(show) {
    if (searchBoxTrack !== null) {
        searchBoxTrack.style.display = show === true ? "block" : "none";
    }

    if (searchBoxCount !== null) {
        const results = getCounters();
        searchBoxCount.textContent = `${results.currentResult}/${results.totalResults}`;
    }
}

function closeSearchBar() {
    if (searchBox !== null && inputBox !== null) {
        searchBox.classList.remove("searchbox-open");
        showSearchBoxTrack(false);

        inputBox.value = "";
        inputBox.blur();

        resetCounters();
    }
}

function openSearchBar() {
    if (searchBox !== null && inputBox !== null) {
        searchBox.classList.add("searchbox-open");
        inputBox.focus();
    }
}

function onFormClick(event) {
    if (!_dataSet) {
        _dataSet = true;
        this.setUpData();
    }
    event.preventDefault();
}

function isPaytable() {
    if (document.getElementById("paytable").style.display === "block") {
        return true;
    } else {
        return false;
    }
}

//ensure we reset data when switching with buttons
var targetNode = document.getElementById('paytable');
var observer = new MutationObserver(function() {
    closeSearchBar();
    _dataSet = false;
    _allNodes = [];
});

observer.observe(targetNode, {
    attributes: true,
    childList: true
});
/* jshint ignore:end */