
// execute func on each element of the array pointed to by params_var_string
// func should accept 2 arguments [element index and element value, respectively]
function each_param(params_var_string, func) {

    if (typeof window[params_var_string] !== 'undefined') {
        var params_var = window[params_var_string];
        $.each(params_var, function(param, elemid) {
            if (param && elemid) {
                func(param, elemid);
            }
        });
    }
}

// return a params variable based on a params var string
// a params var is set per dashlet somewhere in the global namespace
// it is a hash of the name of the parameter => the element id containing the value
function dashlet_get_params(params_var_string) {

    var params = { };

    each_param(params_var_string, 

        function(param, elemid) {
            var val = $('#'+elemid).val();
            if (val)
                params[param] = val;
        });

    return params;
}

// return a corresponding dashlet from somewhere in that dashlets settings popup
// pass this an element that is a child of the dashlet-settings
// or the dashlet-settings element itself
function get_dashlet_from_settings($elem) {

    if (!$elem)
        return false;

    var $dashlet;
    var dashlet_id;
    if ($elem.hasClass('dashlet-settings')) {
        dashlet_id = $elem.data('dashlet-id');
    } else {
        dashlet_id = $elem.parents('.dashlet-settings').data('dashlet-id');
    }
    
    if (dashlet_id)
        $dashlet = $('#' + dashlet_id);

    if ($dashlet)
        return $dashlet;

    return false;
}

// load a url by passing an element id (or the element jquery object)
// it will pull the url based on
// the data-url attribute of the specified element
// and will pass the element values listed in data-params-var of
//   that same specified element
// it will also set its own timeout based on whether data-refresh 
//   exists and is greater than 0
// if you need to pass in additional params, you can pass an object as
//   additional_params - and if you'd like any key/values present
//   in additional_params to overwrite the same key in params
//   set overwrite_params to a truthy value
function dashlet_load_url(elemid, additional_params, overwrite_params, inline = false) {
    var $dashlet;

    if (typeof elemid !== 'undefined') {
        if (elemid.jquery) {
            $dashlet = elemid;
        } else if (typeof elemid === 'string') {
            $dashlet = $('#'+elemid);
        }
    }

    var dashlet_url = '';
    var dashlet_params_var_string = '';
    var dashlet_timer_var_string = '';
    var dashlet_refresh = 0;
    var dashlet_opacity = 1;
    var params = { };

    if ($dashlet) {

        dashlet_url = $dashlet.data('url');
        dashlet_params_var_string = $dashlet.data('params-var');
        dashlet_timer_var_string = $dashlet.data('timer-var');
        dashlet_refresh = parseInt($dashlet.data('refresh')) * 1000;
        dashlet_opacity = $dashlet.data('opacity');

        if (dashlet_url) {
            if (dashlet_params_var_string) {
                params = dashlet_get_params(dashlet_params_var_string);
            }

            if ((typeof additional_params === 'object')
                && (typeof params === 'object')) {

                // should probably be an else here
                // for support of older browsers
                if (Object.assign) {
                    if ((typeof overwrite_params !== 'undefined') 
                        && (overwrite_params)) {

                        params = Object.assign(params, additional_params);
                    } else {
                        params = Object.assign(additional_params, params);
                    }
                } else {

                    // heres where that else should be
                    // probably look something like a foreach
                }
            }

            $.ajax({
                url: dashlet_url,
                data: params,
                success: function(data) {
                    $dashlet.find('.content').html(data);
                    update_content_wrapper_size($dashlet);

                    // add the scrollable dashlet class if the dashlet is not generated inline
                    if (!inline && $('.dashlet_wrapper').length > 0) {
                        $('.dashlet_wrapper').addClass('scrollable_dashlet');
                    }
                }
            });
        }

        // REMOVED DASHLET fadeTO(OPACITY) AS IT WAS CAUSING DASHLETS TO VANSIH -AC 8/16/23

        if (dashlet_timer_var_string && dashlet_refresh > 0) {

            if (window[dashlet_timer_var_string])
                clearTimeout(window[dashlet_timer_var_string]);

            window[dashlet_timer_var_string] = setTimeout(function() { dashlet_load_url(elemid); }, dashlet_refresh);
        
        } else if (dashlet_timer_var_string && dashlet_refresh <= 0) {

            if (window[dashlet_timer_var_string])
                clearTimeout(window[dashlet_timer_var_string]);            
        }
    }
}

