/*!
 * Google Firebase Cloud Firestore functions for Thorium Mobile projects
 * Version 4.0 April, 2024
 * framework7 v8.x (https://framework7.io)
 * Google firebase (https://firebase.google.com)
 * framework7: MIT Licensed
 * Copyright 2018-2024 Thorium builder.
*/


var firestoredb = firebase.firestore();

var firestorePlugin = {
    name: "Thorium Builder Firestore Plugin",
    bundleid: "com.thoriumbuilder.firestore",
    version: "4.0",
    shoppingCartPopup: null,
    currentItem: {},

    convertFormData: function (fld, key, value, formData) {
        //Generic function: Convert Memory data to Form Data for 
        //a Given Form (used from singleRecordFormInit & fillFormFromData)
        //And fill all inputs with values
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] converting Form data");
        var isShadow = fld.classList.contains("shadow-text");
        if (fld.type == 'checkbox') {
            if ((value === 'true') || (value === true) || (value === '1') || (value === 'on')) {
                formData[key] = 'on';
                fld.setAttribute("checked", "checked");
            } else {
                formData[key] = 'off';
                fld.removeAttribute("checked");
            }

        } else if ((fld.type == 'select-one') || (fld.tagName.toLowerCase == 'select')) {
            $('#' + fld.id).attr('data-value', value);
            var fp = $('#' + fld.id).closest('.smart-select');
            if ((fp) && (fp.length > 0)) {
                var sm = app.smartSelect.get(fp);
                if (sm) { sm.setValue(value); }
            } else {
                $('#' + fld.id).val(value);
                var n = $('#' + fld.id).html().trim();
                if (n.length == 0) {
                    $('#' + fld.id).html('<option value="' + value + '">' + value + '</option>');
                }
            }
            formData[key] = value;

        } else if (fld.type == 'image') {
            $('#' + fld.id + '-fileinput-filename').css('visibility', 'hidden');
            if ((value) && (value.length > 0)) {
                $('#' + fld.id).css('background-image', 'url(' + value + ')');
                $('#' + fld.id + '-fileinput-filename span').text(value);
                $('#' + fld.id + '-remove').show();
            }

        } else if (fld.type == 'range') {
            formData[key] = value;
            var range = app.range.get(fld.parentElement);
            if (range) {
                range.setValue(value);
            } else {
                range = app.range.create(fld.parentElement);
                range.setValue(value);
            }

        } else if (isShadow == true) {
            formData[key] = value;
            var sid = fld.id.replaceAll("-shadow", '');
            var te = app.textEditor.get('#' + sid);
            if (te) {
                te.setValue(value);
            }
        } else if (fld.type == 'text') {
            fld.value = value;

        } else if (fld.type == 'textarea') {
            fld.value = value;

        } else if (fld.type == 'radio') {
            //Loop on all Radio Items
            var radioParent = fld.closest("ul");
            var radioName = fld.getAttribute("name");
            var radioButtons = radioParent.querySelectorAll("input[name='" + radioName + "']");
            for (var i = 0; i < radioButtons.length; i++) {
                const radioItem = radioButtons[i];
                const radioValue = radioItem.value;
                if (radioValue == value) {
                    radioItem.setAttribute("checked", "checked");
                } else {
                    radioItem.removeAttribute("checked");
                }
            }

        } else if (fld.type == 'file') {
            var lineIdent = fld.getAttribute("data-fileinput-ref");
            var ot = $('#' + lineIdent);
            if ((ot) && (ot.length > 0)) {
                var toto = $('#' + lineIdent + '-fileinput-filename span');
                $('#' + lineIdent + '-fileinput-filename').show();
                $('#' + lineIdent + '-fileinput-filename').css('visibility', 'visible');
                $('#' + lineIdent + '-fileinput-filename span').text(value);
                $('#' + lineIdent + '-fileinput-filename i').show();
                $('#' + lineIdent + '-fileinput-link').show();
                $('#' + lineIdent + '-fileinput-link span').html('<a class="external" target="_blank" rel="noopener" data-rel="external" target="_blank" href="' + value + '">See attached file</a>');
                if (value.length > 0) {
                    $('#' + lineIdent + '-remove').show();
                } else {
                    $('#' + lineIdent + '-fileinput-filename').css('visibility', 'hidden');
                }

            }
            formData[key] = value;
        } else {
            formData[key] = value;
            fld.value = value;
        }
        return formData;
    },

    formBeforeSubmitFunction: function (form) {
        const beforeSubmitFunc = form.getAttribute("data-form-beforesubmit");
        if (beforeSubmitFunc) {
            const fn = window[beforeSubmitFunc];
            var fnparams = [form];
            if (typeof fn === "function") {
                var r = fn.apply(this, fnparams);
                thoriumapi.logEvent(0, "[com.thoriumbuilder.core] Function [" + beforeSubmitFunc + "] Called for Form with id [" + form.id + "]");
            }
            else {
                var err = '[com.thoriumbuilder.core] An error occured "' + beforeSubmitFunc + '" is not an existing function';
                thoriumapi.logEvent(2, err);
            }
        }
    },

    updateFormData: function (e, v) {
        //Send data to firebase for updating record (v=true = Call-Back VL)
        e.preventDefault;
        var form = e.target;
        if (app.input.validateInputs(form) == false) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Missing Mandatory fields for Form with id [" + form.id + "]");
            return;
        }
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Sending Form data to Cloud Firestore");
        if (kShowPreloader==true) {app.preloader.show();}
        firestorePlugin.formBeforeSubmitFunction(form);
        app.emit('onFirestoreBeforeUpdate', e);
        var collection = e.target.getAttribute('data-firebase-collection');
        if (!(collection) || (collection.length == 0) || (collection == "null")) {
            app.preloader.hide();
            app.dialog.alert("Firebase Collection not defined");
            return;
        }
        var message = e.target.getAttribute('data-form-message') || null;
        var postprocess = e.target.getAttribute('data-form-postprocess') || 0;
        var uid = e.target.getAttribute('data-uid') || null;
        if (!uid) {
            app.preloader.hide();
            var m = "[com.thoriumbuilder.firestore] Record ID not set";
            thoriumapi.logEvent(1, m);
            app.dialog.alert(m);
            return;
        }
        var user = firebase.auth().currentUser;
        var currentRecord = firestoredb.collection(collection).doc(uid);
        if (!currentRecord) {
            var m = "[com.thoriumbuilder.firestore] Record not found";
            thoriumapi.logEvent(1, m);
            app.dialog.alert(m);
            return;
        }
        var data = {};
        var dataArray = {};
        var f = e.target;
        for (var i = 0; i < f.length; i++) {
            const x = "_alias";
            const reservedWords = ["name" + x, "id" + x, "description" + x, "this" + x, "title" + x, "submit" + x];
            var alias = f[i].name;
            if (reservedWords.includes(alias) === true) { alias = alias.replaceAll(x, ''); }
            var type = f[i].type;
            if (f[i].type == "radio") { if (f[i].checked === true) { data[alias] = f[i].value; } }
            else if (f[i].type == "checkbox") { if (f[i].checked == true) { data[alias] = true } else { data[alias] = false } }
            else if (f[i].type == "submit") { }
            else if (f[i].type == "file") {
                var oid = f[i].id;
                var blob = $('#' + oid).data("data-blob");
                var filename = $('#' + oid).data("data-filename");
                var fieldName = $('#' + oid)[0].name.replace('-fileinput', '');
                if (!(fieldName)) {
                    app.preloader.hide();
                    err = "Invalid File Reference";
                    app.emit('onFirestoreBeforeUpdateError', e.target, err);
                    app.dialog.alert("Error writing document: " + err);
                    return;
                }
                if (blob) {
                    thoriumCorePlugin.uploadFile(blob, filename, collection, uid, fieldName, currentRecord);
                } else { //Reset to Blank file
                    var id = $('#' + oid)[0].id;
                    if (id) {
                        id = id.replace('-fileinput', '');
                        var inpt = document.getElementById(id);
                        if (inpt) {
                            if (inpt.getAttribute("data-clear") == 'true') {
                                dataArray[fieldName] = '';
                            }
                        }
                    }
                }
            }
            else { data[alias] = f[i].value; }
            if ((alias) && (data[alias] != null)) {
                dataArray[alias] = data[alias];
            }
        }
        //Updating modifiedby / modifieddate
        var userid = null;
        if (user) { userid = user.uid; }
        var now = Date.now();
        dataArray['modifiedby'] = userid;
        dataArray['modifieddate'] = now;
        currentRecord.update(
            dataArray
        )
            .then(function () {
                //Update Displayers with current record
                var x = document.querySelectorAll(".firebase-form");
                for (var i = 0; i < x.length; i++) {
                    var elt = x[i];
                    if ((elt.getAttribute("data-collection") == collection) && (elt.getAttribute("data-firebase-uid") == uid)) {
                        var datamode = 1; //elt.getAttribute("data-loading-mode")||0;
                        var parentuid = elt.getAttribute("data-parent-key") || null;
                        firestorePlugin.firebase_initFirebaseDisplayer(elt, collection, uid, parentuid, datamode, null);
                    }
                }

                //Update Repeaters with current record
                var x = document.querySelectorAll(".firebase-virtual-list-content[data-collection='" + collection + "']");
                if ((x) && (x.length > 0)) {
                    for (var i = 0; i < x.length; i++) {
                        var elt = x[i];
                        var vl = app.virtualList.get(elt);
                        if ((vl) && (vl.items)) {
                            for (var j = 0; j < vl.items.length; j++) {
                                var vlItem = vl.items[j];
                                if (vlItem.uid == uid) {
                                    for (const [key, value] of Object.entries(dataArray)) {
                                        vlItem[key] = value;
                                    }
                                    vl.replaceItem(j, vlItem);
                                    vl.update();
                                    break;
                                }
                            }
                        }
                    }
                }
                app.preloader.hide();
                app.emit('onFirestoreUpdateSuccess', e.target, dataArray);
                if (message) { thoriumapi.showNotification(message); }
                //Clear Data
                var clearData = e.target.getAttribute('data-reset-form') || 'false';
                if (clearData == 'true') {
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Form Reset");
                    e.target.reset();
                    $("#" + e.target.id + " .text-editor").each(function (field) {
                        var te = app.textEditor.get('#' + field.id);
                        if (te) { te.setValue(""); }
                    });
                }
                //Post Action
                if (postprocess == 0) {
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Form Sent");
                } else if (postprocess == 1) {
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Going Back to Previous Page");
                    thoriumapi.backToPreviousPage();
                } else if (postprocess == 2) {
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Reloading Home Page");
                    thoriumapi.reloadHomePage();
                }
                //Post JS Function
                var func = e.target.getAttribute('data-return-function') || null;
                if (func) {
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Form with id [" + e.target.id + "] : Calling JS function [" + func + "]");
                    var fn = window[func];
                    var fnparams = [e.target, dataArray];
                    if (typeof fn === "function") {
                        var r = fn.apply(this, fnparams);
                        app.preloader.hide();
                        app.emit('userFormSuccess', r);
                        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] JS function [" + func + "] called successfully when submitting Form with id [" + e.target.id + "]");
                    }
                    else {
                        app.preloader.hide();
                        var err = 'An error occured "' + func + '" is not an existing function';
                        thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] JS function [" + func + "] called with Error: [" + err + "] when submitting Form with id [" + e.target.id + "]");
                        thoriumapi.showAlert(err);
                        app.emit('userFormError', err || null);
                    }
                }



            })
            .catch(function (error) {
                app.preloader.hide();
                var m = "[com.thoriumbuilder.firestore] Error Updating document: " + error.message;
                thoriumapi.logEvent(2, m);
                app.dialog.alert(m);
                return;
            });
    },

    insertDocument: function (e, t) {
        var f = e.target; //Form Reference
        if (app.input.validateInputs(f) == false) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Missing Mandatory fields for Form with id [" + f.id + "]");
            return;
        }
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Inserting Document");
        app.emit('onFirestoreBeforeInsert', t);
        firestorePlugin.formBeforeSubmitFunction(f);
        if (kShowPreloader==true) {app.preloader.show();}
        var collection = t.attr('data-firebase-collection');
        if (!(collection)) {
            app.preloader.hide();
            app.dialog.alert("Firebase Collection not defined");
            return;
        }
        var message = t.attr('data-form-message') || null;
        var postprocess = t.attr('data-form-postprocess') || 0;

        //Check Required fields
        for (var i = 0; i < f.length; i++) {
            var fld = f[i].name;
            var req = f[i].getAttribute("data-mandatory") || 'false';
            if ((f[i].type == "file") && (req) && (req == 'true')) {
                var blob = $('#' + f[i].id).data("data-blob");
                if (!(blob)) {
                    app.preloader.hide();
                    app.dialog.alert("You must select a file");
                    return;
                }
            }

        }
        //Create Blank Record in a transaction
        var data = {};
        var dataArray = {};
        var user = firebase.auth().currentUser;
        var userid = null;
        var displayName = null;
        if (user) {
            userid = user.uid;
            displayName = user.displayName;
        }
        var now = Date.now();
        dataArray['createdby'] = userid;
        dataArray['createddate'] = now;
        dataArray['createdbyname'] = displayName;
        var fk = e.target.getAttribute("data-parent-key") || null;
        if ((fk) && (fk != 'null')) {
            dataArray['parentuid'] = fk;
        }
        for (var i = 0; i < f.length; i++) {
            const x = "_alias";
            const reservedWords = ["name" + x, "id" + x, "description" + x, "this" + x, "title" + x, "submit" + x];
            var alias = f[i].name;
            if (reservedWords.includes(alias) === true) { alias = alias.replaceAll(x, ''); }
            if (f[i].type == "radio") {
                if (f[i].checked === true) { data[alias] = f[i].value; }
            }
            else if (f[i].type == "checkbox") {
                data[alias] = f[i].checked;
            }
            else if (f[i].type == "submit") { } //Nothing
            else if (f[i].type == "file") { } //Nothing, done after Insert
            else { data[alias] = f[i].value; }
            if ((alias) && (data[alias] != null)) {
                dataArray[alias] = data[alias];
            }
        }
        //Insert To Firebase
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Inserting Record in Collection " + collection);
        var record = firestoredb.collection(collection).add(
            dataArray
        )
            .catch(function (error) {
                app.preloader.hide();
                app.emit('onFirestoreInsertError', t, error);
                thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] Error writing document: " + error.message);
                app.dialog.alert("Error writing document: " + error.message);
            })
            .then(function (docRef) {
                //Post Form Process
                //-- 1° Loop on files
                for (var i = 0; i < f.length; i++) {
                    if (f[i].type == "file") {
                        var oid = f[i].id;
                        var blob = $('#' + oid).data("data-blob");
                        var filename = $('#' + oid).data("data-filename");
                        var fieldName = $('#' + oid)[0].name.replace('-fileinput', '');;
                        if (!(fieldName)) {
                            app.preloader.hide();
                            err = "Invalid File Reference";
                            thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] Error writing document, Invalid File Reference");
                            app.emit('onFirestoreBeforeUpdateError', f, err);
                            app.dialog.alert("Error writing document: " + err);
                            return;
                        }
                        if (blob) {
                            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Upload Blob to collection " + collection);
                            thoriumCorePlugin.uploadFile(blob, filename, collection, docRef.id, fieldName, docRef);
                        }
                    }
                }

                //-- 2° Finish Process
                thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] document added to collection " + collection);
                setTimeout(function () {
                    firestorePlugin.reloadVlAfterInsert(collection);
                    app.preloader.hide();
                    var clearData = e.target.getAttribute('data-reset-form') || 'false';
                    if (clearData == 'true') {
                        e.target.reset();
                        $("#" + e.target.id + " .text-editor").each(function (field) {
                            var te = app.textEditor.get('#' + field.id);
                            if (te) { te.setValue(""); }
                        });
                        $('.firebase_document_preview').css('background-image', '');
                        $('.input-filename span').html('');
                        $('.firebase_fileupload-rotate').hide();
                        $('.firebase_fileupload-remove').hide();
                        $('.input-filename i').hide();
                    }
                    if (message) { thoriumapi.showNotification(message); }
                    if (postprocess == 1) {
                        thoriumapi.backToPreviousPage();
                    } else if (postprocess == 2) {
                        thoriumapi.reloadHomePage();
                    }
                    app.emit('onFirestoreInsertSuccess', f, docRef); //3.4.1
                    //Post JS Function
                    var func = e.target.getAttribute('data-return-function') || null;
                    if (func) {
                        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Form with id [" + e.target.id + "] : Calling JS function [" + func + "]");
                        var fn = window[func];
                        var fnparams = [e.target, dataArray];
                        if (typeof fn === "function") {
                            var r = fn.apply(this, fnparams);
                            app.preloader.hide();
                            app.emit('userFormSuccess', r);
                            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] JS function [" + func + "] called successfully when submitting Form with id [" + e.target.id + "]");
                        }
                        else {
                            app.preloader.hide();
                            var err = 'An error occured "' + func + '" is not an existing function';
                            thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] JS function [" + func + "] called with Error: [" + err + "] when submitting Form with id [" + e.target.id + "]");
                            thoriumapi.showAlert(err);
                            app.emit('userFormError', err || null);
                        }
                    }
                }, 1000);
            });
    },

    singleRecordFormInit: function (f) {
        //New v2.0 SingleRecord Form
        if (f.getAttribute("data-loaded") == 'true') {
            return;
        }
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Initialize Single Record Form with ID [" + f.id + "]");
        var c = f.getAttribute("data-firebase-collection");
        if ((!c) || (c == 'null') || (c.length == 0)) {
            $(f).hide();
            thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] Collection not set for Single Record Form with ID [" + f.id + "]");
            app.dialog.alert("Firebase Collection not set!");
            return;
        }
        var user = firebase.auth().currentUser;
        if ((!user) || (user.isAnonymous == true)) {
            $(f).hide();
            app.preloader.hide();
            thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] User not Connected, unable to Initialize Single Record Form with ID [" + f.id + "]");
            return;
        }
        var formData = {};
        f.setAttribute('data-uid', user.uid);
        var currentRecord = firestoredb.collection(c).doc(user.uid);
        return firestoredb.runTransaction(function (transaction) {
            // This code may get re-run multiple times if there are conflicts.
            return transaction.get(currentRecord).then(function (doc) {
                if (doc.exists) {
                    var snapshot = doc.data();
                    if (snapshot) {
                        for (var [key, value] of Object.entries(snapshot)) {
                            var fld = f.querySelector('*[name="' + key + '"]');
                            if (fld) {
                                formData = firestorePlugin.convertFormData(fld, key, value, formData);
                            }
                        }
                    }
                } else {
                    //Doc does not exists=>Create Empty Record
                    var nr = firestoredb.collection(c).doc(user.uid).set(
                        formData
                    )
                }
            });
        }).then(function () {
            $(f).show();
            f.setAttribute("data-loaded", true);
            app.emit('onFirestoreAfterFillEditForm', f, formData);
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore]  Single Record Form with ID [" + f.id + "] initialized successfully");
        }).catch(function (error) {
            f.setAttribute("data-loaded", false);
            app.preloader.hide();
            app.emit('onFirestoreSingleRecordFormInitError', f, error);
            var m = "[com.thoriumbuilder.firestore] Error on Single Record Form Initialization" + error.message;
            thoriumapi.logEvent(2, m);
            app.dialog.alert(m);
        });
    },

    firestoreRenderCollectionFromData: function (vlref, items, template) {
        vlref.innerHTML = $("#" + vlref.id + "-template")[0].outerHTML; //Clear Collection
        if (items.length == 0) {
            vlref.innerHTML = vlref.innerHTML + thoriumCorePlugin.emtyResultTemplate;
            app.preloader.hide();
        }
        if (items.length > 0) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Rendering Collection [" + items.length + " rows]");
            $("#" + vlref.id).data('items', items);
            var i = 0;
            for (var prop in items) {
                var row = items[prop];
                var itemhtml = template;
                var ti = 'id="' + vlref.id + '-template-row"';
                itemhtml = itemhtml.replace(ti, 'id="' + vlref.id + '-template-row-' + i + '"')
                for (var key in row) {
                    var datavalue = row[key];
                    if (datavalue == null) { datavalue = '&nbsp;'; }
                    itemhtml = itemhtml.replaceAll("{{" + key + "}}", datavalue);
                    itemhtml = itemhtml.replaceAll("{" + key + "}", datavalue);
                }
                itemhtml = itemhtml.replaceAll("templaterow", "");
                vlref.innerHTML = vlref.innerHTML + itemhtml;
                i = i + 1;
                if (i >= 199) { break; }
            }
            vlref.setAttribute("data-loaded", true);
            vlref.setAttribute("data-count", items.length);
            app.preloader.hide();
        }
    },

    /*-- Get Repeater Data and Render Display --*/
    firestoreGetRepeaterData: function (vlref, parentuid) {
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Get Repeater data");
        var uid = vlref.id;
        if ((parentuid) && (parentuid.length > 0)) {
            vlref.setAttribute('data-parent-key', parentuid);
        }
        parentuid = vlref.getAttribute('data-parent-key');

        vlref.setAttribute("data-loaded", true);
        if (kShowPreloader==true) {app.preloader.show();}
        var templateId = uid + "-template";
        var ref = document.getElementById(templateId);
        var template;
        if (!(ref)) {
            template = $('#' + uid).data("template");
        } else {
            template = ref.innerHTML;
        }
        if (template.length == 0) {
            thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] Unable to get Template for Repeater with ID [" + uid + "]");
            app.preloader.hide();
            return;
        }
        $('#' + uid).data("template", template);
        var items = [];
        const f = vlref.getAttribute('data-filter-field');
        const o = vlref.getAttribute('data-filter-operator');
        const v = vlref.getAttribute('data-filter-value');
        const f2 = vlref.getAttribute('data-filter-field2');
        const o2 = vlref.getAttribute('data-filter-operator2');
        const v2 = vlref.getAttribute('data-filter-value2');
        const t = vlref.getAttribute('data-template');
        const limit = vlref.getAttribute('data-limit') || null;
        const order = vlref.getAttribute('data-order-field') || null;
        const usronly = vlref.getAttribute('data-user-data') == "true" || false;
        const isCollectionMode = vlref.getAttribute('data-collection-mode') == "true" || false;
        var collection = vlref.getAttribute('data-collection') || null;
        if (!collection) {
            app.preloader.hide();
            app.emit('firebaseVirtualListLoadError', $(this), "Collection not Defined");
            app.dialog.alert("Error getting documents, Collection not Defined");
            return;
        }
        var query = firestoredb.collection(collection);
        if (parentuid) {
            try {
                query = query.where('parentuid', '==', parentuid);
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(thoriumapi.txtToUrl(e.message));
                return;
            }
        }

        //First Criteria
        if (f) {
            var sv = "";
            if (v == "false") { sv = false; }
            else if (v == "true") { sv = true; }
            else { sv = v; }
            if (v == '{useruid}') {
                sv = firebase.auth().currentUser.uid;
            }
            //Dynamic Variables
            if ((v.indexOf("{") >= 0) && (v.indexOf("}") >= 0)) {
                const varname = v.replace("{", "").replace("}", "");
                if ((varname) && (varname.length > 0)) {
                    var varValue = "";
                    try {
                        varValue = window[varname];
                    }
                    catch (err) {
                        app.preloader.hide();
                        var m = "[com.thoriumbuilder.firestore] Unable to find variable " + varname + "] " + err;
                        app.dialog.alert(m);
                        return;
                    }
                    if (varValue) {
                        sv = varValue;
                    } else {
                        app.preloader.hide();
                        var m = "[com.thoriumbuilder.firestore] variable [" + varname + "] is undefined";
                        app.dialog.alert(m);
                        return;
                    }
                }
            }

            try {
                query = query.where(f, o, sv);
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(e.message);
                return;
            }
        }
        //Second criteria
        if (f2) {
            var sv;
            if (v2 == "false") { sv = false; }
            else if (v2 == "true") { sv = true; }
            else { sv = v2; }
            if (v2 == '{useruid}') {
                sv = firebase.auth().currentUser.uid;
            }
            //Dynamic Variables
            if ((v2.indexOf("{") >= 0) && (v2.indexOf("}") >= 0)) {
                const varname = v2.replace("{", "").replace("}", "");
                if ((varname) && (varname.length > 0)) {
                    var varValue = "";
                    try {
                        varValue = window[varname];
                    }
                    catch (err) {
                        app.preloader.hide();
                        var m = "[com.thoriumbuilder.firestore] Unable to find variable " + varname + "] " + err;
                        app.dialog.alert(m);
                        return;
                    }
                    if (varValue) {
                        sv = varValue;
                    } else {
                        app.preloader.hide();
                        var m = "[com.thoriumbuilder.firestore] variable [" + varname + "] is undefined";
                        app.dialog.alert(m);
                        return;
                    }
                }
            }

            try {
                query = query.where(f2, o2, sv);
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(e.message);
                return;
            }
        }

        if (usronly == true) {
            var u = firebase.auth().currentUser;
            try {
                query = query.where('createdby', '==', u.uid);
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(e.message);
                return;
            }
        }
        if ((limit) && (limit > 0)) {
            try {
                query = query.limit(parseInt(limit));
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(e.message);
                return;
            }
        }
        if (order) {
            var w = vlref.getAttribute('data-order-way') || "asc";
            try {
                query = query.orderBy(order, w);
            }
            catch (e) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), e.message);
                app.dialog.alert(e.message);
                return;
            }
        }

        query.get()
            .then(function (querySnapshot) {
                var i = 0;
                querySnapshot.forEach(function (doc) {
                    var item = {};
                    item = doc.data();
                    for (var key in item) {
                        if (item[key] == null) { item[key] = '&nbsp;'; }
                        if (key == "thorium_count_likes") {
                            var cnt = item[key];
                            if (cnt == 1) { item[key] = "1 like" }
                            else if (cnt > 1) { item[key] = cnt + " likes" }
                        }
                    }
                    item["dataindex"] = i;
                    item["uid"] = doc.id;
                    if ((!item["thorium_comments_count"]) || (item["thorium_comments_count"].length == 0)) {
                        item["thorium_comments_count"] = "";
                    }
                    if ((!item["thorium_count_likes"]) || (item["thorium_count_likes"].length == 0)) {
                        item["thorium_count_likes"] = "";
                    }


                    items.push(item);
                    i = i + 1;
                });

                if (isCollectionMode == true) {
                    firestorePlugin.firestoreRenderCollectionFromData(vlref, items, template);
                } else {
                    thoriumCorePlugin.virtuallist.renderVirtualListFromData(vlref, items, template);
                }
                app.emit('firebaseVirtualListLoadSuccess', vlref, items.length, items);
            })
            .catch(function (error) {
                app.preloader.hide();
                app.emit('firebaseVirtualListLoadError', $(this), error);
                //app.dialog.alert("Error getting documents: " + error);
                app.dialog.alert(thoriumapi.txtToUrl(error.message));
                return;
            });
    },

    firebase_initFirebaseVirtualLists: function (reload, key) {
        reload = reload || false;
        key = key || null;
        var user = firebase.auth().currentUser;
        if (user) {
            reload = reload || false;
            var x = document.querySelectorAll(".firebase-virtual-list-content");
            for (var i = 0; i < x.length; i++) {
                var elt = x[i];
                var loaded = elt.getAttribute("data-loaded") || "false";
                if ((loaded != "true") || (reload == true)) {
                    firestorePlugin.firestoreGetRepeaterData(elt, key);
                }
            }
        }
    },

    firebase_initFirebaseDisplayer: function (form, c, uid, parentuid, datamode, data) {
        //Form Ref || Collection
        //datamode: 0=Memory 1=Record with ID  2=SingleRecord 3=PArent Record
        datamode = datamode || 0;
        parentuid = parentuid || null;
        data = data || null;
        var item = [];
        var user = firebase.auth().currentUser;
        if (((!user) || (user.isAnonymous == true)) && (datamode == 2)) {
            thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] User not Connected, unable to Initialize Displayer with ID [" + form.id + "]");
            form.style.display = "none";
            return;
        }
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Initialize Displayer with id [" + form.id + "]");
        var ctnr = form.closest('.page-content');
        if (ctnr) {
            app.preloader.showIn(ctnr)
        };
        var currentRecord;
        var uidp;
        if (datamode == 0) {
            return;
        }
        else if (datamode == 1) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Displayer [" + form.id + "] Initialization Mode : Load from UID [" + uid + "]) ");
            currentRecord = firestoredb.collection(c).doc(uid);
        }
        else if (datamode == 2) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Displayer [" + form.id + "] Initialization Mode : Load User Record for user with uid [" + user.uid + "]) ");
            currentRecord = firestoredb.collection(c).doc(user.uid);
        }
        else if (datamode == 3) {
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Displayer [" + form.id + "] Initialization Mode : Load User Owner Record from Firebase Collection [" + c + "] UID [" + uid + "]) ");
            var createdby = data.createdby;
            currentRecord = firestoredb.collection("thorium.users").doc(createdby);
        }
        else if (datamode == 4) {
            if (data) {
                if (data.parentuid) {
                    var p = data.parentuid;
                    thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Displayer [" + form.id + "] Initialization Mode : Load Parent Record from Firebase Collection [" + c + "] UID [" + p + "]) ");
                    currentRecord = firestoredb.collection(c).doc(p);
                }
            } else {
                thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] No Record Found for Displayer [" + form.id + "]");
            }

        }

        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Call Firebase Transaction for  Displayer with id [" + form.id + "]");
        return firestoredb.runTransaction(function (transaction) {
            return transaction.get(currentRecord).then(function (doc) {
                if (doc.exists) {
                    var snapshot = doc.data();
                    for (var [key, value] of Object.entries(snapshot)) {
                        item[key] = value;
                    }
                    firestorePlugin.fillDisplayerFromData(form, item, null, null, c);
                    form.style.display = "block";
                } else {
                    thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] No Record Found for Displayer [" + form.id + "]");
                    if (ctnr) { app.preloader.hideIn(ctnr); }
                    form.style.display = "none";
                }
            });
        }).then(function () {
            if (ctnr) { app.preloader.hideIn(ctnr); }
            form.setAttribute("data-loaded", true);
            app.emit('onFirestoreAfterFillEditForm', form, item);
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore]  Single Record Form with ID [" + form.id + "] initialized successfully");
        }).catch(function (error) {
            form.setAttribute("data-loaded", false);
            if (ctnr) { app.preloader.hideIn(ctnr); }
            form.style.display = "none";
            app.emit('onFirestoreSingleRecordFormInitError', form, error);
            var m = "[com.thoriumbuilder.firestore] Error on Single Record Form with ID [" + form.id + "] Initialization" + error.message;
            thoriumapi.logEvent(2, m);
            app.dialog.alert(m);
        });
    },

    firebase_initFirebaseDisplayers: function (reload, parentuid) {
        reload = reload || false;
        parentuid = parentuid || null;
        var user = firebase.auth().currentUser;
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Initializing all Firebase Displayers");
        if (user) {
            reload = reload || false;
            $(".firebase-form[data-loading-mode]").each(function (field) {
                var datamode = field.getAttribute("data-loading-mode") || 0;
                var dataLoaded = field.getAttribute("data-loaded") || false;
                if (((datamode > 0) && (dataLoaded == false)) || ((datamode > 0) && (reload == true))) {
                    var collection = field.getAttribute("data-firebase-collection");
                    var uid = field.getAttribute("data-firebase-uid");
                    var datamode = field.getAttribute("data-loading-mode") || 0;
                    firestorePlugin.firebase_initFirebaseDisplayer(field, collection, uid, parentuid, datamode);
                }
            });
        }
    },

    filterButtonclick: function (e) {
        app.emit('firebaseFilterBtnClick', e);
        var vl = e.target.getAttribute('data-filter-virtuallist');
        var virtualList = app.virtualList.get('#' + vl);
        if (virtualList) {
            app.virtualList.destroy(virtualList);
        }
        var obj = document.getElementById(vl);
        if (obj) {
            const f = e.target.getAttribute('data-filter-field') || '';
            const o = e.target.getAttribute('data-filter-operator') || '==';
            const v = e.target.getAttribute('data-filter-value') || '';
            const f2 = e.target.getAttribute('data-filter-field2') || '';
            const o2 = e.target.getAttribute('data-filter-operator2') || '==';
            const v2 = e.target.getAttribute('data-filter-value2') || '';
            const limit = e.target.getAttribute('data-limit') || '';
            const order = e.target.getAttribute('data-order-field') || '';
            const way = e.target.getAttribute('data-order-way') || 'asc';
            const usronly = e.target.getAttribute('data-user-data') || false;
            obj.setAttribute('data-filter-field', f);
            obj.setAttribute('data-filter-operator', o);
            obj.setAttribute('data-filter-value', v);
            obj.setAttribute('data-filter-field2', f2);
            obj.setAttribute('data-filter-operator2', o2);
            obj.setAttribute('data-filter-value2', v2);
            obj.setAttribute('data-limit', limit);
            obj.setAttribute('data-order-field', order);
            obj.setAttribute('data-order-way', way);
            obj.setAttribute('data-user-data', usronly);
            firestorePlugin.firestoreGetRepeaterData(obj);
        }
    },

    fillFormFromData: function (form, data, rowindex, parentvlid, collection) {
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Loading Data for Form with ID: [" + form.id + "]");
        var loaded = form.getAttribute("data-loaded") == 'true' || false;
        if (loaded == true) {
            app.preloader.hide();
            return;
        }
        if (!data) {
            app.preloader.hide();
            $("#" + form.id).hide();
            app.dialog.alert('Record not found!');
            return;
        }
        app.emit('onFirestoreBeforeFillEditForm', form);
        $("#" + form.id).attr("data-uid", data['uid']);

        if (!collection) {
            app.preloader.hide();
            var m = "[com.thoriumbuilder.firestore] Missing Firebase Collection Name: [" + form.id + "]";
            thoriumapi.logEvent(2, m);
            app.dialog.alert(m);
            return;
        }
        form.setAttribute("data-firebase-collection", collection);
        var currentRecord = firestoredb.collection(collection).doc(data['uid']);
        if (!currentRecord) {
            app.preloader.hide();
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] No Record found for Form with ID: [" + form.id + "]");
            app.dialog.alert('Record not found!');
            return;
        }
        var formData = {};
        currentRecord.get().then(function (doc) {
            if (doc.exists) {
                var snapshot = doc.data();
                for (var [key, value] of Object.entries(snapshot)) {
                    var fld = form.querySelector('*[name="' + key + '"]');
                    if (fld) {
                        firestorePlugin.convertFormData(fld, key, value, formData);
                    }
                }
                //app.form.fillFromData("#" + f.id, formData); Actually Done by convertFormData
                form.setAttribute("data-loaded", true);
                form.setAttribute("data-row-index", rowindex);
                form.setAttribute("data-virtuallist-id", parentvlid);
                app.emit('onFirestoreAfterFillEditForm', form, Object.entries(snapshot));
                setTimeout(function () { app.preloader.hide(); }, 1000);
            } else {
                app.preloader.hide();
                app.dialog.alert("No such document!");
            }
        }).catch(function (error) {
            app.preloader.hide();
            thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Error while loading data for Form with ID: [" + form.id + "] :" + error);
            app.emit('onFirestoreBeforeFillEditFormError', form, error);
            app.dialog.alert("Error getting document: " + error);
        });
    },

    setDisplayerMap: function (field, latlng, lat, lng) {
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Set Displayer Map Content");

        if ((!latlng) && (!(lat) && !(lng))) {
            thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] invalid coordinates ");
            return;
        }

        var engine = field.getAttribute("data-engine") || '';
        var item = {};
        item.latitude = 0;
        item.longitude = 0;
        item.target = '';
        if ((lat.length > 0) && (lng.length > 0)) {
            item.latitude = lat;
            item.longitude = lng;
        }
        else if (latlng) {
            var res = latlng.split(",");
            if (res.length == 2) {
                item.latitude = res[0];
                item.longitude = res[1];
            }
        }
        item.name = item.latitude + "-" + item.longitude;
        var mapObject = document.getElementById(field.id);
        var datazoom = mapObject.getAttribute("data-zoom") || 5;
        mapObject.setAttribute("data-zoom", datazoom);
        mapObject.setAttribute("data-lat", item.latitude);
        mapObject.setAttribute("data-lng", item.longitude);

        if ((engine == 'googlemap') && (typeof googleMapPlugin !== 'undefined')) {
            var dataMarkers = Base64.encode(('[{"name":  "' + item.name.escapeSpecialChars() + '",' +
                '"lat":  ' + item.latitude + ',' +
                '"lng":  ' + item.longitude +
                '}]'));
            mapObject.setAttribute('data-markers', dataMarkers);
            googleMapPlugin.initializeMap(field.id);
        }
        else if ((engine == 'osm') && (typeof openStreetMapPlugin !== 'undefined')) {
            var map = openStreetMapPlugin.initMap(field.id);
            openStreetMapPlugin.addMarkerAt(map, item.latitude, item.longitude, item);
        }
    },

    fillDisplayerFromData: function (form, data, parentuid, rowindex, collection) {
        $("#" + form.id + " [data-firebase-field]").each(function (firebaseField) {
            var tag = firebaseField.tagName.toLowerCase();
            var c = firebaseField.className.toLowerCase();
            var fld = firebaseField.getAttribute("data-firebase-field");
            if ((["embed-responsive-item"].indexOf(c) > -1) && (tag != "audio") && (tag != "video")) { //IMG
                var imgContainer = firebaseField.closest(".firebase-img");
                if ((fld in data) && (data[fld])) {
                    firebaseField.style.backgroundImage = "url('" + data[fld] + "')";
                    firebaseField.style.display = 'block';
                    if (imgContainer) { imgContainer.style.display = 'block'; }
                } else {
                    firebaseField.style.display = 'none';
                    if (imgContainer) { imgContainer.style.display = 'none'; }
                }
            } else if ((["embed-responsive-item"].indexOf(c) > -1) && (tag == "video")) {  //video
                if ((fld in data) && (data[fld])) {
                    firebaseField.setAttribute("src", data[fld]);
                } else {
                    $('#' + firebaseField.id).parent().hide();
                }
            } else if (tag == "audio") {  // audio
                if ((fld in data) && (data[fld])) {
                    firebaseField.setAttribute("src", data[fld]);
                } else {
                    firebaseField.style.display = 'none';
                }
            } else if (c.includes("db-map") == true) {  // map
                var latfld = firebaseField.getAttribute("data-firebase-field-lat") || '';
                var lngfld = firebaseField.getAttribute("data-firebase-field-lng") || '';
                var lat = null;
                var lng = null;
                if ((latfld in data) && (latfld in data)) {
                    lat = data[latfld];
                    lng = data[lngfld]
                }
                if ((lat) && (lng)) {
                    firestorePlugin.setDisplayerMap(firebaseField, null, lat, lng);
                }

            } else {
                if (fld in data) {
                    var dataField = firebaseField.getAttribute("data-firebase-field") || null;
                    var lh="";
                    //V3.5
                    if (dataField) {
                        if (firebaseField.innerHTML=="" ) {lh = "{{" + dataField + "}}";}
                    }
                    if (firebaseField.innerHTML!="{{" + dataField + "}}") {
                        lh = firebaseField.innerHTML;
                    }
                    lh = lh.replaceAll("{{" + fld + "}}", data[fld]);
                    lh = lh.replaceAll("{" + fld + "}", data[fld]);
                    firebaseField.innerHTML = lh;
                    if (tag == "a") {
                        firebaseField.setAttribute("href", data[fld]);
                        lh = firebaseField.getAttribute("href");
                        if (lh) {
                            lh = lh.replaceAll("{{" + fld + "}}", data[fld]);
                            lh = lh.replaceAll("{" + fld + "}", data[fld]);
                            firebaseField.setAttribute("href", lh);
                        }

                    }
                } else {
                    firebaseField.style.display = 'none';
                }
            }
        });
        $("#" + form.id + " .firebase-action-button").each(function (obj) {
            obj.setAttribute("data-key", parentuid);
            obj.setAttribute("data-index", rowindex);
            obj.setAttribute("data-collection", collection);
            $("#" + obj.id).data('record', data);
            obj.setAttribute("data-from-displayer", true);
            var ccount = data.thorium_comments_count || "";
            $(obj).children('.tb-comments-link').attr('data-count', ccount);
        });
        $("#" + form.id + " .firebase-like").each(function (obj) {
            var clikes = data.thorium_count_likes || "";
            $(obj).children('span').html(clikes);
        });
        form.setAttribute("data-collection", collection);
        form.setAttribute("data-loaded", true);
        if ((data) && (data['uid'])) { form.setAttribute("data-firebase-uid", data['uid']); }

        $("#" + form.id).data('record', data);
        app.preloader.hide();
    },

    deleteElementFromVirtualists: function (collection, uid) {
        //Delete doc in Repeaters
        var x = document.querySelectorAll(".firebase-virtual-list-content");
        for (var i = 0; i < x.length; i++) {
            var elt = x[i];
            if (elt.getAttribute("data-collection") == collection) {
                var vl = app.virtualList.get(elt);
                if (vl) {
                    for (var j = 0; j < vl.items.length; j++) {
                        var vlItem = vl.items[j];
                        if (vlItem.uid == uid) {
                            var index = j;
                            var currItem = vl.items[index];
                            var currentRecord = firestoredb.collection(collection).doc(uid);
                            if ((currentRecord) && (currItem)) {
                                vl.deleteItem(index);
                                break;
                            }
                        }
                    }
                    for (var j = 0; j < vl.items.length; j++) {
                        var vlItem = vl.items[j];
                        vlItem.dataindex = j;
                        vl.replaceItem(j, vlItem);
                    }
                    vl.update();
                }
            }
        }
    },

    deleteDocument: function (sender) {
        var collection = sender.getAttribute('data-collection') || null;
        var uid = sender.getAttribute('data-key') || null;
        var fromDisplayer = sender.getAttribute("data-from-displayer") || null;
        if ((collection) && (uid)) {
            var doc = firestoredb.collection(collection).doc(uid);
            if (!doc) {
                app.preloader.hide();
                var error = 'Record not found';
                app.emit('onFirestoreDeleteError', vl, error);
                app.dialog.alert(error);
                return;
            }
            doc.delete()
                .then(function () {
                    firestorePlugin.deleteElementFromVirtualists(collection, uid);
                    if (fromDisplayer == "true") {
                        thoriumapi.backToPreviousPage();
                    }
                    app.preloader.hide();
                    app.emit('onFirestoreDeleteSuccess', collection, uid);
                })
                .catch(function (error) {
                    app.preloader.hide();
                    app.emit('onFirestoreDeleteError', collection, uid, error);
                    app.dialog.alert('Delete Error ' + error.message);
                    return;
                });
        }
    },


    initFormSelectWithCollection: function (obj, api, fld) {
        var user = firebase.auth().currentUser;
        if (!user) {
            app.preloader.hide();
            thoriumapi.logEvent(1, "[com.thoriumbuilder.firestore] User not Connected, unable to Initialize Select Input Form with ID [" + obj.id + "]");
            return;
        }
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Loading Data from Collection [" + api + "]");
        var query = firestoredb.collection(api);
        query = query.orderBy(fld);
        query.get()
            .then(function (querySnapshot) {
                var i = 0;
                var h = '<option value="" disabled>...</option>';
                querySnapshot.forEach(function (doc) {
                    var item = {};
                    item = doc.data();
                    h = h + '<option value="' + item[fld] + '">' + item[fld] + '</option>';
                    i = i + 1;
                });
                thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Loading Collection Data from [" + api + "] [" + i + " records]");
                app.emit('dataloadSuccess', obj);
                obj.innerHTML = h;
                //Current Value
                var v = obj.getAttribute('data-value') || '';
                if (v.length > 0) {
                    var fp = $(obj).closest('.smart-select');
                    if ((fp) && (fp.length > 0)) {
                        var sm = app.smartSelect.get(fp);
                        if (sm) { sm.setValue(v); }
                    } else {
                        obj.value = v;
                    }
                }
                $("#" + obj.id).removeClass("disabled");
                obj.setAttribute("data-loaded", "true");
                app.preloader.hide();
            })
            .catch(function (error) {
                app.preloader.hide();
                thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] Loading Data from Collection Error [" + error.message + "]");
                app.emit('firebaseLoadError', obj, error);
                app.dialog.alert(thoriumapi.txtToUrl(error.message));
                return;
            });
    },

    initialize: function () {
    },

    InitPage: function (e) {
        var p = e.detail;
        var appRoute;
        var jsonData;
        var rowindex;
        var parentvlid;
        var parentuid;
        var pcollection;
        if (p.name == "smart-select-page") { return; }
        var elt;
        thoriumapi.logEvent(0, "[com.thoriumbuilder.firestore] Initializing Page");
        if (p === page) { elt = app.root; } else { elt = p.$el; appRoute = p.route; }
        if (elt) {
            if (appRoute) {
                if (appRoute.query.data) {
                    var dtx = JSON.parse(appRoute.query.data);
                    firestorePlugin.currentItem = dtx;
                }
                jsonData = firestorePlugin.currentItem;
                rowindex = appRoute.query.rowindex || null;
                parentvlid = appRoute.query.parentvlid || null;
                parentuid = appRoute.query.key || null;
                pcollection = appRoute.query.collection || null;
                var data = jsonData;

                var user = firebase.auth().currentUser;
                if (user) {
                    firestorePlugin.firebase_initFirebaseVirtualLists(false, parentuid);
                    $(".firebase-form").each(function (form) {
                        if (form.getAttribute("data-loaded") != "true") {
                            var datamode = form.getAttribute("data-loading-mode") || 0;
                            form.setAttribute("data-parent-key", parentuid);
                            if (datamode > 0) {
                                var collection = form.getAttribute("data-firebase-collection");
                                var uid = form.getAttribute("data-firebase-uid");
                                firestorePlugin.firebase_initFirebaseDisplayer(form, collection, uid, parentuid, datamode, data);
                            } else {
                                firestorePlugin.fillDisplayerFromData(form, data, parentuid, rowindex, pcollection);
                                form.style.display = "block";
                            }
                        }
                    });
                    $(".firebase-edit-form").each(function (form) {
                        form.setAttribute("data-parent-key", parentuid);
                        firestorePlugin.fillFormFromData(form, data, rowindex, parentvlid, pcollection);
                    });
                    $(".firebase-single-form").each(function (form) {
                        firestorePlugin.singleRecordFormInit(form);
                    });

                    $(".firebase-display-form").each(function (form) {
                        form.setAttribute("data-parent-key", parentuid);
                        firestorePlugin.fillFormFromData(form, data, rowindex, parentvlid, pcollection);
                    });
                    $(".firebase-insert-form").each(function (form) {
                        form.setAttribute("data-parent-key", parentuid);
                    });
                }
                app.preloader.hide();
            }
        }
    },

    reloadVlAfterInsert: function (collection) {
        //Add new do to all Repeaters
        var user = firebase.auth().currentUser;
        if (user) {
            var x = document.querySelectorAll(".firebase-virtual-list-content");
            if (x) {
                for (var i = 0; i < x.length; i++) {
                    var elt = x[i];
                    if (elt.getAttribute("data-collection") == collection) {
                        var vl = app.virtualList.get(elt);
                        if (vl) {
                            var parentuid = elt.getAttribute('data-parent-key');
                            firestorePlugin.firestoreGetRepeaterData(elt, parentuid);
                        }
                    }
                }
            }
        }
    },

    loadLineItem: function (e, t) {
        var rowindex = t.attr('data-index') || null;
        var datakey = t.attr('data-key') || null;
        if (rowindex) {
            var o = t.parents(".firebase-virtual-list-content");
            if (o) {
                var vl = app.virtualList.get("#" + o[0].id);
                var datatarget = o.attr('data-detail') || null;
                var collection = o.attr('data-collection') || null;
                var itemSel = vl.items[rowindex];
                firestorePlugin.currentItem = itemSel;
                var view = app.view;
                var parentVl = t.closest(".virtual-list") || null;
                var parentID = null;
                if (parentVl) { parentID = parentVl[0].id; }
                var transition = parentVl.attr('data-transition');
                var options = null;
                if (transition) {
                    options = { transition: transition };
                }
                if ((view) && (view.length > 0) && (datatarget)) {
                    app.emit('firebaseVirtualListLineClick', t, rowindex, itemSel, datatarget);
                    view[0].router.navigate('/' + datatarget + '/?rowindex=' + rowindex + "&key=" + datakey + "&parentvlid=" + parentID + "&collection=" + collection, options);
                }
            }
        }
    },
};


