/*
 * The MIT License
 *
 * Copyright 2016 MrMcX.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package main;

import com.mxgraph.layout.mxCircleLayout;
import com.mxgraph.layout.mxIGraphLayout;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxCellRenderer;
import com.mxgraph.util.mxConstants;
import dungeon.Dungeon;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jgrapht.UndirectedGraph;
import org.jgrapht.ext.GmlExporter;
import org.jgrapht.ext.JGraphXAdapter;
import java.awt.image.BufferedImage;
import java.awt.Image;
import javax.swing.ImageIcon;

/**
 *
 * @author MrMcX
 */
public class DungeonGeneratorUI extends javax.swing.JFrame {

    private Dungeon mDungeon;
    private UndirectedGraph mGraph;
    mxGraphComponent mGraphComponent;

    /**
     * Creates new form DungeonGeneratorUI
     */
    public DungeonGeneratorUI() {
        initComponents();
        ImageIcon imageIcon = new ImageIcon("resources/images/firewall.png");
        this.setIconImage(imageIcon.getImage());
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelCards = new javax.swing.JPanel();
        jPanelCardNew = new javax.swing.JPanel();
        jButtonGenerate = new javax.swing.JButton();
        jPanelSettings = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jSpinSize = new javax.swing.JSpinner();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(1, 0), new java.awt.Dimension(1, 0), new java.awt.Dimension(1, 32767));
        jCheckBoxExp = new javax.swing.JCheckBox();
        jLabel1 = new javax.swing.JLabel();
        jComboBoxNatural = new javax.swing.JComboBox<>();
        jLabel2 = new javax.swing.JLabel();
        jComboBoxMode = new javax.swing.JComboBox<>();
        jTabs = new javax.swing.JTabbedPane();
        jPanelCardShow = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextDescription = new javax.swing.JTextArea();
        jPanelCardDraw = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jPanelDraw = new javax.swing.JPanel();
        jPanelStatus = new javax.swing.JPanel();
        jLabelStatus1 = new javax.swing.JLabel();
        jLabelStatus2 = new javax.swing.JLabel();
        jLabelStatus3 = new javax.swing.JLabel();
        jMenuBar = new javax.swing.JMenuBar();
        jMenu = new javax.swing.JMenu();
        jMenuNew = new javax.swing.JMenuItem();
        jMenuSave = new javax.swing.JMenuItem();
        jMenuGraph = new javax.swing.JMenu();
        jMenuExport = new javax.swing.JMenuItem();
        jMenuImage = new javax.swing.JMenuItem();
        jMenuClose = new javax.swing.JMenuItem();
        jMenuHelp = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        jMenuItemAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("DungeonGenerator");
        setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
        setMinimumSize(new java.awt.Dimension(800, 600));

        jPanelCards.setLayout(new java.awt.CardLayout());

        jPanelCardNew.setLayout(new java.awt.BorderLayout());