// update a dashlet with given data
function update_dashlet(data) {
    if (data && typeof data === 'object') {
        post_ajax_data('update_dashlet', data);
    }
}

// add a dashlet to a dashboard (via the dashletize-popup)
function add_dashlet(data) {
    if (data && typeof data === 'object') {
        data['add'] = 1;
        post_ajax_data_with_callback('update_dashlet', data, function(html) {
            html = html.trim();

            $('#child_popup_container').html('');
            display_child_popup();

            if (html == 'error') {
                $('#child_popup_container').html("<h1>Error</h1><br /><p>An error occurred processing your request.</p>");
                center_child_popup();
                fade_child_popup("red");
            } else {
                $('#child_popup_container').html("<h1 class='dashlet_added'>Dashlet Added</h1><br /><p class='dashlet_added'>The dashlet has been added and will now show up on your dashboard.</p>");
                center_child_popup();
                fade_child_popup("green");
            }
        });
    }
}

// delete a dashlet based on id
function delete_dashlet(dashlet_id) {
    if (typeof dashlet_id !== 'undefined') {
        var data = { 
            id: dashlet_id, 
            delete: 1 
        };
        post_ajax_data('update_dashlet', data);
    }
}

// update dashlet title
// pass the dashlet jquery element and the title text
function update_dashlet_title($dashlet, title) {

    var dashlet_database_id = $dashlet.data('database-id');
    if (dashlet_database_id && title) {

        var data = { 
            id: dashlet_database_id,
            settings: {
                title: title 
            }
        };
        update_dashlet(data);

        $dashlet.data("title", title);
    }
}

// update dashlet pinned property
function update_dashlet_pinned($dashlet, pinned) {

    var dashlet_database_id = $dashlet.data('database-id');
    if (dashlet_database_id && (pinned == 0 || pinned == 1)) {

        var data = { 
            id: dashlet_database_id, 
            settings: {
                pinned: pinned 
            }
        };
        update_dashlet(data);
    }
}

// update dashlet show_title property
function update_dashlet_show_title($dashlet, show_title) {

    var dashlet_database_id = $dashlet.data('database-id');
    if (dashlet_database_id && (show_title == 0 || show_title == 1)) {

        var data = { 
            id: dashlet_database_id, 
            settings: {
                show_title: show_title 
            }
        };
        update_dashlet(data);
    }    
}

// update dashlet position (top / left)
function update_dashlet_position($dashlet, top, left) {

    var dashlet_database_id = $dashlet.data('database-id');
    if (dashlet_database_id && typeof top !== 'undefined' && typeof left !== 'undefined') {

        var data = { 
            id: dashlet_database_id, 
            settings: {
                x: top, 
                y: left 
            }
        };
        update_dashlet(data);
    }
}

// update dashlet size (width / height)
function update_dashlet_size($dashlet, width, height)
{
    var dashlet_database_id = $dashlet.data('database-id');
    if (dashlet_database_id && typeof width !== 'undefined' && typeof height !== 'undefined') {
        var data = {
            id: dashlet_database_id,
            settings: {
                width: width,
                height: height
            }
        };
        update_dashlet(data);
    }

    // Update the content wrapper height
    update_content_wrapper_size($dashlet, width, height);
}

// Update content wrapper
function update_content_wrapper_size($dashlet, width, height)
{
    // Get height/width by parsing if it's not passed
    if (typeof width === 'undefined' || typeof height === 'undefined') {
        width = $dashlet.outerWidth();
        height = $dashlet.outerHeight();
    }

    var title_height = 0;

    if ($dashlet.find('.title').is(':visible')) {
        title_height = $dashlet.find('.title').outerHeight();

        // -2 for border top/bottom
        var h = height - title_height + 4;
        $dashlet.find('.content-overflow').css('height', h);
    }
}