$(document).on('click', '.btn-firebase-filter', function (e) {
    e.preventDefault;
    firestorePlugin.filterButtonclick(e);
})


/*-- Single Form  Submit--*/
$(document).on('submit', '.firebase-single-form', function (e) {
    firestorePlugin.updateFormData(e, false);
})

$(document).on('submit', '.firebase-edit-form', function (e) {
    firestorePlugin.updateFormData(e, true);
})

$(document).on('submit', '.firebase-insert-form', function (e) {
    e.preventDefault;
    firestorePlugin.insertDocument(e, $(this));
})
/* -- firebase Insert Form--*/

/*-- Virtual list line click--*/
$(document).on('click', '.item-firebase', function (e) {
    e.preventDefault();
    var ptrContent = $('.ptr-content');
    if (ptrContent) {
        if (ptrContent.hasClass("ptr-transitioning") == true) { return; }
    }
    if (e.target.classList.contains("firebase-action-button")) {
        //Preserve sub buttons action
        e.stopPropagation();
        return;
    }
    firestorePlugin.loadLineItem(e, $(this));
});


/*-- Action Button Click--*/
$(document).on('click', 'a.btn-firebase-page', function (e) {
    e.preventDefault();
    var rowindex = this.getAttribute('data-index') || null;
    var datakey = this.getAttribute('data-key') || null;
    var datatarget = this.getAttribute('data-target') || null;
    var transition = this.getAttribute('data-transition') || null;
    var dataFromDisplayer = (this.getAttribute('data-from-displayer') == 'true') || false;
    if (dataFromDisplayer == true) {
        var parentID = this.getAttribute('data-key') || null;
        var view = app.view;
        var itemSel = $(this).data('record') || null;
        firestorePlugin.currentItem = itemSel;
        var collection = this.getAttribute('data-collection') || null;
        app.emit('firebaseVirtualListLineClick', this, rowindex, itemSel, datatarget);
        view[0].router.navigate('/' + datatarget + '/'
            + '?rowindex=' + rowindex
            + "&key=" + datakey
            + "&collection=" + collection
            , { animate: true, transition: transition, reloadAll: false });
        // encodeURIComponent(JSON.stringify(itemSel))
    }
    else if (rowindex) {
        var o = $(this).parents(".firebase-virtual-list-content");
        if (o) {
            var collection;
            var vl = app.virtualList.get("#" + o[0].id);
            var itemSel = vl.items[rowindex];
            firestorePlugin.currentItem = itemSel;
            var view = app.view;
            var parentVl = $(this).closest(".virtual-list") || null;
            var parentID = null;
            if ((parentVl) && (parentVl.length > 0)) {
                parentID = parentVl[0].id;
                collection = parentVl[0].getAttribute("data-collection");
            }
            if ((view) && (view.length > 0)) {
                app.emit('firebaseVirtualListLineClick', $(this), rowindex, itemSel, datatarget);
                view[0].router.navigate('/' + datatarget + '/?rowindex=' + rowindex + "&key=" + datakey + "&parentvlid=" + parentID + "&collection=" + collection, { animate: true, transition: transition, reloadAll: false });
            }
        }
    }
});

