/**
 * @author Martin Karkowski
 * @email m.karkowski@zema.de
 * @create date 2019-04-29 11:30:22
 * @modify date 2020-10-29 12:44:40
 * @desc [description]
 */

import { faArrowLeft, faArrowRight, faClone, faDownload, faEyeSlash, faFile, faPlusSquare, faPrint, faUpload } from '@fortawesome/free-solid-svg-icons';
import React from 'react';
import { Button, Form } from 'react-bootstrap';
import { IToolbar } from '../../layout/toolbar';
import { IGraphCallbackData } from '../interfaces/IGraphCallbackData';
import { writeToClipboard } from '../../helpers/clipboard'

async function openFile(data){
    return await data.layout.getDialogData({
        content: {
            props: {},
            component(props: {
                onSubmit: (data: string) => void;
                onCancel: (error: any) => void
            }) {
                const showFile = (e) => {
                    e.preventDefault()
                    const reader = new FileReader()
                    reader.onload = async (event) => {
                        const text = ((event.target).result as string);
                        // Use the Submit Function
                        props.onSubmit(text);
                    };

                    // Tell the Reader to load the File.
                    reader.readAsText(e.target.files[0])
                }

                return (
                    <>
                        <p>
                            Select the File:
                        </p>
                        <Form>
                            <Form.File
                                id="file"
                                label="Custom file input"
                                custom
                                onChange={(e) => showFile(e)}
                            />
                        </Form>                                                
                    </>
                )
            },
        },
        header: 'Do you want to discard all unstored changes?',
    });
}

/**
 * Function to extract the Default Toolbar Menu
 */