// Update dashlet title
function do_update_dashlet_title_actions(input, $text)
{
    var update = true;
    var input_val = input.val();

    // if they didn't enter any text, use the placeholder as value
    if (input_val == '') {
        update = false;
        input_val = input.attr('placeholder');
    }

    // Sanatize input val
    input_val = String(input_val).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');

    $text.html(input_val).removeClass('dragging');
    input.remove();

    update_dashlet_title($text.parents('.dashlet'), input_val);

    // we also need to update the title in the common settings area
    if (update) {
        var dashlet_settings_id = $text.parents('.dashlet').attr('id') + '_settings';
        var $dashlet_settings = $('#' + dashlet_settings_id);
        if ($dashlet_settings.hasClass('dashlet-settings') && $dashlet_settings.hasClass('managed')) {
            var $title = $dashlet_settings.find('input.title');
            $title.val(input_val);
            $title.data('default', input_val);
        }
    }
}

// on page load
// miscellaneous bindings
$(function() { 
    // Applys opacity value only to the background of the dashlet -AC
    if ($('.dashlet').length > 0) {
        for (var inc = 0; inc < $('.dashlet').not(".inline").length; inc++){
            var dashlet = $('#' + $('.dashlet').not(".inline")[inc]['id'])
            var dashlet_settings = $('#' + $('.dashlet')[inc]['id'] + '_settings')
            var dashlet_bgcolor = dashlet_settings.find('input.bgcolor').val()
            var dashlet_opacity = dashlet_settings.find('input.opacity').val()
            
            dashlet.css('background-color', tinycolor('#' + dashlet_bgcolor).setAlpha(dashlet_opacity).toRgbString())
        }
    }

    // make dashlets have borders when you press mouse on one of them
    $('.dashlet').on('mousedown', function() {
        $('.dashlet').addClass('show-border');
    }).on('mouseup', function() {
        $('.dashlet').removeClass('show-border');
    });

    // center any 'loading dashlet' throbbers
    $('.dashlet .content .loading').each(function(index) {
        $(this).position({
            my: "center",
            at: "center",
            of: $(this).parents('.content-overflow')
        });

        // make sure that the loading div is properly contained in the parent
        // if it isn't, we just fall back to a tiny spinner.
        if ($(this).offset().top < $(this).parent().offset().top) {
            $(this).find("i").remove();
            $(this).find("p").remove();
            $(this).html('<i class="fa fa-spinner fa-pulse fa-lg"></i>');
            $(this).position({
                my: "center",
                at: "center",
                of: $(this).parents('.content-overflow')
            });
        }
    });

    // change the title bar text to an input unless we grabbed the text to drag
    var is_dragging = false;

    $('.dashlet .title .text')
    .mousedown(function() { is_dragging = false; })
    .mousemove(function() { is_dragging = true; })
    .mouseup(function() {

        var was_dragging = is_dragging;
        is_dragging = false;

        if (!was_dragging && !$(this).hasClass('dragging')) {

            var $text = $(this);
            var $dashlet = $(this).parents('.dashlet');
            var z_index = $dashlet.css('z-index') + 1;
            var text_width = $dashlet.width();

            $text.addClass('dragging');
            var old_text = $text.html();

            $text.html('<input type="text" style="position: relative; width: ' + text_width + 'px; z-index: ' + z_index + ';" placeholder="' + old_text + '" />');

            var input = $text.find('input');

            // update title when user presses enter
            input.focus();

            // Bind keypress update
            input.keypress(function(keycode) {
                if (keycode.which == 13) {
                    do_update_dashlet_title_actions(input, $text);
                }
            });

            // Bind update for exiting the box
            input.focusout(function() {
                do_update_dashlet_title_actions(input, $text);
            });
        }
    });

    // show/hide title bar
    $('.dashlet .icons .toggle-title').click(function() {
        var $dashlet = $(this).parents('.dashlet');

        // show title bar
        if ($(this).hasClass('fa-eye')) {

            $(this).removeClass('fa-eye').addClass('fa-eye-slash');
            $dashlet.children('.title').show();
            update_dashlet_show_title($dashlet, 1);
        
        // remove title bar
        } else if ($(this).hasClass('fa-eye-slash')) {

            $(this).removeClass('fa-eye-slash').addClass('fa-eye');
            $dashlet.children('.title').hide();
            update_dashlet_show_title($dashlet, 0);

        }

        dashlet_load_url($(this).parents('.dashlet'));
    });

    // pin and unpin dashlet
    $('.dashlet .icons .toggle-pin').click(function() {
        var $dashlet = $(this).parents('.dashlet');

        // unpin
        if ($(this).hasClass('fa-rotate-180')) {
            $(this).removeClass('fa-rotate-180');
            $dashlet.addClass('unpinned').draggable('enable').resizable('enable');
            update_dashlet_pinned($dashlet, 0);

        // pin
        } else {
            $(this).addClass('fa-rotate-180');
            $dashlet.removeClass('unpinned').draggable('disable').resizable('disable');
            update_dashlet_pinned($dashlet, 1);
        }
    });

    // destroy dashlet
    $('.dashlet .icons .fa-close').click(function() {
        $dashlet = $(this).parents('.dashlet');
        delete_dashlet($dashlet.data('database-id'));
        $dashlet.remove();
    });

    // refresh
    $('.dashlet .icons .refresh').click(function() {
        dashlet_load_url($(this).parents('.dashlet'));
    });

    // dashletize
    $('.dashlet .dashletize i').click(function() {

        var $dashlet = $(this).parents('.dashlet');
        var dashlet_name = $dashlet.data('dashlet') || 0;
        var dashlet_title = $dashlet.data('title') || 0;
        var dashlet_params_var = $dashlet.data('params-var') || 0;

        var o = { 
            'dashlet' : dashlet_name,
            'title' : dashlet_title,
            'params': dashlet_get_params(dashlet_params_var)
        };

        post_ajax_data_with_callback('dashletize', o, function(data) {
            $('#child_popup_container').html(data);
            center_child_popup();
            display_child_popup();
            whiteout();
        });
    });
    
    // show settings
    $('.dashlet .icons .toggle-settings').click(function() {

        //whiteout();
        var dashlet_id = $(this).parents('.dashlet').attr('id');
        $('#' + dashlet_id + '_settings').center().show().draggable();

        // escape key handler
        $(document).keydown(function(keycode) {
            if (keycode.which == 27) {
                //clear_whiteout();
                $("#close_child_popup_link").click();
            }
        });
    });


    // update button for dashlet-settings popup
    // this simply:
    // updates the params elements data-defaults
    // updates the dashlet itself
    // hides the popup
    // handles updating the database if the update-dashlet button also has class update-dashlet-db
    $('.dashlet-settings .update-dashlet').click(function() {

        var $dashlet = get_dashlet_from_settings($(this));
        if ($dashlet) {

            var dashlet_database_id = $dashlet.data('database-id');
            var params_var_string = $dashlet.data('params-var');
            var settings;
            var params;

            // update the settings (this is the db portion)
            var $dashlet_settings = $(this).parents('.dashlet-settings');
            if ($dashlet_settings.hasClass("managed")) {

                var title = $dashlet_settings.find('input.title').val() || '';
                var bgcolor = $dashlet_settings.find('input.bgcolor').val() || '';
                var opacity = $dashlet_settings.find('input.opacity').val() || 1;
                var padding = $dashlet_settings.find('input.padding').val() || 10;
                var refresh = $dashlet_settings.find('input.refresh').val() || 60;
                var zindex = $dashlet_settings.find('input.zindex').val() || 1;

                // display value validation
                if ((padding < 0 || padding > 255) ||
                    (refresh < 1) ||
                    (zindex < 0)) {
                    return;
                }

                $dashlet
                .css('background-color', tinycolor('#' + bgcolor).setAlpha(opacity).toRgbString())
                .css('z-index', zindex)
                .data('refresh', refresh)
                .find('.title span.text').html(js_html_encode(title));
                
                // REMOVED DASHLET fadeTO(OPACITY) AS IT WAS CAUSING DASHLETS TO VANSIH -AC 8/16/23
                $dashlet.find('.content-overflow').css('padding', padding + 'px');

                if ($(this).hasClass('update-dashlet-db')) {
                    settings = {
                        title: title,
                        bgcolor: bgcolor,
                        opacity: opacity,
                        padding: padding,
                        refresh: refresh,
                        zindex: zindex,
                    };
                }
            }

            // update the params data defaults
            each_param(params_var_string, 

                function(param, elemid) {

                    var $elem = $('#' + elemid);
                    var val = $elem.val();

                    $elem.data('default', val);
                });

            // update the settings and params at the same time
            if ($(this).hasClass('update-dashlet-db')) {

                params = dashlet_get_params(params_var_string);

                var data = { 
                    id: dashlet_database_id, 
                    params: params, 
                    settings: settings 
                };
                update_dashlet(data);
            }

            // reload the dashlet
            dashlet_load_url($dashlet);

            // update the data-defaults in the inputs in the common settings portion
            if ($(this).parents('.dashlet-settings').hasClass('managed')) {
                $(this).parents('.dashlet-settings').find('.common-settings input').each(function(index) {
                    if ($(this).data('default')) {
                        $(this).data('default', $(this).val());
                    }
                });
            }
        }

        // hide the popup
        if ($(this).parents('.dashlet-settings').hasClass("managed")) {
            clear_whiteout();
            $(this).parents('.dashlet-settings').hide();
        }
    });

    // cancel button for dashlet-settings
    // hide the popup
    // reset the params elements back to their data-defaults
    $('.dashlet-settings .cancel-update').click(function() {

        // hide the popup
        clear_whiteout();
        $(this).parents('.dashlet-settings').hide();

        var $dashlet = get_dashlet_from_settings($(this));
        if ($dashlet) {

            // reset the param elements back to the value present in data-defaults
            each_param($dashlet.data('params-var'), 

                function(param, elemid) {

                    var $elem = $('#' + elemid);
                    var elem_default = $elem.data('default');

                    $elem.val(elem_default);
                });

            // reset the default settings elements back to the value present in data-defaults
            var $dashlet_settings = $(this).parents('.dashlet-settings');
            if ($dashlet_settings.hasClass('managed')) {
                $dashlet_settings.find('.common-settings input').each(function(index) {
                    if ($(this).data('default')) {
                        $(this).val($(this).data('default'));
                    }
                });

                // update the spectrum background selector
                var bgcolor = $dashlet_settings.find('input.bgcolor').val();
                var opacity = $dashlet_settings.find('input.opacity').val();
                $dashlet_settings.find('input.background').spectrum("set", tinycolor('#' + bgcolor).setAlpha(opacity).toRgbString());
            }
        }
    });
});