$(document).on('click', 'a.btn-firebase-delete', function (e) {
    e.preventDefault();
    var sender = this;
    var m = this.getAttribute('data-confirm-message') || 'Delete?';
    var collection = sender.getAttribute('data-collection') || null;
    if (!collection) {
        var vl = sender.closest(".virtual-list");
        if (vl) { collection = vl.getAttribute('data-collection') || null; }
        if (!collection) {
            var displayer = sender.closest(".firebase-form");
            if (displayer) { collection = displayer.getAttribute('data-collection') || null; }
            if (!collection) {
                app.preloader.hide();
                var err = 'Unable to get Collection for this action';
                thoriumapi.logEvent(2, "[com.thoriumbuilder.firestore] " + err);
                app.dialog.alert(err);
            }
        }
    }
    sender.setAttribute('data-collection', collection);
    app.dialog.confirm(m, function () {
        setTimeout(function () {
            firestorePlugin.deleteDocument(sender);
        }, 100);
    });
});

/*-- Collection item Click--*/
$(document).on('click', '.collection-item-firebase', function (e) {
    e.preventDefault();
    var rowindex = $(this).attr('data-index') || null;
    var datakey = $(this).attr('data-key') || null;
    if (rowindex) {
        var o = $(this).parents(".firebase-virtual-list-content");
        if (o) {
            var items = o.data('items');
            var target = o.attr('data-detail') || null;
            var collection = o.attr('data-collection') || null;
            var itemSel = items[rowindex];
            firestorePlugin.currentItem = itemSel;
            var view = app.view;
            var transition = o.attr('data-transition');
            var options = null;
            if (transition) {
                options = { transition: transition };
            }
            if ((view) && (view.length > 0)) {
                view[0].router.navigate('/' + target + '/?rowindex=' + itemSel.rowindex + "&key=" + datakey + "&collection=" + collection, options);
            }
        }
    }
});

/* -- Page Init Event --*/
$(document).on('page:mounted', function (e,page) { //OK
    e.preventDefault;
    firestorePlugin.InitPage(e);
})

