/*
 * MainGUI.java
 *
 * Created on 12 de Janeiro de 2008, 19:37
 */
package br.gfca.openstereogram.gui;

import br.gfca.openstereogram.stereo.ImageManipulator;
import br.gfca.openstereogram.stereo.StereogramGenerator;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.HeadlessException;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author  Gustavo
 */
public class MainGUI extends javax.swing.JFrame {

    private static final long serialVersionUID = 5494881572447296266L;
    private StereogramWindow stereogramWindow;

    /** Creates new form MainGUI */
    public MainGUI() {
        initComponents();
        this.setLocationRelativeTo(null);
        this.stereogramWindow = null;
    }

    /** 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.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lookButtonGroup = new javax.swing.ButtonGroup();
        elementButtonGroup = new javax.swing.ButtonGroup();
        mapFileChooser = new javax.swing.JFileChooser();
        patternFileChooser = new javax.swing.JFileChooser();
        topPanel = new javax.swing.JPanel();
        typePanel = new javax.swing.JPanel();
        lookLabel = new javax.swing.JLabel();
        dottedRadioButton = new javax.swing.JRadioButton();
        texturedRadioButton = new javax.swing.JRadioButton();
        elementLabel = new javax.swing.JLabel();
        textRadioButton = new javax.swing.JRadioButton();
        mapRadioButton = new javax.swing.JRadioButton();
        parametersPanel = new javax.swing.JPanel();
        observationLabel = new javax.swing.JLabel();
        observationTextField = new javax.swing.JTextField();
        eyeLabel = new javax.swing.JLabel();
        eyeTextField = new javax.swing.JTextField();
        maxDepthLabel = new javax.swing.JLabel();
        maxDepthTextField = new javax.swing.JTextField();
        minDepthLabel = new javax.swing.JLabel();
        minDepthTextField = new javax.swing.JTextField();
        widthLabel = new javax.swing.JLabel();
        widthTextField = new javax.swing.JTextField();
        heightLabel = new javax.swing.JLabel();
        heightTextField = new javax.swing.JTextField();
        vPpiLabel = new javax.swing.JLabel();
        vPpiTextField = new javax.swing.JTextField();
        hPpiLabel = new javax.swing.JLabel();
        hPpiTextField = new javax.swing.JTextField();
        guideAndGeneratePanel = new javax.swing.JPanel();
        guideImagePanel = new javax.swing.JPanel();
        generateButton = new javax.swing.JButton();
        bottomPanel = new javax.swing.JPanel();
        mapAndPatternPanel = new javax.swing.JPanel();
        textLabel = new javax.swing.JLabel();
        textTextField = new javax.swing.JTextField();
        sizeLabel = new javax.swing.JLabel();
        sizeSpinner = new javax.swing.JSpinner();
        mapLabel = new javax.swing.JLabel();
        mapPreviewPanel = new br.gfca.openstereogram.gui.ImagePreviewPanel();
        patternLabel = new javax.swing.JLabel();
        patternPreviewPanel = new br.gfca.openstereogram.gui.ImagePreviewPanel();
        colorsPanel = new javax.swing.JPanel();
        color1Label = new javax.swing.JLabel();
        color1Panel = new javax.swing.JPanel();
        color2Label = new javax.swing.JLabel();
        color2Panel = new javax.swing.JPanel();
        color3Label = new javax.swing.JLabel();
        color3Panel = new javax.swing.JPanel();
        thirdColorCheckBox = new javax.swing.JCheckBox();
        intensityLabel = new javax.swing.JLabel();
        intensitySlider = new javax.swing.JSlider();
        percentLabel = new javax.swing.JLabel();
        jMenuBar = new javax.swing.JMenuBar();
        helpMenu = new javax.swing.JMenu();
        helpMenuItem = new javax.swing.JMenuItem();
        helpSeparator = new javax.swing.JSeparator();
        aboutMenuItem = new javax.swing.JMenuItem();

        mapFileChooser.setCurrentDirectory(new File("./images/depthMaps/"));
        mapFileChooser.setDialogTitle("Open depth map");
        mapFileChooser.setFileFilter(new FileNameExtensionFilter("Image file (png, jpg, jpeg, gif, bmp)", "png", "jpg", "jpeg", "gif", "bmp"));

        patternFileChooser.setCurrentDirectory(new File("./images/texturePatterns/"));
        patternFileChooser.setDialogTitle("Open texture pattern");
        patternFileChooser.setFileFilter(new FileNameExtensionFilter("Image file (png, jpg, jpeg, gif, bmp)", "png", "jpg", "jpeg", "gif", "bmp"));

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Open Stereogram");
        setResizable(false);

        topPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        typePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        typePanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        lookLabel.setText("Stereogram look:");
        typePanel.add(lookLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, 130, -1));

        lookButtonGroup.add(dottedRadioButton);
        dottedRadioButton.setText("Dotted");
        dottedRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        dottedRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
        dottedRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                dottedRadioButtonStateChanged(evt);
            }
        });
        typePanel.add(dottedRadioButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 40, 120, -1));

        lookButtonGroup.add(texturedRadioButton);
        texturedRadioButton.setSelected(true);
        texturedRadioButton.setText("Textured");
        texturedRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        texturedRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
        typePanel.add(texturedRadioButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 70, 120, -1));

        elementLabel.setText("Hidden element:");
        typePanel.add(elementLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 110, 130, -1));

        elementButtonGroup.add(textRadioButton);
        textRadioButton.setText("Text");
        textRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        textRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
        textRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                textRadioButtonStateChanged(evt);
            }
        });
        typePanel.add(textRadioButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 170, 120, -1));

        elementButtonGroup.add(mapRadioButton);
        mapRadioButton.setSelected(true);
        mapRadioButton.setText("Depth map");
        mapRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        mapRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
        typePanel.add(mapRadioButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 140, 120, -1));

        topPanel.add(typePanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 150, 250));

        parametersPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        parametersPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        observationLabel.setText("Obs. distance:");
        parametersPanel.add(observationLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, 100, -1));

        observationTextField.setText("14");
        parametersPanel.add(observationTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 30, 50, -1));

        eyeLabel.setText("Eye separation:");
        parametersPanel.add(eyeLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 10, 100, -1));

        eyeTextField.setText("2.5");
        parametersPanel.add(eyeTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 30, 50, -1));

        maxDepthLabel.setText("Max. depth:");
        parametersPanel.add(maxDepthLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 70, 100, -1));

        maxDepthTextField.setText("12");
        parametersPanel.add(maxDepthTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 90, 50, -1));

        minDepthLabel.setText("Min. depth:");
        parametersPanel.add(minDepthLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 70, 100, -1));

        minDepthTextField.setText("0");
        parametersPanel.add(minDepthTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 90, 50, -1));

        widthLabel.setText("Width:");
        parametersPanel.add(widthLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 130, 100, -1));

        widthTextField.setText("800");
        parametersPanel.add(widthTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 150, 50, -1));

        heightLabel.setText("Height:");
        parametersPanel.add(heightLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 130, 100, -1));

        heightTextField.setText("600");
        parametersPanel.add(heightTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 150, 50, -1));

        vPpiLabel.setText("Vert. PPI:");
        parametersPanel.add(vPpiLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 190, 100, -1));

        vPpiTextField.setText("81");
        parametersPanel.add(vPpiTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(130, 210, 50, -1));

        hPpiLabel.setText("Horiz. PPI:");
        parametersPanel.add(hPpiLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 190, 100, -1));

        hPpiTextField.setText("81");
        parametersPanel.add(hPpiTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 210, 50, -1));

        topPanel.add(parametersPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(160, 0, 240, 250));

        guideAndGeneratePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        guideAndGeneratePanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        guideImagePanel.setBackground(new java.awt.Color(255, 255, 255));
        guideImagePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        javax.swing.GroupLayout guideImagePanelLayout = new javax.swing.GroupLayout(guideImagePanel);
        guideImagePanel.setLayout(guideImagePanelLayout);
        guideImagePanelLayout.setHorizontalGroup(
            guideImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 186, Short.MAX_VALUE)
        );
        guideImagePanelLayout.setVerticalGroup(
            guideImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 206, Short.MAX_VALUE)
        );

        guideAndGeneratePanel.add(guideImagePanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 190, 210));

        generateButton.setText("Generate");
        generateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                generateButtonActionPerformed(evt);
            }
        });
        guideAndGeneratePanel.add(generateButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 220, 170, -1));

        topPanel.add(guideAndGeneratePanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(410, 0, -1, 250));

        bottomPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        mapAndPatternPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        mapAndPatternPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        textLabel.setText("Hidden text:");
        textLabel.setEnabled(false);
        mapAndPatternPanel.add(textLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, 140, -1));

        textTextField.setText(" ");
        textTextField.setEnabled(false);
        mapAndPatternPanel.add(textTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 30, 140, -1));

        sizeLabel.setText("Text size:");
        sizeLabel.setEnabled(false);
        mapAndPatternPanel.add(sizeLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 10, 80, -1));

        sizeSpinner.setEnabled(false);
        sizeSpinner.setValue(200);
        mapAndPatternPanel.add(sizeSpinner, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 30, 80, -1));

        mapLabel.setText("Depth map:");
        mapAndPatternPanel.add(mapLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(160, 80, 110, -1));

        mapPreviewPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                mapPreviewPanelMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                mapPreviewPanelMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                mapPreviewPanelMousePressed(evt);
            }
        });
        mapAndPatternPanel.add(mapPreviewPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(160, 100, 110, 110));

        patternLabel.setText("Texture pattern:");
        mapAndPatternPanel.add(patternLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 80, 110, -1));

        patternPreviewPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                patternPreviewPanelMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                patternPreviewPanelMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                patternPreviewPanelMousePressed(evt);
            }
        });
        mapAndPatternPanel.add(patternPreviewPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 100, 110, 110));

        bottomPanel.add(mapAndPatternPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 300, 220));

        colorsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        colorsPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        color1Label.setText("Color 1:");
        color1Label.setEnabled(false);
        colorsPanel.add(color1Label, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, 60, -1));

        color1Panel.setBackground(new java.awt.Color(255, 0, 0));
        color1Panel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        color1Panel.setEnabled(false);
        color1Panel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                color1PanelMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                color1PanelMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                color1PanelMousePressed(evt);
            }
        });

        javax.swing.GroupLayout color1PanelLayout = new javax.swing.GroupLayout(color1Panel);
        color1Panel.setLayout(color1PanelLayout);
        color1PanelLayout.setHorizontalGroup(
            color1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );
        color1PanelLayout.setVerticalGroup(
            color1PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );

        colorsPanel.add(color1Panel, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 30, 50, 50));

        color2Label.setText("Color 2:");
        color2Label.setEnabled(false);
        colorsPanel.add(color2Label, new org.netbeans.lib.awtextra.AbsoluteConstraints(100, 10, 60, -1));

        color2Panel.setBackground(new java.awt.Color(0, 255, 0));
        color2Panel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        color2Panel.setEnabled(false);
        color2Panel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                color2PanelMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                color2PanelMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                color2PanelMousePressed(evt);
            }
        });

        javax.swing.GroupLayout color2PanelLayout = new javax.swing.GroupLayout(color2Panel);
        color2Panel.setLayout(color2PanelLayout);
        color2PanelLayout.setHorizontalGroup(
            color2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );
        color2PanelLayout.setVerticalGroup(
            color2PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );

        colorsPanel.add(color2Panel, new org.netbeans.lib.awtextra.AbsoluteConstraints(100, 30, 50, 50));

        color3Label.setText("Color 3:");
        color3Label.setEnabled(false);
        colorsPanel.add(color3Label, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 10, 60, -1));

        color3Panel.setBackground(new java.awt.Color(0, 0, 255));
        color3Panel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        color3Panel.setEnabled(false);
        color3Panel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                color3PanelMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                color3PanelMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                color3PanelMousePressed(evt);
            }
        });

        javax.swing.GroupLayout color3PanelLayout = new javax.swing.GroupLayout(color3Panel);
        color3Panel.setLayout(color3PanelLayout);
        color3PanelLayout.setHorizontalGroup(
            color3PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );
        color3PanelLayout.setVerticalGroup(
            color3PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 48, Short.MAX_VALUE)
        );

        colorsPanel.add(color3Panel, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 30, 50, 50));

        thirdColorCheckBox.setSelected(true);
        thirdColorCheckBox.setText("3rd color");
        thirdColorCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        thirdColorCheckBox.setEnabled(false);
        thirdColorCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
        thirdColorCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                thirdColorCheckBoxActionPerformed(evt);
            }
        });
        colorsPanel.add(thirdColorCheckBox, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 100, 80, -1));

        intensityLabel.setText("1st color intensity:");
        intensityLabel.setEnabled(false);
        colorsPanel.add(intensityLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 150, 200, -1));

        intensitySlider.setMaximum(99);
        intensitySlider.setMinimum(1);
        intensitySlider.setPaintLabels(true);
        intensitySlider.setPaintTicks(true);
        intensitySlider.setSnapToTicks(true);
        intensitySlider.setEnabled(false);
        intensitySlider.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                intensitySliderStateChanged(evt);
            }
        });
        colorsPanel.add(intensitySlider, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 170, -1, -1));

        percentLabel.setText("50%");
        percentLabel.setEnabled(false);
        colorsPanel.add(percentLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(230, 170, 50, -1));

        bottomPanel.add(colorsPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(310, 0, 290, 220));

        helpMenu.setText("Help");

        helpMenuItem.setText("Content...");
        helpMenu.add(helpMenuItem);
        helpMenu.add(helpSeparator);

        aboutMenuItem.setText("About...");
        aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutMenuItem);

        jMenuBar.add(helpMenu);

        setJMenuBar(jMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(topPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(bottomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(topPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bottomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

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

    private void generateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateButtonActionPerformed
        try {
            if (this.dottedRadioButton.isSelected()) {
                BufferedImage depthMap = null;
                if (this.textRadioButton.isSelected()) {
                    depthMap = ImageManipulator.generateTextDepthMap(getMapText(), getFontSize(),
                            getStereogramWidth(), getStereogramHeight());
                } else {
                    depthMap = getImage(this.mapFileChooser.getSelectedFile());
                }
                Color c1 = getColor1();
                Color c2 = getColor2();
                Color c3 = getColor3();
                float intensity = getIntensity();
                float obsDistance = getObservationDistance();
                float eyeSep = getEyeSeparation();
                float maxDepth = getMaxDepth();
                float minDepth = getMinDepth();
                int width = getStereogramWidth();
                int height = getStereogramHeight();
                int horizPPI = getHorizontalPPI();

                BufferedImage stereogram = StereogramGenerator.generateSIRD(
                        depthMap,
                        c1, c2, c3, intensity,
                        width, height,
                        obsDistance, eyeSep,
                        maxDepth, minDepth,
                        horizPPI);
                if (this.stereogramWindow != null) {
                    this.stereogramWindow.dispose();
                }
                this.stereogramWindow = new StereogramWindow(stereogram);
                this.stereogramWindow.setVisible(true);
            } else {
                BufferedImage depthMap = null;
                if (this.textRadioButton.isSelected()) {
                    depthMap = ImageManipulator.generateTextDepthMap(getMapText(), getFontSize(), getStereogramWidth(), getStereogramHeight());
                } else {
                    depthMap = getImage(this.mapFileChooser.getSelectedFile());
                }
                BufferedImage texturePattern = getImage(this.patternFileChooser.getSelectedFile());
                float obsDistance = getObservationDistance();
                float eyeSep = getEyeSeparation();
                float maxDepth = getMaxDepth();
                float minDepth = getMinDepth();
                int width = getStereogramWidth();
                int height = getStereogramHeight();
                int vertPPI = getVerticalPPI();
                int horizPPI = getHorizontalPPI();

                BufferedImage stereogram = StereogramGenerator.generateTexturedSIRD(
                        depthMap, texturePattern,
                        width, height,
                        obsDistance, eyeSep,
                        maxDepth, minDepth,
                        horizPPI, vertPPI);
                if (this.stereogramWindow != null) {
                    this.stereogramWindow.dispose();
                }
                this.stereogramWindow = new StereogramWindow(stereogram);
                this.stereogramWindow.setVisible(true);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error generating stereogram." +
                    System.getProperty("line.separator") +
                    "ERROR: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_generateButtonActionPerformed

    private void patternPreviewPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_patternPreviewPanelMousePressed
        if (this.patternPreviewPanel.isEnabled()) {
            int button = this.patternFileChooser.showOpenDialog(this);
            if (button == JFileChooser.APPROVE_OPTION) {
                try {
                    File f = this.patternFileChooser.getSelectedFile();
                    BufferedImage bf = this.getImage(f);
                    this.patternPreviewPanel.setImage(bf);
                } catch (Exception e) {
                    this.patternPreviewPanel.resetImage();
                    this.patternFileChooser.setSelectedFile(null);
                    JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }//GEN-LAST:event_patternPreviewPanelMousePressed

    private void mapPreviewPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapPreviewPanelMousePressed
        if (this.mapPreviewPanel.isEnabled()) {
            int button = this.mapFileChooser.showOpenDialog(this);
            if (button == JFileChooser.APPROVE_OPTION) {
                try {
                    File f = this.mapFileChooser.getSelectedFile();
                    BufferedImage bf = this.getImage(f);
                    this.mapPreviewPanel.setImage(bf);
                } catch (Exception e) {
                    this.mapPreviewPanel.resetImage();
                    JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }//GEN-LAST:event_mapPreviewPanelMousePressed

    private void intensitySliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_intensitySliderStateChanged
        if (this.intensitySlider.isEnabled()) {
            int value = this.intensitySlider.getValue();
            this.percentLabel.setText(value + "%");
        }
    }//GEN-LAST:event_intensitySliderStateChanged

    private void color3PanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color3PanelMousePressed
        this.handleColorChooser(this.color3Panel, 3);
    }//GEN-LAST:event_color3PanelMousePressed

    private void color2PanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color2PanelMousePressed
        this.handleColorChooser(this.color2Panel, 2);
    }//GEN-LAST:event_color2PanelMousePressed

    private void color1PanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color1PanelMousePressed
        this.handleColorChooser(this.color1Panel, 1);
    }//GEN-LAST:event_color1PanelMousePressed

    private void handleColorChooser(JPanel colorPanel, int panelNumber) {
        try {
            if (colorPanel.isEnabled()) {
                Color newColor = JColorChooser.showDialog(this, "Select color " + panelNumber, colorPanel.getBackground());
                if (newColor != null) {
                    colorPanel.setBackground(newColor);
                }
            }
        } catch (HeadlessException he) {
        }
    }

    private void textRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_textRadioButtonStateChanged
        if (this.textRadioButton.isSelected()) {
            this.textLabel.setEnabled(true);
            this.textTextField.setEnabled(true);
            this.sizeLabel.setEnabled(true);
            this.sizeSpinner.setEnabled(true);

            this.mapLabel.setEnabled(false);
            this.mapPreviewPanel.setEnabled(false);
        } else {
            this.textLabel.setEnabled(false);
            this.textTextField.setEnabled(false);
            this.sizeLabel.setEnabled(false);
            this.sizeSpinner.setEnabled(false);

            this.mapLabel.setEnabled(true);
            this.mapPreviewPanel.setEnabled(true);
        }
    }//GEN-LAST:event_textRadioButtonStateChanged

    private void dottedRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_dottedRadioButtonStateChanged
        if (this.dottedRadioButton.isSelected()) {
            this.patternLabel.setEnabled(false);
            this.patternPreviewPanel.setEnabled(false);

            this.vPpiLabel.setEnabled(false);
            this.vPpiTextField.setEnabled(false);

            this.color1Label.setEnabled(true);
            this.color1Panel.setEnabled(true);
            this.color2Label.setEnabled(true);
            this.color2Panel.setEnabled(true);
            this.thirdColorCheckBox.setEnabled(true);
            this.thirdColorCheckBoxActionPerformed(null);
        } else {
            this.patternLabel.setEnabled(true);
            this.patternPreviewPanel.setEnabled(true);

            this.vPpiLabel.setEnabled(true);
            this.vPpiTextField.setEnabled(true);

            this.color1Label.setEnabled(false);
            this.color1Panel.setEnabled(false);
            this.color2Label.setEnabled(false);
            this.color2Panel.setEnabled(false);
            this.color3Label.setEnabled(false);
            this.color3Panel.setEnabled(false);
            this.thirdColorCheckBox.setEnabled(false);
            this.intensityLabel.setEnabled(false);
            this.intensitySlider.setEnabled(false);
            this.percentLabel.setEnabled(false);
        }
    }//GEN-LAST:event_dottedRadioButtonStateChanged

    private void thirdColorCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_thirdColorCheckBoxActionPerformed
        if (this.thirdColorCheckBox.isSelected()) {
            this.color3Label.setEnabled(true);
            this.color3Panel.setEnabled(true);
            this.intensityLabel.setEnabled(false);
            this.intensitySlider.setEnabled(false);
            this.percentLabel.setEnabled(false);
        } else {
            this.color3Label.setEnabled(false);
            this.color3Panel.setEnabled(false);
            this.intensityLabel.setEnabled(true);
            this.intensitySlider.setEnabled(true);
            this.percentLabel.setEnabled(true);
        }
    }//GEN-LAST:event_thirdColorCheckBoxActionPerformed

    private void mapPreviewPanelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapPreviewPanelMouseEntered
        this.changeMouseCursor(false);
    }//GEN-LAST:event_mapPreviewPanelMouseEntered

    private void patternPreviewPanelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_patternPreviewPanelMouseEntered
        this.changeMouseCursor(false);
    }//GEN-LAST:event_patternPreviewPanelMouseEntered

    private void color1PanelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color1PanelMouseEntered
        this.changeMouseCursor(false);
    }//GEN-LAST:event_color1PanelMouseEntered

    private void color2PanelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color2PanelMouseEntered
        this.changeMouseCursor(false);
    }//GEN-LAST:event_color2PanelMouseEntered

    private void color3PanelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color3PanelMouseEntered
        this.changeMouseCursor(false);
    }//GEN-LAST:event_color3PanelMouseEntered

    private void mapPreviewPanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapPreviewPanelMouseExited
        this.changeMouseCursor(true);
    }//GEN-LAST:event_mapPreviewPanelMouseExited

    private void patternPreviewPanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_patternPreviewPanelMouseExited
        this.changeMouseCursor(true);
    }//GEN-LAST:event_patternPreviewPanelMouseExited

    private void color1PanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color1PanelMouseExited
        this.changeMouseCursor(true);
    }//GEN-LAST:event_color1PanelMouseExited

    private void color2PanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color2PanelMouseExited
        this.changeMouseCursor(true);
    }//GEN-LAST:event_color2PanelMouseExited

    private void color3PanelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_color3PanelMouseExited
        this.changeMouseCursor(true);
    }//GEN-LAST:event_color3PanelMouseExited

    private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed
        new AboutDialog( this, true ).setVisible(true);
    }//GEN-LAST:event_aboutMenuItemActionPerformed

    private void changeMouseCursor(boolean isDefault) {
        this.setCursor(isDefault ? Cursor.getDefaultCursor() : Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    }

    private BufferedImage getImage(File file) throws Exception {
        try {
            return ImageIO.read(file);
        } catch (Exception e) {
            throw new Exception("Error while loading image." +
                    System.getProperty("line.separator") +
                    "ERROR: " + e.getMessage());
        }
    }

    private Color getColor1() {
        return this.color1Panel.getBackground();
    }

    private Color getColor2() {
        return this.color2Panel.getBackground();
    }

    private Color getColor3() {
        return this.color3Panel.isEnabled() ? this.color3Panel.getBackground() : null;
    }

    private float getIntensity() {
        return this.intensitySlider.getValue() / 100f;
    }

    private int getStereogramWidth() throws Exception {
        try {
            return Integer.parseInt(this.widthTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid width.");
        }
    }

    private int getStereogramHeight() throws Exception {
        try {
            return Integer.parseInt(this.heightTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid height.");
        }
    }

    private float getObservationDistance() throws Exception {
        try {
            return Float.parseFloat(this.observationTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid observation distance.");
        }
    }

    private float getEyeSeparation() throws Exception {
        try {
            return Float.parseFloat(this.eyeTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid eye separation.");
        }
    }

    private float getMaxDepth() throws Exception {
        try {
            return Float.parseFloat(this.maxDepthTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid max. depth.");
        }
    }

    private float getMinDepth() throws Exception {
        try {
            return Float.parseFloat(this.minDepthTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid min. depth.");
        }
    }

    private int getHorizontalPPI() throws Exception {
        try {
            return Integer.parseInt(this.hPpiTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid horizontal PPI.");
        }
    }

    private int getVerticalPPI() throws Exception {
        try {
            return Integer.parseInt(this.vPpiTextField.getText().trim());
        } catch (Exception e) {
            throw new Exception("Inavlid vertical PPI.");
        }
    }

    private String getMapText() {
        return this.textTextField.getText() != null ? this.textTextField.getText().trim() : "";
    }

    private int getFontSize() {
        return (Integer) this.sizeSpinner.getValue();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JPanel bottomPanel;
    private javax.swing.JLabel color1Label;
    private javax.swing.JPanel color1Panel;
    private javax.swing.JLabel color2Label;
    private javax.swing.JPanel color2Panel;
    private javax.swing.JLabel color3Label;
    private javax.swing.JPanel color3Panel;
    private javax.swing.JPanel colorsPanel;
    private javax.swing.JRadioButton dottedRadioButton;
    private javax.swing.ButtonGroup elementButtonGroup;
    private javax.swing.JLabel elementLabel;
    private javax.swing.JLabel eyeLabel;
    private javax.swing.JTextField eyeTextField;
    private javax.swing.JButton generateButton;
    private javax.swing.JPanel guideAndGeneratePanel;
    private javax.swing.JPanel guideImagePanel;
    private javax.swing.JLabel hPpiLabel;
    private javax.swing.JTextField hPpiTextField;
    private javax.swing.JLabel heightLabel;
    private javax.swing.JTextField heightTextField;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JMenuItem helpMenuItem;
    private javax.swing.JSeparator helpSeparator;
    private javax.swing.JLabel intensityLabel;
    private javax.swing.JSlider intensitySlider;
    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.ButtonGroup lookButtonGroup;
    private javax.swing.JLabel lookLabel;
    private javax.swing.JPanel mapAndPatternPanel;
    private javax.swing.JFileChooser mapFileChooser;
    private javax.swing.JLabel mapLabel;
    private br.gfca.openstereogram.gui.ImagePreviewPanel mapPreviewPanel;
    private javax.swing.JRadioButton mapRadioButton;
    private javax.swing.JLabel maxDepthLabel;
    private javax.swing.JTextField maxDepthTextField;
    private javax.swing.JLabel minDepthLabel;
    private javax.swing.JTextField minDepthTextField;
    private javax.swing.JLabel observationLabel;
    private javax.swing.JTextField observationTextField;
    private javax.swing.JPanel parametersPanel;
    private javax.swing.JFileChooser patternFileChooser;
    private javax.swing.JLabel patternLabel;
    private br.gfca.openstereogram.gui.ImagePreviewPanel patternPreviewPanel;
    private javax.swing.JLabel percentLabel;
    private javax.swing.JLabel sizeLabel;
    private javax.swing.JSpinner sizeSpinner;
    private javax.swing.JLabel textLabel;
    private javax.swing.JRadioButton textRadioButton;
    private javax.swing.JTextField textTextField;
    private javax.swing.JRadioButton texturedRadioButton;
    private javax.swing.JCheckBox thirdColorCheckBox;
    private javax.swing.JPanel topPanel;
    private javax.swing.JPanel typePanel;
    private javax.swing.JLabel vPpiLabel;
    private javax.swing.JTextField vPpiTextField;
    private javax.swing.JLabel widthLabel;
    private javax.swing.JTextField widthTextField;
    // End of variables declaration//GEN-END:variables
}