        jButtonGenerate.setText("Generieren");
        jButtonGenerate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGenerateActionPerformed(evt);
            }
        });
        jPanelCardNew.add(jButtonGenerate, java.awt.BorderLayout.PAGE_END);

        jPanelSettings.setLayout(new java.awt.GridLayout(4, 2));

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel4.setText("Raummaximum");
        jPanelSettings.add(jLabel4);

        jSpinSize.setModel(new javax.swing.SpinnerNumberModel(1, 1, null, 1));
        jSpinSize.setMaximumSize(new java.awt.Dimension(40, 30));
        jSpinSize.setValue(1);
        jPanelSettings.add(jSpinSize);
        jPanelSettings.add(filler1);

        jCheckBoxExp.setText("Experimenteller Modus");
        jCheckBoxExp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxExpActionPerformed(evt);
            }
        });
        jPanelSettings.add(jCheckBoxExp);

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Wie ist der Dungeon entstanden?");
        jPanelSettings.add(jLabel1);

        jComboBoxNatural.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Natürlich", "Künstlich" }));
        jPanelSettings.add(jComboBoxNatural);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel2.setText("Wie ist der Dungeon aufgebaut?");
        jPanelSettings.add(jLabel2);

        jComboBoxMode.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Verzweigt", "Geradlinig", "Zufällig" }));
        jPanelSettings.add(jComboBoxMode);

        jPanelCardNew.add(jPanelSettings, java.awt.BorderLayout.CENTER);

        jPanelCards.add(jPanelCardNew, "new");

        jPanelCardShow.setLayout(new java.awt.BorderLayout());

        jTextDescription.setEditable(false);
        jTextDescription.setColumns(20);
        jTextDescription.setRows(5);
        jTextDescription.setDisabledTextColor(new java.awt.Color(0, 0, 0));
        jScrollPane1.setViewportView(jTextDescription);

        jPanelCardShow.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jTabs.addTab("Beschreibung", jPanelCardShow);

        jPanelCardDraw.setLayout(new java.awt.BorderLayout());

        jScrollPane2.setViewportView(jPanelDraw);

        jPanelCardDraw.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        jTabs.addTab("Graph", jPanelCardDraw);

        jPanelCards.add(jTabs, "show");

        getContentPane().add(jPanelCards, java.awt.BorderLayout.CENTER);

        jPanelStatus.setLayout(new java.awt.GridLayout(1, 4));

        jLabelStatus1.setText("Max:");
        jPanelStatus.add(jLabelStatus1);

        jLabelStatus2.setText("Type:");
        jPanelStatus.add(jLabelStatus2);

        jLabelStatus3.setText("Mode:");
        jPanelStatus.add(jLabelStatus3);

        getContentPane().add(jPanelStatus, java.awt.BorderLayout.SOUTH);

        jMenu.setText("Datei");

        jMenuNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        jMenuNew.setText("Neuer Dungeon");
        jMenuNew.setEnabled(false);
        jMenuNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuNewActionPerformed(evt);
            }
        });
        jMenu.add(jMenuNew);

        jMenuSave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        jMenuSave.setText("Beschreibung speichern");
        jMenuSave.setEnabled(false);
        jMenuSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuSaveActionPerformed(evt);
            }
        });
        jMenu.add(jMenuSave);

        jMenuGraph.setText("Graph exportieren");
        jMenuGraph.setEnabled(false);

        jMenuExport.setText(".GML-Datei");
        jMenuExport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuExportActionPerformed(evt);
            }
        });
        jMenuGraph.add(jMenuExport);

        jMenuImage.setText("Bilddatei");
        jMenuImage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuImageActionPerformed(evt);
            }
        });
        jMenuGraph.add(jMenuImage);

        jMenu.add(jMenuGraph);

        jMenuClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
        jMenuClose.setText("Beenden");
        jMenuClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuCloseActionPerformed(evt);
            }
        });
        jMenu.add(jMenuClose);

        jMenuBar.add(jMenu);

        jMenuHelp.setText("Hilfe");

        jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        jMenuItem1.setText("Hilfe");
        jMenuHelp.add(jMenuItem1);
        jMenuHelp.add(jSeparator1);

        jMenuItemAbout.setText("Über/Lizenz");
        jMenuItemAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemAboutActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemAbout);

        jMenuBar.add(jMenuHelp);

        setJMenuBar(jMenuBar);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuCloseActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jMenuCloseActionPerformed

    private void jButtonGenerateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGenerateActionPerformed
        mDungeon = new Dungeon((int) jSpinSize.getValue(), SelectedNatural(), SelectedMode());

        mGraph = mDungeon.toGraph();
        JGraphXAdapter graphAdapter = new JGraphXAdapter(mGraph);
        mGraphComponent = new mxGraphComponent(graphAdapter);
        mGraphComponent.setEnabled(false);
        Map edgeStyle = graphAdapter.getStylesheet().getDefaultEdgeStyle();
        edgeStyle.put(mxConstants.STYLE_NOLABEL, true);

        mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
        layout.execute(graphAdapter.getDefaultParent());

        jPanelDraw.add(mGraphComponent);
        jTextDescription.setText(mDungeon.toString());
        jLabelStatus1.setText("Max: " + jSpinSize.getValue());
        jLabelStatus2.setText("Type: " + SelectedNatural().toString());
        jLabelStatus3.setText("Mode: " + SelectedMode().toString());

        jMenuSave.setEnabled(true);
        jMenuNew.setEnabled(true);
        jMenuGraph.setEnabled(true);
        CardLayout cl = (CardLayout) jPanelCards.getLayout();
        cl.show(jPanelCards, "show");
    }//GEN-LAST:event_jButtonGenerateActionPerformed

    private void jMenuNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuNewActionPerformed
        jMenuSave.setEnabled(false);
        jMenuNew.setEnabled(false);
        jMenuGraph.setEnabled(false);
        CardLayout cl = (CardLayout) jPanelCards.getLayout();
        cl.show(jPanelCards, "new");
        jPanelDraw.removeAll();
        jLabelStatus1.setText("Max: -");
        jLabelStatus2.setText("Type: -");
        jLabelStatus3.setText("Mode: -");
    }//GEN-LAST:event_jMenuNewActionPerformed

    private void jMenuSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuSaveActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Textdateien", "txt");
        fileChooser.setFileFilter(filter);
        fileChooser.setDialogTitle("Speicherort wählen");
        int userSelection = fileChooser.showSaveDialog(this);
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            try {
                File file = fileChooser.getSelectedFile();
                if (!file.getName().endsWith(".txt")) {
                    file = new File(file.getCanonicalPath() + ".txt");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                Path path = Files.createFile(file.toPath());
                Files.write(path, jTextDescription.getText().getBytes());
                JOptionPane.showMessageDialog(this, "Gespeichert!");
            } catch (IOException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuSaveActionPerformed

    private void jMenuExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuExportActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Graph Modelling Files", "gml");
        fileChooser.setFileFilter(filter);
        fileChooser.setDialogTitle("Speicherort wählen");
        int userSelection = fileChooser.showSaveDialog(this);
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            try {
                File file = fileChooser.getSelectedFile();
                if (!file.getName().endsWith(".gml")) {
                    file = new File(file.getCanonicalPath() + ".gml");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                try (FileWriter fw = new FileWriter(file, false)) {
                    //System.setProperties(file);
                    GmlExporter gex = new GmlExporter();
                    gex.setPrintLabels(GmlExporter.PRINT_EDGE_VERTEX_LABELS);
                    gex.export(fw, mGraph);
                    JOptionPane.showMessageDialog(this, "Gespeichert!");
                }
            } catch (IOException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuExportActionPerformed

    private void jMenuImageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuImageActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Bilddateien", ".png");
        fileChooser.setFileFilter(filter);
        fileChooser.setDialogTitle("Speicherort wählen");
        int userSelection = fileChooser.showSaveDialog(this);
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            try {
                File file = fileChooser.getSelectedFile();
                if (!file.getName().endsWith(".png")) {
                    file = new File(file.getCanonicalPath() + ".png");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                BufferedImage image = mxCellRenderer.createBufferedImage(mGraphComponent.getGraph(), null, 1, Color.WHITE, true, null);
                ImageIO.write(image, "PNG", file);
                JOptionPane.showMessageDialog(this, "Gespeichert!");
            } catch (IOException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuImageActionPerformed

    private void jMenuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemAboutActionPerformed
        ResourceBundle vprops = ResourceBundle.getBundle("version", Locale.getDefault());
        String number = vprops.getString("BUILDNUMBER");
        String date = vprops.getString("BUILDDATE");

        JOptionPane.showMessageDialog(this, "DungeonGenerator Version " + number + "\n"
                + "(compiled on " + date + ")\n"
                + "\n"
                + "The MIT License (MIT)\n"
                + "\n"
                + "Copyright (c) 2016 Simon Moser IT\n"
                + "\n"
                + "Permission is hereby granted, free of charge, to any person\n"
                + "obtaining a copy of this software and associated documentation\n"
                + "files (the \"Software\"), to deal in the Software without restriction,\n"
                + "including without limitation the rights to use,copy, modify,\n"
                + "merge, publish, distribute, sublicense, and/or sell copies\n"
                + "of the Software, and to permit persons to whom the Software\n"
                + "is furnished to do so, subject to the following conditions:\n"
                + "\n"
                + "The above copyright notice and this permission notice shall be\n"
                + "included in all copies or substantial portions of the Software.\n"
                + "\n"
                + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY\n"
                + "OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT\n"
                + "LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
                + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n"
                + "IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n"
                + "BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n"
                + "WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n"
                + "ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n"
                + "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
                + "\n"
                + "Icons made by Revicon from www.flaticon.com", "Über", JOptionPane.QUESTION_MESSAGE);
    }//GEN-LAST:event_jMenuItemAboutActionPerformed

    private void jCheckBoxExpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxExpActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jCheckBoxExpActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(DungeonGeneratorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(DungeonGeneratorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(DungeonGeneratorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(DungeonGeneratorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DungeonGeneratorUI().setVisible(true);
            }
        });
    }

    private Dungeon.Mode SelectedMode() {
        String sel = (String) jComboBoxMode.getSelectedItem();
        switch (sel) {
            case "Verzweigt":
                return Dungeon.Mode.BRANCHED;
            case "Geradlinig":
                return Dungeon.Mode.STRAIGHT;
            default:
                return Dungeon.Mode.RANDOM;
        }
    }

    private Dungeon.Type SelectedNatural() {
        if(jComboBoxNatural.getSelectedItem().equals("Künstlich")){
            if(jCheckBoxExp.isSelected()){
                return Dungeon.Type.EXP_ARTIFICIAL;
            }
            return Dungeon.Type.ARTIFICIAL;
        } else {
            if(jCheckBoxExp.isSelected()){
                return Dungeon.Type.EXP_NATURAL;
            }
            return Dungeon.Type.NATURAL;
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.Box.Filler filler1;
    private javax.swing.JButton jButtonGenerate;
    private javax.swing.JCheckBox jCheckBoxExp;
    private javax.swing.JComboBox<String> jComboBoxMode;
    private javax.swing.JComboBox<String> jComboBoxNatural;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabelStatus1;
    private javax.swing.JLabel jLabelStatus2;
    private javax.swing.JLabel jLabelStatus3;
    private javax.swing.JMenu jMenu;
    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.JMenuItem jMenuClose;
    private javax.swing.JMenuItem jMenuExport;
    private javax.swing.JMenu jMenuGraph;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuImage;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuNew;
    private javax.swing.JMenuItem jMenuSave;
    private javax.swing.JPanel jPanelCardDraw;
    private javax.swing.JPanel jPanelCardNew;
    private javax.swing.JPanel jPanelCardShow;
    private javax.swing.JPanel jPanelCards;
    private javax.swing.JPanel jPanelDraw;
    private javax.swing.JPanel jPanelSettings;
    private javax.swing.JPanel jPanelStatus;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JSpinner jSpinSize;
    private javax.swing.JTabbedPane jTabs;
    private javax.swing.JTextArea jTextDescription;
    // End of variables declaration//GEN-END:variables
}
