var searchbase;
var baseid;
var datafile;
var showcount = 0;
var showbuttoncount = 0;
let gtf_typingTimer;
let doneTypingInterval = 500;

function load_filter() {
    pathelems = document.location.pathname.split(/\//);
    lastelem = pathelems[pathelems.length-1];
    var baseconfig = document.getElementsByClassName('generictableconfig');
    if (baseconfig.length > 0) {
        baseconfig[0].classList.forEach(function(item) {
            if (item == 'jsfiltersource') {return;}
            var keyvalue = item.split(':');
            if (keyvalue[0] == 'id') {
                baseid = keyvalue[1];
            }
            if (keyvalue[0] == 'data') {
                datafile = keyvalue[1];
            }
            if (keyvalue[0] == 'showcount') {
                showcount = keyvalue[1];
            }
            if (keyvalue[0] == 'showbuttoncount') {
                showbuttoncount = keyvalue[1];
            }
        });

        if (!baseid) {
            console.log("Base ID not found");
        }
        
        if (datafile) {
            httpRequest = new XMLHttpRequest();
            httpRequest.open("GET", "js/" + datafile, true);
            httpRequest.send();
            httpRequest.addEventListener("readystatechange", function() {
                if (this.readyState === this.DONE) {
                    searchbase = JSON.parse(this.response);
                    build_filter_buttons();
                }
            });
        } else {
            console.log("Datafile not specified");
        }
    } else {
        console.log("No configuration entry");
    }
}

function resolvetitle(key,defaulttext) {
    if (key in searchbase['buttonlabels']) {
        return(searchbase['buttonlabels'][key])
    }
    return defaulttext;
}

function sortobject(unordered) {
    const ordered = Object.keys(unordered).sort().reduce(
        (obj, key) => { 
            obj[key] = unordered[key]; 
            return obj;
        }, 
        {}
    );
    return(ordered);
}

function build_filter_buttons() {
    var searchid = '';
    var searchindex = 0;
    var label = '';
    const buttons = document.getElementById(baseid + '_tablefilter');
    var filtertitle = resolvetitle('filtertitle',"Filter Table");

    if (buttons) {
        buttons.classList.add('tablefilter');
        buttons.innerHTML = '<div class="tablefiltertitle">' + filtertitle + '</div>';

        var searchtitle = resolvetitle('searchlabel','Search Text');
        var placeholder = resolvetitle('placeholder','Search...');

        buttons.innerHTML = buttons.innerHTML + '<div class="buttongroup"><b>' + searchtitle + ':</b> <input class="filtersearchtext" spellcheck="false" autocorrect="false" type="text" size="40" placeholder="' + placeholder + '" id="' + baseid + '_filtersearchtext">' + '<button class=\"filterbutton\" id=\"filterbutton_nonereset\" onclick=\"filtersearchreset();\">Reset</button></div>';

        if ('buttons' in searchbase) {
            buttontypes = searchbase['buttons'];
            const orderedtypes = sortobject(buttontypes);

            for (type in orderedtypes) {
                cleantype = type.replace(/ /g,'_');
                label = resolvetitle(type,capitalizeFirstLetter(type));

                filters = searchbase['buttons'][type];
                buttonlength = 0;
                tempbuttons = '<div class="buttongroup"><div class="buttongrouplabel">' + label + ': </div><div class="buttongroupbuttons">';

                const orderedfilters = sortobject(filters);
                
                for (key in orderedfilters) {

                    var count = '';

                    if (showbuttoncount == 1) {
                        count = ' (' + Object.keys(searchbase['bytype'][type][key]).length + ')';
                    }

                    cleankey = key.replace(/ /g,'_');
	            tempbuttons = tempbuttons +
                        "<button class=\"filterbutton\" id=\"filterbutton_" +
                        cleantype +
                        '_' +
                        cleankey +
                        "\" onmouseover=\"filter_highlight('" +
                        cleantype +
                        '_' +
                        cleankey +
                        "');\" onmouseleave=\"filter_highlight_clear('" +
                        cleantype +
                        '_' +
                        cleankey +
                        "');\" onclick=\"filter_class('" +
                        type +
                        "','" +
                        key +
                        "',1);\">" +
                        key + count + 
                        "</button>";
                    buttonlength = buttonlength+1;
                }
                if (buttonlength > 0) {
                    buttons.innerHTML = buttons.innerHTML + tempbuttons + '</div></div>';
                }
            }
        }

        if (showcount == 1)
        {
            buttons.innerHTML = buttons.innerHTML + '<div class="tablefilterresults" id="' + baseid + '_resultcount"></div>';
        }

        buttons.innerHTML = buttons.innerHTML + '</div>';

        let myInput = document.getElementById(baseid + '_filtersearchtext');
        if (myInput) {
            myInput.addEventListener('keyup', () => {
                clearTimeout(gtf_typingTimer);
                if (myInput.value) {
                    gtf_typingTimer = setTimeout(filtersearch, doneTypingInterval);
                } else {
                    resetallrows();
                    update_count('');
                }
            });
        }
    }
    else
    {
        console.log("Couldn't find the root button item " + baseid);
    }
}

function filter_highlight(buttonid) {
    var button = document.getElementById('filterbutton_' + buttonid);
    if (button) {
        button.classList.add("filterenabled");
    }
}

function filter_highlight_clear(classname) {
    var button = document.getElementById('filterbutton_' + classname);
    if (button) {
        button.classList.remove("filterenabled");
    }
}

function resetallrows() {
    for (key in searchbase['byid']) {
        item = document.getElementById(key);
        if (item) {
            item.style.display = 'table-row';
        }
    }
}

function filtersearchreset() {
    resetallrows();

    buttons = document.getElementsByClassName("filterbutton");

    for(var i=0;i<buttons.length;i++) {
        button = buttons[i];
        button.classList.remove("filterselected");
    }

    var stinput = document.getElementById(baseid + '_filtersearchtext');
    if (stinput) {
        stinput.value = '';
    }

    update_count('');
}

function filter_class(type,classname,showhide) {
    cleantype = type.replace(/ /g,'_');
    cleanclassname = classname.replace(/ /g,'_');

    var button = document.getElementById('filterbutton_' + cleantype + '_' + cleanclassname);

    if (button) {
        var remove = 0;
        button.classList.forEach(function(item) {
            if (item == 'filterselected') {
                remove = 1;
            }
        });

        if (remove == 1) {
            button.classList.remove("filterselected");
            filtersearchreset();
            update_count('');
            return;
        }
    }

    filtersearchreset();

    buttons = document.getElementsByClassName("filterbutton");

    for(var i=0;i<buttons.length;i++) {
        button = buttons[i];
        button.classList.remove("filterselected");
    }

    var button = document.getElementById('filterbutton_' + cleantype + '_' + cleanclassname);

    if (button) {
        button.classList.toggle("filterselected");
    }

    var counter = 0;
    for(key in searchbase['byid']) {
        row = document.getElementById(key);
        if (row) {
            if (key in searchbase['bytype'][type][classname]) {
                row.style['display'] = 'table-row';
                counter = counter + 1;
            }
            else {
                row.style['display'] = 'none';
            }
        }
    }
    update_count("<b>Showing</b> " + counter + " filtered entries from full table");
}

function filtersearch() {
    var searchtext = document.getElementById(baseid + '_filtersearchtext').value.toLowerCase();

    if ((searchtext.length == 0)) {
        console.log("Resetting search");
        resetallrows();
        update_count('');
        return;
    }

    var regmatch;

    try {
        regmatch = new RegExp(searchtext,'mgi');
    }
    catch(err) {
        output.innerHTML = err.message;
        return;
    }

    var matchingitems = {};
    for(key in searchbase['bysearchtext']) {

        text = searchbase['bysearchtext'][key].toLowerCase();

        matching = text.match(regmatch);

        if (matching) {
	    matchingitems[key] = 1;
	}
    }

    var counter = 0;

    for(key in searchbase['byid']) {
        var row = document.getElementById(key);
        if (row != null) {
            if (key in matchingitems) {
                row.style['display'] = 'table-row';
                counter = counter + 1;
            }
            else {
                row.style['display'] = 'none';
            }
        }
    }
    update_count("<b>Showing</b> " + counter + " filtered entries from full table");
}

function capitalizeFirstLetter(val) {
    return String(val).charAt(0).toUpperCase() + String(val).slice(1);
}

function update_count(string) {
    if (showcount == 1) {
        var count = document.getElementById(baseid + '_resultcount');
        if (count) {
            count.innerHTML = string;
        }
    }
}

document.addEventListener("DOMContentLoaded", function(event) { load_filter(); });
