/*
 * 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 eu.smoser.dungeongenerator.main;

import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
import eu.smoser.dungeongenerator.dungeon.Dungeon;
import eu.smoser.dungeongenerator.dungeon.Exit;
import eu.smoser.dungeongenerator.dungeon.Room;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import com.mxgraph.layout.*;
import com.mxgraph.util.*;
import com.mxgraph.swing.mxGraphComponent;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.HeadlessException;
import java.awt.Label;
import java.nio.file.*;
import javax.imageio.ImageIO;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.jgrapht.UndirectedGraph;
import org.jgrapht.ext.*;
import java.awt.image.BufferedImage;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;

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

    private static final long serialVersionUID = 1L;

    private transient Dungeon mDungeon;
    private transient UndirectedGraph<Room, Exit> mGraph;
    transient 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();
        jMenuTreasure = new javax.swing.JMenuItem();
        jMenuEncounters = new javax.swing.JMenuItem();
        jMenuDescription = new javax.swing.JMenu();
        jMenuDescTxt = new javax.swing.JMenuItem();
        jMenuDescPdf = new javax.swing.JMenuItem();
        jMenuGraph = new javax.swing.JMenu();
        jMenuGraphGml = new javax.swing.JMenuItem();
        jMenuGraphPng = new javax.swing.JMenuItem();
        jMenuGraphPdf = new javax.swing.JMenuItem();
        jMenuPdf = new javax.swing.JMenuItem();
        jMenuClose = new javax.swing.JMenuItem();
        jMenuHelp = new javax.swing.JMenu();
        jMenuItemHelp = new javax.swing.JMenuItem();
        jMenuItemContact = new javax.swing.JMenuItem();
        jMenuItemGithub = 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("Raumanzahl");
        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("<html>\n<b>Experimenteller Modus</b><br/>\nschränkt Raumzahl nicht direkt ein, sondern ändert die Zufallsfunktion so, dass ihr Erwartungswert der Raumanzahl entspricht");
        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_DOWN_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);

        jMenuTreasure.setText("Neuer Schatz");
        jMenuTreasure.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuTreasureActionPerformed(evt);
            }
        });
        jMenu.add(jMenuTreasure);

        jMenuEncounters.setText("Neue Zufallsbegegnungen");
        jMenuEncounters.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuEncountersActionPerformed(evt);
            }
        });
        jMenu.add(jMenuEncounters);

        jMenuDescription.setText("Beschreibung exportieren");
        jMenuDescription.setEnabled(false);
        jMenuDescription.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuDescriptionActionPerformed(evt);
            }
        });

        jMenuDescTxt.setText("Textdokument");
        jMenuDescTxt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuDescTxtActionPerformed(evt);
            }
        });
        jMenuDescription.add(jMenuDescTxt);

        jMenuDescPdf.setText("PDF-Dokument");
        jMenuDescription.add(jMenuDescPdf);

        jMenu.add(jMenuDescription);

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

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

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

        jMenuGraphPdf.setText("PDF-Dokument");
        jMenuGraphPdf.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuGraphPdfActionPerformed(evt);
            }
        });
        jMenuGraph.add(jMenuGraphPdf);

        jMenu.add(jMenuGraph);

        jMenuPdf.setText("PDF erstellen");
        jMenuPdf.setEnabled(false);
        jMenuPdf.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuPdfActionPerformed(evt);
            }
        });
        jMenu.add(jMenuPdf);

        jMenuClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_DOWN_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");

        jMenuItemHelp.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        jMenuItemHelp.setText("Hilfe");
        jMenuItemHelp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemHelpActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemHelp);

        jMenuItemContact.setText("Kontakt");
        jMenuItemContact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemContactActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemContact);

        jMenuItemGithub.setText("Github");
        jMenuItemGithub.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemGithubActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemGithub);
        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
        Dungeon.Mode mode = SelectedMode();
        Dungeon.Type type = SelectedNatural();
        int size = (int) jSpinSize.getValue();
        mDungeon = new Dungeon(size, type);
        if (false && Dungeon.Experimental(type)) {
            JFrame frame = new JFrame("Debug");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            Label lab = new Label();
            lab.setText(mDungeon.GetGreedyMap().toString());
            frame.getContentPane().add(lab, BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
        mDungeon.generate(size, type, mode);
        mGraph = mDungeon.toGraph();
        JGraphXAdapter<Room, Exit> graphAdapter = new JGraphXAdapter<>(mGraph);
        mGraphComponent = new mxGraphComponent(graphAdapter);
        mGraphComponent.setEnabled(false);
        Map<String, Object> edgeStyle = graphAdapter.getStylesheet().getDefaultEdgeStyle();
        edgeStyle.put(mxConstants.STYLE_NOLABEL, true);
        edgeStyle.put(mxConstants.STYLE_ENDARROW, mxConstants.NONE);

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

        jPanelDraw.add(mGraphComponent);
        jTextDescription.setText(mDungeon.toString());
        jLabelStatus1.setText("Max: " + size);
        jLabelStatus2.setText("Type: " + type.toString());
        jLabelStatus3.setText("Mode: " + mode.toString());

        jMenuNew.setEnabled(true);
        jMenuDescription.setEnabled(true);
        jMenuGraph.setEnabled(true);
        jMenuPdf.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
        jMenuNew.setEnabled(false);
        jMenuDescription.setEnabled(false);
        jMenuGraph.setEnabled(false);
        jMenuPdf.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 jMenuDescTxtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuDescTxtActionPerformed
        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_jMenuDescTxtActionPerformed

    private void jMenuGraphGmlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuGraphGmlActionPerformed
        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<Room, Exit> 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_jMenuGraphGmlActionPerformed

    private void jMenuGraphPngActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuGraphPngActionPerformed
        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, 10, 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_jMenuGraphPngActionPerformed

    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, "<html><b>DungeonGenerator Version " + number + "</b>\n"
                + "<html><i>(compiled on " + date + ")</i>\n"
                + "\n"
                + "<html><b>The MIT License (MIT)</b>\n"
                + "\n"
                + "<html>Copyright &copy; 2016 <a href='https://smoser.eu/'>Simon Moser IT</a>\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"
                + "<html>Icons made by <a href='http://www.flaticon.com/authors/revicon'>Revicon</a>", "Über", JOptionPane.QUESTION_MESSAGE);
    }//GEN-LAST:event_jMenuItemAboutActionPerformed

    private void jMenuItemContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemContactActionPerformed
        try {
            Desktop.getDesktop().mail(new URI("mailto:info@smoser.eu?subject=DungeonGenerator"));
        } catch (URISyntaxException | IOException ex) {
            Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jMenuItemContactActionPerformed

    private void jMenuItemHelpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemHelpActionPerformed
        try {
            Desktop.getDesktop().browse(new URI("https://naclador.de/git/mosers/DungeonGenerator/issues"));
        } catch (URISyntaxException | IOException ex) {
            Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jMenuItemHelpActionPerformed

    private void jMenuItemGithubActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemGithubActionPerformed
        try {
            Desktop.getDesktop().browse(new URI("https://naclador.de/git/mosers/DungeonGenerator/"));
        } catch (URISyntaxException | IOException ex) {
            Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jMenuItemGithubActionPerformed

    private void jMenuPdfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuPdfActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Portable Document Format", ".pdf");
        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(".pdf")) {
                    file = new File(file.getCanonicalPath() + ".pdf");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                File tmpDesc = File.createTempFile("desc", ".pdf");
                File tmpGraph = File.createTempFile("graph", ".pdf");
                CreateDescPDF(tmpDesc);
                CreateGraphPDF(tmpGraph);
                PDFMergerUtility merger = new PDFMergerUtility();
                merger.setDestinationFileName(file.getCanonicalPath());
                merger.addSource(tmpGraph);
                merger.addSource(tmpDesc);
                merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());      
                tmpDesc.delete();
                tmpGraph.delete();
                JOptionPane.showMessageDialog(this, "Gespeichert!");
            } catch (IOException | HeadlessException | DocumentException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuPdfActionPerformed

    private void jMenuGraphPdfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuGraphPdfActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Portable Document Format", ".pdf");
        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(".pdf")) {
                    file = new File(file.getCanonicalPath() + ".pdf");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                CreateGraphPDF(file);
                JOptionPane.showMessageDialog(this, "Gespeichert!");
            } catch (IOException | HeadlessException | DocumentException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuGraphPdfActionPerformed

    private void jMenuDescriptionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuDescriptionActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Portable Document Format", ".pdf");
        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(".pdf")) {
                    file = new File(file.getCanonicalPath() + ".pdf");
                }
                if (file.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, "Existierende Datei überschreiben?");
                    if (result != JOptionPane.YES_OPTION) {
                        return;
                    }
                    file.delete();
                }
                CreateDescPDF(file);
                JOptionPane.showMessageDialog(this, "Gespeichert!");
            } catch (IOException | HeadlessException | DocumentException ex) {
                Logger.getLogger(DungeonGeneratorUI.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_jMenuDescriptionActionPerformed

    private void jCheckBoxExpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxExpActionPerformed
        jComboBoxMode.setEnabled(!jCheckBoxExp.isSelected());
        jLabel2.setEnabled(!jCheckBoxExp.isSelected());
        //jComboBoxMode.setSelectedItem("Zufällig");
    }//GEN-LAST:event_jCheckBoxExpActionPerformed

    private void jMenuTreasureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuTreasureActionPerformed
        JFrame treasureGenerator = new TreasureGenerator();
        treasureGenerator.setVisible(true);
    }//GEN-LAST:event_jMenuTreasureActionPerformed

    private void jMenuEncountersActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuEncountersActionPerformed
        JFrame encounters = new EncounterGenerator();
        encounters.setVisible(true);
    }//GEN-LAST:event_jMenuEncountersActionPerformed

    private void CreateGraphPDF(File file) throws BadElementException, IOException, DocumentException {
        Document document = new Document(PageSize.A4);
        Image image = Image.getInstance(mxCellRenderer.createBufferedImage(mGraphComponent.getGraph(), null, 10, Color.WHITE, true, null), Color.WHITE);
        image.scaleToFit(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin(), document.getPageSize().getHeight() - document.topMargin() - document.bottomMargin());

        PdfWriter.getInstance(document, new FileOutputStream(file));
        document.open();
        document.add(image);
        document.close();
    }

    private void CreateDescPDF(File file) throws BadElementException, IOException, DocumentException {
        Document document = new Document(PageSize.A4);
        Image image = Image.getInstance(mxCellRenderer.createBufferedImage(mGraphComponent.getGraph(), null, 10, Color.WHITE, true, null), Color.WHITE);
        image.scaleToFit(document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin(), document.getPageSize().getHeight() - document.topMargin() - document.bottomMargin());

        PdfWriter.getInstance(document, new FileOutputStream(file));
        document.open();
        Font myfont = new Font();
        myfont.setStyle(Font.NORMAL);
        myfont.setSize(11);
        document.add(new Paragraph("\n"));
        String[] outputString = mDungeon.toString().split("\n");
        for (String s : outputString) {
            Paragraph para = new Paragraph(s + "\n", myfont);
            para.setAlignment(Element.ALIGN_JUSTIFIED);
            document.add(para);
        }
        document.close();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the FlatLaf look and feel for modern UI */
        try {
            UIManager.setLookAndFeel(new FlatDarkLaf());
        } catch (Exception ex) {
            System.err.println("Failed to initialize FlatLaf");
            // Fallback to Nimbus
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (Exception e) {
                java.util.logging.Logger.getLogger(DungeonGeneratorUI.class.getName()).log(java.util.logging.Level.SEVERE, null, e);
            }
        }

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(() -> {
            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 jMenuDescPdf;
    private javax.swing.JMenuItem jMenuDescTxt;
    private javax.swing.JMenu jMenuDescription;
    private javax.swing.JMenuItem jMenuEncounters;
    private javax.swing.JMenu jMenuGraph;
    private javax.swing.JMenuItem jMenuGraphGml;
    private javax.swing.JMenuItem jMenuGraphPdf;
    private javax.swing.JMenuItem jMenuGraphPng;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuItemContact;
    private javax.swing.JMenuItem jMenuItemGithub;
    private javax.swing.JMenuItem jMenuItemHelp;
    private javax.swing.JMenuItem jMenuNew;
    private javax.swing.JMenuItem jMenuPdf;
    private javax.swing.JMenuItem jMenuTreasure;
    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
}