// add a dashlet to dashboard aka "dashletize"
function dashletize_add(dashlet, $btn_elem, params_var_string) {

    // sanity checks
    if (typeof dashlet === 'undefined')
        return false;
    if (typeof $btn_elem === 'undefined')
        return false;
    if (!$btn_elem.jquery)
        return false;
    if (typeof params_var_string === 'undefined')
        params_var_string = '';

    var settings = { };
    var params = dashlet_get_params(params_var_string);

    var $dashletize_popup = $btn_elem.parents('.dashletize-popup');
    var dashboard_id = $dashletize_popup.find('.dashboards').val();
    settings['title'] = $dashletize_popup.find('.title').val();
    settings['bgcolor'] = $dashletize_popup.find('.bgcolor').val();
    settings['opacity'] = $dashletize_popup.find('.opacity').val();
    settings['padding'] = $dashletize_popup.find('.padding').val();
    settings['refresh'] = $dashletize_popup.find('.refresh').val();
    settings['zindex'] = $dashletize_popup.find('.zindex').val();

    // display settings validation
    if ((settings['padding'] < 0 || settings['padding'] > 255) ||
        (settings['refresh'] < 1) ||
        (settings['zindex'] < 0)) {
        return;
    }

    var data = { 
        dashlet: dashlet, 
        dashboard_id: dashboard_id, 
        settings: settings, 
        params: params 
    };
    add_dashlet(data);

    $("#close_child_popup_link").click();
}

// cancel the add to dashboard
// just emulate clicking the popup close
function dashletize_cancel() {
    $("#close_child_popup_link").click();
}