export function defaultToolbar<N=any,E=any>() {

    const toolbar: IToolbar<IGraphCallbackData<N,E>> = {
        items: [
            {
                type: 'action',
                label: '',
                icon: faPlusSquare,
                onClick: (data) => {
                    /**
                     * Add a new Node in the Center of the Screen.
                     * Therefore extract the Center-Position of the
                     * Graph and call the addNode Function. 
                     * 
                     * This will result in opening up the corresponding
                     * Editor. 
                     */

                    data.network.network.addNodeMode();

                    // if (( data.component.template as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length > 0){
                    //     const pos = data.network.network.getViewPosition();
                    //     data.component.addNode(pos);
                    // } else {
                    //     data.network.showMessage('info', 'No Template Selected!', 'Please select a template for a Node in the Sidebar!', 5000);
                    // }                             

                }
            },
            {
                type: 'action',
                label: '',
                icon: faArrowRight,
                onClick: (data) => {
                    /** 
                     * Set the graph in the Add-Edge Mode
                     */

                    data.network.network.addEdgeMode();

                    // if ((data.eid as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length === 0 && (data.component.template as ITemplate<N,E>).edges.length === 1){
                    //     data.network.network.addEdgeMode();
                    // } else {
                    //     data.network.showMessage('info', 'No Template Selected!', 'Please select a template for an Edge in the Sidebar!', 5000);
                    // }                                
                }
            },  
            {
                type: 'menu',
                id: 'fileMenu',
                items: [
                    {
                        type: 'action',
                        label: 'New File',
                        icon: faFile,
                        onClick: async (data) => {
                            /** Clearout the Graph and Delete the History */
                            data.network.clear();
                            data.network.resetHistory();

                            if (data.tabs.tabs.length > 0) {
                                const clearAll = await data.layout.getDialogData({
                                    content: {
                                        props: {},
                                        component(props: {
                                            onSubmit: (data: boolean) => void;
                                            onCancel: (error: any) => void
                                        }) {
                                            return (
                                                <>
                                                    <Button variant="danger" onClick={e => props.onSubmit(true)}>Yes</Button> {' '}
                                                    <Button variant="success" onClick={e => props.onSubmit(false)}>No </Button>
                                                </>
                                            )
                                        },
                                    },
                                    header: 'Do you want to discard all unstored changes?',
                                });

                                 // Iterate over the Tabs and delete every.
                                for (const tab of data.tabs.tabs){
                                    // Force to delete the Tabs.
                                    await data.tabs.delteTab(tab,clearAll);
                                }

                            }
                            await data.tabs.requestTab();
                        }
                    },
                    {
                        type: 'divider',
                    },
                    {
                        type: 'action',
                        label: 'Open File',
                        icon: faUpload,
                        onClick: async (data) => {
                            let file =''
                            while (file == ''){
                                // Load the File
                                file = await openFile(data);

                                // Try to load the File till the User aborts, or the 
                                // File was correct.
                                try {
                                    data.network.loadJSON(file, true);
                                    data.layout.showToast('Loaded Graph','success');
                                } catch (e) {
                                    data.layout.showToast('Failed to Load the Graph','error');
                                    console.error(e)
                                    file = '';
                                }
                            }                                               
                        }
                    },
                    {
                        type: 'action',
                        label: 'Import File',
                        icon: faUpload,
                        onClick: async (data) => {
                            let file =''
                            while (file == ''){
                                // Load the File
                                file = await openFile(data);

                                // Try to load the File till the User aborts, or the 
                                // File was correct.
                                try {
                                    setTimeout(() => {
                                        data.network.loadJSON(file, false);
                                    },1000);
                                    
                                    data.layout.showToast('Loaded Graph','success');
                                } catch (e) {
                                    data.layout.showToast('Failed to Load the Graph','error');
                                    file = '';
                                }
                            }       
                        }
                    },
                    {
                        type: 'action',
                        label: 'Save File',
                        icon: faDownload,
                        onClick: async (data) => {
                            // Get the Name
                            const name = await data.layout.getDialogData({
                                header: 'Enter File-Name',
                                content: {
                                    component: 'DynamicForm',
                                    props: {
                                        schema: {
                                            type: "string",
                                            description: "Name of the File"
                                        }
                                    }
                                }
                            });

                            // Store the content
                        }
                    },
                    {
                        type: 'action',
                        label: 'print',                        
                        icon: faPrint,
                        onClick: (data) => {
                            /** Function, which should render the CANVAS as PDF */
                            /** Therefore extract the real Canvas-Object */
                            const canvas = data.network.network.body.container.getElementsByTagName('canvas')[0];
                            const imgData = canvas.toDataURL('image/jpeg', 1.0);
                            // // const pdf = new jsPDF();
                            // pdf.addImage(imgData, 'JPEG', 0, 0);
                            // pdf.save('download.pdf');
                        }
                    }

                ],
                label: 'File'
            }, 
            {
                type: 'menu',
                id: 'editMenu',
                label: 'edit',
                items: [
                    {
                        type: 'action',
                        label: 'Undo',
                        icon: faArrowLeft,
                        onClick: (data) => {
                            /** Undo the Last Action if Possible */
                            data.network.undo();
                        }
                    },
                    {
                        type: 'action',
                        label: 'Redo',
                        icon: faArrowRight,
                        onClick: (data) => {
                            /** Redo the Last Action if Possible */
                            data.network.redo();
                        }
                    },
                    {
                        type: 'divider'
                    },
                    {
                        type: 'action',
                        label: 'add node',
                        icon: faPlusSquare,
                        onClick: (data) => {
                            /**
                             * Add a new Node in the Center of the Screen.
                             * Therefore extract the Center-Position of the
                             * Graph and call the addNode Function. 
                             * 
                             * This will result in opening up the corresponding
                             * Editor. 
                             */
                            data.layout.showToast('Shortcut for adding a node: "Left-Control + Mouse-Click"','light');
                            data.network.network.addNodeMode();
                        }
                    },
                    {
                        type: 'action',
                        label: 'add edge',
                        icon: faArrowRight,
                        onClick: (data) => {
                            /** 
                             * Set the graph in the Add-Edge Mode
                             */
                            data.layout.showToast('Shortcut for adding a node: "Left-Shift + Mouse-Click"','info');
                            data.network.network.addEdgeMode();
                        }
                    },                        
                    {
                        type: 'divider',
                    },
                    {
                        type: 'action',
                        label: 'export to clipboard',
                        icon: faClone,
                        onClick: (data) => {
                            writeToClipboard(data.network.getJSON())
                        }
                    },
                    {
                        type: 'action',
                        label: 'import from clipboard',
                        icon: faClone,
                        onClick: (data) => {
                            data.component.pasteFromClipboard();
                        }
                    },
                    {
                        type: 'action',
                        label: 'upload project-file',
                        icon: faClone,
                        onClick: (data) => {
                            
                        }
                    },
                    {
                        type: 'divider',
                    },
                    {
                        type: 'action',
                        label: 'hide selected',
                        icon: faEyeSlash,
                        onClick: (data) => {
                            /**
                             * Callback which whill hide the selected Elements.
                             * Therefore disable storingContent on Updates, cause
                             * every data.options of the Selected Elements are updated.
                             */

                            data.network.disableUndoRedo = true;

                            data.network.network.setVisibilityOfNodes(data.selectedNodes, false);
                            data.network.network.storePositions();

                            /** Iterate over the selected Elements and hide the Node */
                            for (const id of data.selectedNodes) {
                                const node = data.network.getNode(id);
                                node.hidden = true;
                                /** Update the data.options */
                                data.network.updateNode(node);
                            }

                            /** Iterate over the selected Elements and hide the Edge */
                            for (const id of data.selectedEdges) {
                                const edge = data.network.getEdge(id);
                                edge.hidden = true;
                                /** Update the data.options */
                                data.network.updateEdge(edge);
                            }

                            /** Activate Redo/Undo Tracking again */
                            data.network.disableUndoRedo = false;
                            /** Store the current state */
                            data.network.save();
                        }
                    },
                ]
            }
        ]
    }

    // const config: IToolbar<D> = {
    //     /** Set the File-Menu as initally active */
    //     activeTab: 'fileMenu',
    //     /** Define the Tabs of the Toolbar */
    //     tabs: {
    //         view: {
    //             label: 'View',
    //             tooltip: 'Manipulates the View of the Graph',
    //             menu: {
    //                 items: [
    //                     {
    //                         type: 'action',
    //                         label: 'fit',
    //                         tooltip: 'Fits the Graph',
    //                         icon: 'fa fa-expand',
    //                         onClick: (data) => {
    //                             data.network.network.fit({
    //                                 animation: true
    //                             });
    //                         }
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'zoom in',
    //                         tooltip: 'Zoom in the Graph',
    //                         icon: 'fa fa-search-plus',
    //                         onClick: (data) => {
    //                             const position = data.network.network.getViewPosition();
    //                             const currentScale = data.network.network.getScale();
    //                             data.network.network.moveTo({
    //                                 position,
    //                                 scale: currentScale + 0.1,
    //                                 animation: {
    //                                     duration: 100,
    //                                 }
    //                             });
    //                         }
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'zoom out',
    //                         tooltip: 'Zooms out the Graph',
    //                         icon: 'fa fa-search-minus',
    //                         onClick: (data) => {
    //                             const position = data.network.network.getViewPosition();
    //                             const currentScale = data.network.network.getScale();
    //                             data.network.network.moveTo({
    //                                 position,
    //                                 scale: currentScale - 0.1,
    //                                 animation: {
    //                                     duration: 100,
    //                                 }
    //                             });
    //                         }
    //                     }, {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'view all',
    //                         tooltip: 'Show all hidden Elements',
    //                         icon: 'fa fa-eye',
    //                         onClick: (data) => {
    //                             const nodes = data.network.nodes;
    //                             const edges = data.network.edges;

    //                             for (const node of nodes){
    //                                 node.hidden = false;
    //                             }

    //                             for (const edge of edges){
    //                                 edge.hidden = false;
    //                             }

    //                             data.network.updateNode(nodes);
    //                             data.network.updateEdge(edges);
    //                         }
    //                     },
    //                 ]
    //             }
    //         },
    //         layout: {
    //             label: 'Layout',
    //             tooltip: 'Options to Manipulate the Layout of the Graph',
    //             // disabled: true,
    //             menu: {
    //                 items: [
    //                     {
    //                         id: 'item2',
    //                         type: 'menu-radio',
    //                         text(item) {
    //                             const text = item.selected;
    //                             const el = this.get('item2:' + item.selected);
    //                             return el.text;
    //                         },
    //                         selected: getCurrentLayout(),
    //                         items: [
    //                             { id: 'h_ud', label: 'Hierarchical: UD', icon: 'fa fa-arrow-down' },
    //                             { id: 'h_du', label: 'Hierarchical: DU', icon: 'fa fa-arrow-up' },
    //                             { id: 'h_lr', label: 'Hierarchical: LR', icon: 'fa fa-arrow-right' },
    //                             { id: 'h_rl', label: 'Hierarchical: RL', icon: 'fa fa-arrow-left' },
    //                             { id: 'normal', label: 'Normal View-Mode' }
    //                         ],
    //                         onRefresh(data) {
    //                             data.event.done(() => {
    //                                 const before = getCurrentLayout();

    //                                 if (data.event.item.selected != before) {
    //                                     // Update the data.options object
    //                                     if (typeof rgetattr(data.options, 'layout.hierarchical', {}) === 'boolean') {
    //                                         rsetattr(data.options, 'layout.hierarchical', {})
    //                                     }

    //                                     // Based on the Selection, update the Elements
    //                                     switch (data.event.item.selected) {
    //                                         case 'normal':
    //                                             rsetattr(data.options, 'layout.hierarchical.enabled', false)
    //                                             break;

    //                                         default:
    //                                             const direction = (data.event.item.selected as string).slice(2).toUpperCase();
    //                                             rsetattr(data.options, 'layout.hierarchical.enabled', true);
    //                                             rsetattr(data.options, 'layout.hierarchical.direction', direction);
    //                                             break;
    //                                     }

    //                                     data.component.visjsOptions = data.options;

    //                                     // Store the New data.options
    //                                     data.network.network.storePositions();
    //                                     const nodes = data.network.nodes;
    //                                     const edges = data.network.edges;
    //                                     const clusters = data.network.getClusters();

    //                                     data.network.clear();
    //                                     data.network.network.setOptions(data.options);
    //                                     data.network.addNode(nodes);
    //                                     data.network.addEdge(edges);
    //                                     data.network.readinClusters(clusters);
    //                                 }
    //                             });
    //                         }
    //                     },
    //                 ]
    //             }
    //         },
    //         cluster: {
    //             label: 'Clusters',
    //             tooltip: 'Add Clusters to the Node',
    //             // disabled: true,
    //             menu: {
    //                 items: [
    //                     {
    //                         type: 'action',
    //                         label: 'cluster selected',
    //                         tooltip: 'Clusterize the Selected Elements',
    //                         icon: 'fa fa-cog',
    //                         onClick: (data) => {
    //                             clusterSelected(data.component, false)
    //                         }
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'cluster outliners',
    //                         tooltip: 'Clusterize the Selected Elements',
    //                         icon: 'fa fa-cog',
    //                         onClick: (data) => {
    //                             data.network.network.clusterOutliers();
    //                             data.network.save();
    //                         }
    //                     },
    //                     {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'uncluster selected',
    //                         tooltip: '',
    //                         icon: 'fa fa-cog',
    //                         onClick: (data) => {
    //                             for (const node of data.selectedNodes) {
    //                                 if (data.network.network.isCluster(node)) {
    //                                     data.network.network.openCluster(node)
    //                                 }
    //                             }
    //                             data.network.save();
    //                         }
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'view all',
    //                         tooltip: 'Show all hidden Elements',
    //                         icon: 'fa fa-eye',
    //                         onClick: (data) => {
    //                             const nodesToUpdate = data.network.nodes;
    //                             for (const node of nodesToUpdate){
    //                                 node.hidden = false;
    //                             }
    //                             data.network.updateNode(nodesToUpdate);
    //                         }
    //                     },
    //                 ]
    //             }
    //         },
    //         settings: {
    //             label: 'Settings',
    //             tooltip: 'User Settings',
    //             // disabled: true,
    //             menu: {
    //                 items: [
    //                     {
    //                         type: 'check',
    //                         label: 'Multiselect',
    //                         icon: 'fa fa-check-square',
    //                         checked: rgetattr(graphOptions, 'interaction.multiselect', false),
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 rsetattr(data.options, 'interaction.multiselect', data.event.item.checked);
    //                                 data.component.visjsOptions = data.options;
    //                                 data.network.network.setOptions(data.options);
    //                             })
    //                         }
    //                     },
    //                     {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         type: 'check',
    //                         label: 'Navigation Buttons',
    //                         icon: 'fa fa-check-square',
    //                         checked: rgetattr(graphOptions, 'interaction.navigationButtons', false),
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 rsetattr(data.options, 'interaction.navigationButtons', data.event.item.checked);
    //                                 data.component.visjsOptions = data.options;
    //                                 data.network.network.setOptions(data.options);
    //                             })
    //                         }
    //                     },
    //                     {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         id: 'physics',
    //                         type: 'check',
    //                         label: 'physics',
    //                         icon: 'fa fa-check-square',
    //                         checked: rgetattr(graphOptions, 'physics', false) === true || rgetattr(graphOptions, 'physics.enabled', false) === true,
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 if (typeof data.options.physics == 'boolean') {
    //                                     data.options.physics = data.event.item.checked;
    //                                     rsetattr(data.options, 'physics', data.event.item.checked);
    //                                     data.component.visjsOptions = data.options;
    //                                     data.network.network.setOptions(data.options);
    //                                 } else {
    //                                     rsetattr(data.options, 'physics.enabled', data.event.item.checked);
    //                                     data.component.visjsOptions = data.options;
    //                                     data.network.network.setOptions(data.options);
    //                                 }
    //                             })
    //                         }
    //                     },
    //                     {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         id: 'shadows',
    //                         type: 'check',
    //                         label: 'shadows',
    //                         icon: 'fa fa-check-square',
    //                         checked: rgetattr(graphOptions, 'nodes.shadow', false) === true || rgetattr(graphOptions, 'nodes.shadow.enabled', false) === true,
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 if (data.options.nodes && typeof data.options.nodes.shadow == 'boolean') {
    //                                     data.options.nodes.shadow = data.event.item.checked;
    //                                     rsetattr(data.options, 'nodes.shadow', data.event.item.checked);
    //                                 } else {
    //                                     rsetattr(data.options, 'nodes.shadow.enabled', data.event.item.checked);
    //                                 }

    //                                 if (data.options.edges && typeof data.options.edges.shadow == 'boolean') {
    //                                     data.options.edges.shadow = data.event.item.checked;
    //                                     rsetattr(data.options, 'edges.shadow', data.event.item.checked);
    //                                 } else {
    //                                     rsetattr(data.options, 'edges.shadow.enabled', data.event.item.checked);
    //                                 }

    //                                 data.component.visjsOptions = data.options;
    //                                 data.network.network.setOptions(data.options);
    //                             })
    //                         }
    //                     },{
    //                         type: 'divider'
    //                     },
    //                     {
    //                         type: 'check',
    //                         label: 'Edit on Select',
    //                         icon: 'fa fa-check-square',
    //                         checked: additionalOptions.editOnSelect || false,
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 data.component.options.editOnSelect = data.event.item.checked;
    //                             })
    //                         }
    //                     },
    //                     {
    //                         type: 'check',
    //                         label: 'Hide Panel on Deselect',
    //                         icon: 'fa fa-check-square',
    //                         checked: additionalOptions.hidePanelOnDeselect || false,
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 data.component.options.hidePanelOnDeselect = data.event.item.checked;
    //                             })
    //                         }
    //                     },
    //                 ]
    //             }
    //         },
    //         developer: {
    //             label: 'Developer',
    //             tooltip: 'Extra Tools for a Developer',
    //             // disabled: true,
    //             menu: {
    //                 items: [
    //                     {
    //                         type: 'action',
    //                         label: 'json',
    //                         tooltip: 'Shows the current data as JSON',
    //                         icon: 'fa fa-code',
    //                         onClick: (data) => {

    //                             let editor: any = null;

    //                             const speed = 0.3;

    //                             w2popup.open({
    //                                 id: 'test',
    //                                 title: 'Debug window',
    //                                 maximized: true,
    //                                 body: '<div id="jsonviewer" style="width:100%;height:100%"></div>',
    //                                 showMax: true,
    //                                 speed,
    //                                 width: 500,
    //                                 height: 500,
    //                                 onOpen(event) {

    //                                     setTimeout(() => {
    //                                         // Generate the Editor
    //                                         const editorOptions = {
    //                                             // modes: ['tree', 'view', 'code', 'text']
    //                                             mode: 'view',
    //                                             search: 'true',
    //                                             mainMenuBar: false
    //                                         };
    //                                         editor = new JSONEditor(document.getElementById('jsonviewer'), editorOptions, {
    //                                             nodes: data.network.nodes,
    //                                             edges: data.network.edges
    //                                         });
    //                                     }, speed * 1000 + 0.050)




    //                                 },
    //                                 onClose(event) {
    //                                     if (editor) {
    //                                         editor.destroy();
    //                                     }
    //                                 }
    //                             });
    //                         }
    //                     },
    //                     {
    //                         type: 'action',
    //                         label: 'generate Template',
    //                         tooltip: 'Creates a Template Structure',
    //                         icon: 'fa fa-code',
    //                         onClick: (data) => {
    //                             writeToClipboard(stringifyWithFunctions(data.component.generateTemplateData()));
    //                         }
    //                     },
    //                     {
    //                         type: 'divider'
    //                     },
    //                     {
    //                         type: 'check',
    //                         label: 'Use Version Control',
    //                         icon: 'fa fa-check-square',
    //                         checked: rgetattr(additionalOptions, 'useVersionControl', true),
    //                         onClick: (data) => {
    //                             data.event.done(() => {
    //                                 data.component.network.useVersionControl =  data.event.item.checked;
    //                             })
    //                         }
    //                     },
    //                 ]
    //             }
    //         },
    //         help: {
    //             label: 'Help',
    //             menu: {
    //                 items: [
    //                     {
    //                         type: 'action',
    //                         label: 'Show Help',
    //                         tooltip: 'Clusterize the Selected Elements',
    //                         icon: 'fa fa-info',
    //                         onClick: (data) => {
    //                             // Load the Help Component.
    //                             data.component.layout.openDialogComponent<HelpComponent>({
    //                                 title: 'help',
    //                                 component: {
    //                                     component: HelpComponent
    //                                 },
    //                                 buttons: [
    //                                     {
    //                                         label: 'Close',
    //                                         callback(instance, close){
    //                                             close();
    //                                         },
    //                                         status: 'danger'
    //                                     }
    //                                 ],
    //                                 closeOnBackdropClick: true,
    //                                 closeOnEsc: true,
    //                             });
    //                         }
    //                     },
    //                 ]
    //             }
    //         }
    //     }
    // };

    return toolbar;
}