import { getJSONString } from '../other/helperFunctions';

/**
 * FloatingButton represents a button that is used in the floating menu in the right bottom corner
 * of the application. It may have a custom tooltip and callback on the click event
 */
class FloatingButton {
    /**
     * @param {string} buttonClass Custom string that identifies the SVG icon used on this button. This string is also added as a CSS class to the button.
     * @param {string} tooltip     tooltip for the button, that will be displayed on hover and also used as alternative title for the image
     * @param {Function} clickEvent  custom callback when user clicks the button
     * @param {App} appInstance   reference to the parent SVG element
     */
    constructor(buttonClass, tooltip, clickEvent, appInstance) {
        /**
         * jQuery element representing the button
         * @type {jQuery.element}
         */
        this.$el = $('<a>');

        // add classes to the element
        this.$el.addClass('button');
        this.$el.addClass(buttonClass);

        // add the icon
        this.$el.append(
            $('<img>')
                .attr('src', `img/gui/${buttonClass}.svg`)
                .attr('alt', tooltip)
        );

        // add the tooltip element and an event listener if tooltip is defined
        if (tooltip) {
            /**
             * jQuery element representing the tooltip
             * @type {jQuery.element}
             */
            this.$tooltip = $('<div>');
            this.$tooltip.addClass('tooltip').html(tooltip);

            appInstance.$svg.after(this.$tooltip);

            this.$el.hover(
                () => {
                    this.$tooltip.fadeIn(200);
                },
                () => {
                    this.$tooltip.fadeOut(200);
                }
            );
        }

        // add an event listener on click, if the callback function is defined
        if (clickEvent) {
            this.$el.on('click', clickEvent);
        }
    }
}

/** @module FloatingMenu */
/**
 * Class to represent the floating menu in the right bottom corner of the page.
 * It instantiates all the buttons and their callbacks.
 */
export default class FloatingMenu {
    /**
     * @param {App} appInstance reference to the App element this menu is associated with
     */
    constructor(appInstance) {
        /**
         * the jQuery element containing all buttons
         * @type {jQuery.element}
         */
        this.$el = $('<div>');

        const id = 'floatingMenu';

        this.$el.attr('id', id);

        // const $loader = $("<div>").addClass("loader").addClass("hidden");

        /* EXPORT */
        this.append(
            new FloatingButton(
                'export',
                'Get code for this network',
                () => {
                    // create the popup container holding all popup content (that will be passed to lity)
                    let $popup = $('<div>')
                        .addClass('importExport')
                        .addClass('export');

                    // generate the block with code to be displayed and append it to the popup element
                    const $textblock = $('<textarea>').text(
                        getJSONString(appInstance.exportData, true)
                    );

                    $popup.append($textblock);

                    // generate the links
                    $popup.append(
                        $('<a>')
                            .attr({
                                href: getJSONString(appInstance.exportData, true, true),
                                class: 'download',
                                download: 'network.json'
                            })
                            .append($('<img>').attr('src', 'img/gui/export.svg'))
                            .append(' expanded JSON')
                    );
                    $popup.append(
                        $('<a>')
                            .attr({
                                href: getJSONString(appInstance.exportData, false, true),
                                class: 'download',
                                download: 'network.min.json'
                            })
                            .append($('<img>').attr('src', 'img/gui/export.svg'))
                            .append(' compact JSON')
                    );

                    lity($popup);

                    // highlight the text in the textblock
                    $textblock.select();
                },
                appInstance
            )
        );

        /* Tutorial */
        this.append(
            new FloatingButton(
                'tutorial',
                'Start the tutorial',
                () => {
                    appInstance.startTutorial();
                },
                appInstance
            )
        );

        appInstance.$svg.after(this.$el);

        /* HELP */

        let help = new FloatingButton('help', 'Display a help page', false, appInstance);
        help.$el.attr({
            href: './docs/user.html',
            'data-lity': ''
        });
        this.append(help);

        const github = new FloatingButton('github', 'Open the project repository', false, appInstance);
        github.$el.attr({
            href: 'https://github.com/janjaromirhorak/hradla',
            target: '_blank'
        });
        this.append(github);

        appInstance.$svg.after(this.$el);
    }

    /**
     * append a FloatingButton to this menu
     * @param  {FloatingButton} menuItem append an instance of  {@link FloatingButton} to this menu
     */
    append(menuItem) {
        this.$el.append(menuItem.$el);
    }
}