function restoreSavedSettings() {
    let settings = getSettings();

    if (settings !== 'undefined') {

        let json = JSON.parse(settings);

        document.querySelector("#ref").value = json.ref;
        document.querySelector("#style").value = json.style || 'style-1';
        document.querySelector("#columns").value = json.columns || 3;
        document.querySelector("#padding").value = json.padding || 3;
        document.querySelector("#lazy").checked = json.lazy_load || false;

        document.querySelector("#show-summary").checked = json.show_summary || false;
        document.querySelector("#show-button").checked = json.show_button || false;
        document.querySelector("#randomise").checked = json.randomise || false;
        document.querySelector("#number-characters").value = json.number_characters || 100;
        document.querySelector("#number-projects").value = json.number_projects || 3;
    }
}

/**
 * Register events
 *
 * When user make any change to the value, call updateSnippetHtml() function
 * updateSnippetHtml() function generates HTML content to be displayed on the snippet.
 */
function registerFormEvents() {

    // Category dropdown
    document.querySelector('#ref')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Style
    document.querySelector('#style')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Columns
    document.querySelector('#columns')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Padding
    document.querySelector('#padding')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // lazy load
    document.querySelector('#lazy')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Show summary
    document.querySelector('#show-summary')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Show button
    document.querySelector('#show-button')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Randomise
    document.querySelector('#randomise')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Number of characters
    document.querySelector('#number-characters')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });

    // Number of characters
    document.querySelector('#number-projects')
        .addEventListener('change', function (e) {
            updateSnippetHtml();
        });
}

/**
 * Generate html content.
 */
function updateSnippetHtml() {

    let id = makeId();
    let html = '';

    let ref = document.querySelector("#ref").value;
    let style = document.querySelector("#style").value;
    let columns = document.querySelector("#columns").value;
    let padding = document.querySelector("#padding").value;
    let lazy = document.querySelector("#lazy").checked;

    let showSummary = document.querySelector("#show-summary").checked;
    let showButton = document.querySelector("#show-button").checked;
    let randomise = document.querySelector("#randomise").checked;
    let numberCharacters = document.querySelector("#number-characters").value;
    let numberProjects = document.querySelector("#number-projects").value;

    let endpoint = `/api/builder/project?ref=${ref}`;

    if (style) {
        endpoint += `&style=${style}`;
    }
    if (columns) {
        endpoint += `&columns=${columns}`;
    }
    if (padding) {
        endpoint += `&padding=${padding}`;
    }
    if (lazy) {
        endpoint += `&lazy=${lazy}`;
    }

    if (showSummary) {
        endpoint += `&summary=${showSummary}`;
    }
    if (showButton) {
        endpoint += `&button=${showButton}`;
    }
    if (randomise) {
        endpoint += `&randomise=${randomise}`;
    }
    if (numberCharacters) {
        endpoint += `&characters=${numberCharacters}`;
    }
    if (numberProjects) {
        endpoint += `&limit=${numberProjects}`;
    }

    // The ajax container
    html += `<div id="${id}" class="project-builder"></div>`;

    // Append the javascript
    html += '<scr' + 'ipt>';
    html += getDocumentReadyScript();
    html += `
        docReady(function () {

            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState === XMLHttpRequest.DONE) {
                
                    if (xmlhttp.status === 200) {
                        let projectContainer = document.getElementById("${id}");
                        projectContainer.innerHTML = xmlhttp.responseText;
                        
                        if (document.body.classList.contains("web-editor")) {
                            var anchors = document.getElementsByClassName("card-link");
                            if (anchors.length > 0) {
                                for (var i = 0; i < anchors.length; i++) {
                                    anchors[i].style = "pointer-events: none; cursor: default;";
                                }
                            }
                        }

                        if (typeof lazySizes !== 'undefined') {
                            lazySizes.init();

                            if (navigator 
                                && navigator.userAgent 
                                && navigator.userAgent.indexOf('Safari') != -1 
                                && navigator.userAgent.indexOf('Chrome') == -1
                            ) {
                                const images = document.querySelectorAll('img[data-src]');
                                for (let img of images) {
                                    img.src = img.getAttribute('data-src');
                                }
                            }
                        }
                        
                    }
                }
            };
            xmlhttp.open("GET", "${endpoint}", true);
            xmlhttp.send();
        });
    `;
    html += '</scr' + 'ipt>';

    // After generate the html, put the html on the snippet by calling setHtml() method. This will render the content.
    setHtml(html);

    // We also put the custom variables on the snippet by calling setSettings() method.
    let settings = `{
        "ref": "${document.querySelector("#ref").value}",
        "style": "${document.querySelector("#style").value}",
        "columns": "${document.querySelector("#columns").value}",
        "padding": "${document.querySelector("#padding").value}",
        "lazy_load": ${document.querySelector("#lazy").checked},
        
        "show_summary": ${document.querySelector("#show-summary").checked},
        "show_button": ${document.querySelector("#show-button").checked},
        "randomise": ${document.querySelector("#randomise").checked},
        "number_characters": "${document.querySelector("#number-characters").value}",
        "number_projects": "${document.querySelector("#number-projects").value}"
    }`;

    setSettings(settings);
}

/**
 * Get document ready script
 */
function getDocumentReadyScript() {
    return `
        var docReady = function (fn) {
            var stateCheck = setInterval(function () {
                if (document.readyState !== "complete") return;
                clearInterval(stateCheck);
                try { fn() } catch (e) { }
            }, 1);
        };
    `;
}

/**
 * Get the active module
 */
function getActiveModule() {
    return parent.document.querySelector("[data-module-active]");
}

/**
 *
 * @returns {string}
 */
function getSettings() {
    let activeModule = getActiveModule(); //get active module
    return decodeURIComponent(activeModule.getAttribute('data-settings'));
}

/**
 *
 * @param html
 */
function setHtml(html) {
    parent.document.querySelector('#hidContentModuleCode').value = html;
}

/**
 *
 * @param settings
 */
function setSettings(settings) {
    parent.document.querySelector('#hidContentModuleSettings').value = settings;
}

/**
 * http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
 * @returns {string}
 */
function makeId() {
    let text = "";
    let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    for (let i = 0; i < 2; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    let text2 = "";
    let possible2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (let i = 0; i < 5; i++)
        text2 += possible2.charAt(Math.floor(Math.random() * possible2.length));

    return text + text2;
}

// restore any saved settings
restoreSavedSettings();

// Register the events
registerFormEvents();

// Update the html for the snippet
updateSnippetHtml();