// Localization support
const messages = {
    'en': {
        'copy': 'Copy',
        'copy_to_clipboard': 'Copy to clipboard',
        'copy_success': 'Copied!',
        'copy_failure': 'Failed to copy',
    },
    'es': {
        'copy': 'Copiar',
        'copy_to_clipboard': 'Copiar al portapapeles',
        'copy_success': '¡Copiado!',
        'copy_failure': 'Error al copiar',
    },
    'de': {
        'copy': 'Kopieren',
        'copy_to_clipboard': 'In die Zwischenablage kopieren',
        'copy_success': 'Kopiert!',
        'copy_failure': 'Fehler beim Kopieren',
    },
    'fr': {
        'copy': 'Copier',
        'copy_to_clipboard': 'Copier dans le presse-papier',
        'copy_success': 'Copié !',
        'copy_failure': 'Échec de la copie',
    },
    'ru': {
        'copy': 'Скопировать',
        'copy_to_clipboard': 'Скопировать в буфер',
        'copy_success': 'Скопировано!',
        'copy_failure': 'Не удалось скопировать',
    },
    'zh-CN': {
        'copy': '复制',
        'copy_to_clipboard': '复制到剪贴板',
        'copy_success': '复制成功!',
        'copy_failure': '复制失败',
    },
    'it': {
        'copy': 'Copiare',
        'copy_to_clipboard': 'Copiato negli appunti',
        'copy_success': 'Copiato!',
        'copy_failure': 'Errore durante la copia',
    }
}

let locale = 'en'
if (document.documentElement.lang !== undefined
    && messages[document.documentElement.lang] !== undefined) {
    locale = document.documentElement.lang
}

let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT;
if (doc_url_root == '#') {
    doc_url_root = '';
}

/**
 * SVG files for our copy buttons
 */
let iconCheck = `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check" width="44" height="44" viewBox="0 0 24 24" stroke-width="2" stroke="#22863a" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <title>${messages[locale]['copy_success']}</title>
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
  <path d="M5 12l5 5l10 -10" />
</svg>`

// If the user specified their own SVG use that, otherwise use the default
let iconCopy = ``;
if (!iconCopy) {
    iconCopy = `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copy" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#000000" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <title>${messages[locale]['copy_to_clipboard']}</title>
  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
  <rect x="8" y="8" width="12" height="12" rx="2" />
  <path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" />
</svg>`
}

/**
 * Set up copy/paste for code blocks
 */

const runWhenDOMLoaded = cb => {
    if (document.readyState != 'loading') {
        cb()
    } else if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', cb)
    } else {
        document.attachEvent('onreadystatechange', function () {
            if (document.readyState == 'complete') cb()
        })
    }
}

const codeCellId = index => `codecell${index}`

// Clears selected text since ClipboardJS will select the text when copying
const clearSelection = () => {
    if (window.getSelection) {
        window.getSelection().removeAllRanges()
    } else if (document.selection) {
        document.selection.empty()
    }
}

// Changes tooltip text for a moment, then changes it back
// We want the timeout of our `success` class to be a bit shorter than the
// tooltip and icon change, so that we can hide the icon before changing back.
var timeoutIcon = 2000;
var timeoutSuccessClass = 1500;

const temporarilyChangeTooltip = (el, oldText, newText) => {
    el.setAttribute('data-tooltip', newText)
    el.classList.add('success')
    // Remove success a little bit sooner than we change the tooltip
    // So that we can use CSS to hide the copybutton first
    setTimeout(() => el.classList.remove('success'), timeoutSuccessClass)
    setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon)
}

// Changes the copy button icon for two seconds, then changes it back
const temporarilyChangeIcon = (el) => {
    el.innerHTML = iconCheck;
    setTimeout(() => {
        el.innerHTML = iconCopy
    }, timeoutIcon)
}

const addCopyButtonToCodeCells = () => {
    // If ClipboardJS hasn't loaded, wait a bit and try again. This
    // happens because we load ClipboardJS asynchronously.
    if (window.ClipboardJS === undefined) {
        setTimeout(addCopyButtonToCodeCells, 250)
        return
    }

    // Add copybuttons to all of our code cells
    const COPYBUTTON_SELECTOR = 'div.highlight pre';
    const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR)
    codeCells.forEach((codeCell, index) => {
        const id = codeCellId(index)
        codeCell.setAttribute('id', id)

        const clipboardButton = id =>
            `<button class="copybtn o-tooltip--left" data-tooltip="${messages[locale]['copy']}" data-clipboard-target="#${id}">
      ${iconCopy}
    </button>`
        codeCell.insertAdjacentHTML('afterend', clipboardButton(id))
    })

    function escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
    }

    /**
     * Removes excluded text from a Node.
     *
     * @param {Node} target Node to filter.
     * @param {string} exclude CSS selector of nodes to exclude.
     * @returns {DOMString} Text from `target` with text removed.
     */
    function filterText(target, exclude) {
        const clone = target.cloneNode(true);  // clone as to not modify the live DOM
        if (exclude) {
            // remove excluded nodes
            clone.querySelectorAll(exclude).forEach(node => node.remove());
        }
        return clone.innerText;
    }

// Callback when a copy button is clicked. Will be passed the node that was clicked
// should then grab the text and replace pieces of text that shouldn't be used in output
    function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") {
        var regexp;
        var match;

        // Do we check for line continuation characters and "HERE-documents"?
        var useLineCont = !!lineContinuationChar
        var useHereDoc = !!hereDocDelim

        // create regexp to capture prompt and remaining line
        if (isRegexp) {
            regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)')
        } else {
            regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)')
        }

        const outputLines = [];
        var promptFound = false;
        var gotLineCont = false;
        var gotHereDoc = false;
        const lineGotPrompt = [];
        for (const line of textContent.split('\n')) {
            match = line.match(regexp)
            if (match || gotLineCont || gotHereDoc) {
                promptFound = regexp.test(line)
                lineGotPrompt.push(promptFound)
                if (removePrompts && promptFound) {
                    outputLines.push(match[2])
                } else {
                    outputLines.push(line)
                }
                gotLineCont = line.endsWith(lineContinuationChar) & useLineCont
                if (line.includes(hereDocDelim) & useHereDoc)
                    gotHereDoc = !gotHereDoc
            } else if (!onlyCopyPromptLines) {
                outputLines.push(line)
            } else if (copyEmptyLines && line.trim() === '') {
                outputLines.push(line)
            }
        }

        // If no lines with the prompt were found then just use original lines
        if (lineGotPrompt.some(v => v === true)) {
            textContent = outputLines.join('\n');
        }

        // Remove a trailing newline to avoid auto-running when pasting
        if (textContent.endsWith("\n")) {
            textContent = textContent.slice(0, -1)
        }
        return textContent
    }


    var copyTargetText = (trigger) => {
        var target = document.querySelector(trigger.attributes['data-clipboard-target'].value);

        // get filtered text
        let exclude = '.linenos';

        let text = filterText(target, exclude);
        return formatCopyText(text, '', false, true, true, true, '', '')
    }

    // Initialize with a callback so we can modify the text before copy
    const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText})

    // Update UI with error/success messages
    clipboard.on('success', event => {
        clearSelection()
        temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success'])
        temporarilyChangeIcon(event.trigger)
    })

    clipboard.on('error', event => {
        temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure'])
    })
}

runWhenDOMLoaded(addCopyButtonToCodeCells)
