/**
 * GSK - Dynamic List Panel Filtering
 * Include this file in HTML admin panels to create custom forms for dynamically filtering list panels
 */

/**
 * On Form Submit
 * 1) Build name/value pairs array of form fields, consolidating multi-values with the correct delimiter
 * 2) Build custom query string from name/value pairs
 * 3) JS Reload the page
 */
$(function() {
    
    // add submit event to filter form(s)
    $(".panel_list_filters").submit(function() {
        
        // get the form into a variable
        var form = $(this);
        
        // 1) Build name/value pairs array of form fields, consolidating multi-values
        // get all form fields in our filter form(s)
        var fields = $('.panel_list_filters input, .panel_list_filters select');
        // foreach form field
        var nameValuePairs = {};
        fields.each(function() {
            
            // get name and value
            var fieldName = $(this).attr('name');
            var fieldValue = $(this).attr('value');
            
            // get delimiter based on field name (only for fields that support multi values)
            var delimiter = '';
            var supportsMulti = true;
            switch ($(this).attr('name')) {
                // AND/OR (~|)
                case 'tagName':
                    // look for a class of and, else use or
                    delimiter = ($(this).hasClass('and')) ? '~': '|';
                    break;
                // commas (,)
                case 'groupHash':
                case 'hiveHash':
                case 'postHash':
                    delimiter = ',';
                    break;
                // no other fields support multiple values
                default:
                    supportsMulti = false;
                    break;
            }
            
            // get selected value based on tagName
            var selectedValue = '';
            switch (this.tagName.toLowerCase()) {
                case 'input':
                    // switch by input type
                    switch ($(this).attr('type')) {
                        // checkbox/radio - set selected value if it's checked
                        case 'checkbox':
                        case 'radio':
                            if ($(this).attr('checked')) {
                                selectedValue = encodeURIComponent(fieldValue);
                            }
                            break;
                        // text/hidden - set selected value if the value isn't empty
                        case 'text':
                        case 'hidden':
                            if (fieldValue) {
                                selectedValue = encodeURIComponent(fieldValue);
                            }
                            break;
                        // default - next field
                        default:
                            return true;
                            break;
                    }
                    break;
                case 'select':
                    // foreach option
                    $(this).find('option').each(function() {
                        // if it's selected, set or append
                        if ($(this).attr('selected')) {
                            (selectedValue.length === 0) 
                                ? selectedValue = encodeURIComponent($(this).attr('value')) 
                                : selectedValue += delimiter + encodeURIComponent($(this).attr('value'));
                        }
                    });
                    break;
                default:
                    return true; // next field
                    break;
            }

            // if the field isn't selected (doesn't have a selected value), next field
            if (selectedValue.length === 0) {
                return true;
            // if the field name isn't in our array yet or if it doesn't support multiple values, add it
            } else if (nameValuePairs[fieldName] === undefined || !supportsMulti) {
                nameValuePairs[fieldName] = selectedValue;
            // else, consolidate existing value and new value w/ the right delimiter
            } else {
                nameValuePairs[fieldName] += delimiter + selectedValue;
            }
        });
        
        // 2) Build custom query string from name/value pairs
        // walk the name/value pairs array
        var first = true;
        var queryString = '';
        $.each(nameValuePairs, function(name, value) {
            (first) ? first = false : queryString += '&';
            queryString += name + '=' + value;
        });
        
        // 3) JS Reload the page
        // always add a ?, even if the query string is empty, else you will load the same query string as the current page
        // which might have old settings on it
        document.location = form.attr('action') + '?' + queryString;
        
        // and cancel the normal form submit
        return false;
    });
});

/**
 * On Page Load
 * Preload form fields with selected values based on the query string
 */
$(function() {
    
    // grab values from the query string
    var GETArgs = $.map(location.search.slice(1).split('&'), decodeURIComponent);
    
    // for each query string arg
    $.each(GETArgs, function() {
        
        // split into name => value
        var nameValueArray = this.split('=');
        // next arg if empty
        if (nameValueArray.length < 2) {
            return true;
        }
        // else, get name and value
        var name = nameValueArray[0];
        var value = nameValueArray[1];
        
        // value
        // replace + with spaces
        value = value.replace('+', ' ');
        
        // split into array in case its a multi value
        var values = [value];
        switch (name) {
            // AND/OR (~|)
            case 'tagName':
                values = value.split(/[~\|]/);
                break;
            // Commas (,)
            case 'groupHash':
            case 'hiveHash':
            case 'postHash':
                values = value.split(/[\,]/);
                values.push(value);
                break;
        }
        
        // if there are one or more form elements of that name (input or select)
        var matches = $('.panel_list_filters input, select').filter('[name=' + name + ']');
        matches.each(function() {
        
            // handle different elements
            switch (this.tagName.toLowerCase()) {
                case 'input':
                    switch ($(this).attr('type')) {
                        case 'text':
                            // if it's a textbox, write in value
                            $(this).attr('value', value);
                            break;
                        case 'checkbox':
                        case 'radio':
                            // if its value is in the values array, select it
                            if ($.inArray($(this).attr('value'), values) != -1) {
                                $(this).attr('checked', 'checked');
                            }
                            break;
                        default:
                            return true; // next match
                            break;
                    }
                    break;
                case 'select':
                    // foreach option
                    $(this).find('option').each(function() {
                        // if its value is in the values array, select it
                        if ($.inArray($(this).attr('value'), values) != -1) {
                            $(this).attr('selected', 'selected');
                        }
                    });
                    break;
            }
        });
    });
});