/***
 * Neuroph  http://neuroph.sourceforge.net
 * Copyright by Neuroph Project (C) 2008
 *
 * This file is part of Neuroph framework.
 *
 * Neuroph is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Neuroph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Neuroph. If not, see <http://www.gnu.org/licenses/>.
 */
package org.neuroph.easyneurons.ocr.hwr;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import org.neuroph.contrib.imgrec.ColorMode;
import org.neuroph.contrib.imgrec.FractionRgbData;
import org.neuroph.contrib.imgrec.ImageRecognitionHelper;
import org.neuroph.contrib.ocr.OcrHelper;
import org.neuroph.contrib.ocr.OcrPlugin;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.learning.TrainingSet;
import org.neuroph.easyneurons.ProjectManager;
import org.neuroph.easyneurons.imgrec.ImagesLoader;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.VectorParser;
import org.neuroph.util.plugins.LabelsPlugin;

/**
 *
 * @author Mefistofeles
 */
public class HandwritingRecognitionToolFrame extends javax.swing.JInternalFrame {

    /** Creates new form GUI */
    public HandwritingRecognitionToolFrame(String title, boolean resizable, boolean closable, boolean maximizable,
            boolean iconable) {

        super(title, resizable, closable, maximizable, iconable);
        initComponents();
        TreeManager.setLettersTreeModel(jTree1);

     //   recognition = new LetterRecognition();
    }

    private String[] formatOutput(String output) {
        return output.substring(1, output.length() - 1).split(", ");
    }

    /** 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() {
        java.awt.GridBagConstraints gridBagConstraints;

        southPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        centerTabbedPane = new javax.swing.JTabbedPane();
        trainingPanel = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        saveLetterTrainingButton = new javax.swing.JButton();
        clearLetterTrainingButton = new javax.swing.JButton();
        jPanel6 = new javax.swing.JPanel();
        drawingPanelTrening = new org.neuroph.easyneurons.ocr.hwr.DrawingPanel();
        jPanel8 = new javax.swing.JPanel();
        jImagePanel = new org.neuroph.easyneurons.ocr.hwr.JImagePanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();
        jLabel2 = new javax.swing.JLabel();
        trainingButton = new javax.swing.JButton();
        nextButton = new javax.swing.JButton();
        networkPanel = new javax.swing.JPanel();
        createNetworkButton = new javax.swing.JButton();
        jPanel4 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        neuralNetworkNameTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        NeuralNetworkFunctionTypeComboBox = new javax.swing.JComboBox();
        jLabel5 = new javax.swing.JLabel();
        hiddenLayerNeuronsTextField = new javax.swing.JTextField();
        recognitionPanel = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        leftPanel = new javax.swing.JPanel();
        jSplitPane2 = new javax.swing.JSplitPane();
        upperPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        acceptLetterButton = new javax.swing.JButton();
        discardLetterButton = new javax.swing.JButton();
        jCheckBox1 = new javax.swing.JCheckBox();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        probabilitiesList = new javax.swing.JList();
        botomPanel = new javax.swing.JPanel();
        bottomPanelII = new javax.swing.JPanel();
        recognizeLetterButton = new javax.swing.JButton();
        clearLetterButton = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        drawingPanelRecognition = new org.neuroph.easyneurons.ocr.hwr.DrawingPanel();
        rightPanel = new javax.swing.JPanel();
        rightBotomPanel = new javax.swing.JPanel();
        jSpinner1 = new javax.swing.JSpinner();
        jToggleButton1 = new javax.swing.JToggleButton();
        jToggleButton2 = new javax.swing.JToggleButton();
        jToggleButton3 = new javax.swing.JToggleButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        aboutPanel = new javax.swing.JPanel();
        jScrollPane5 = new javax.swing.JScrollPane();
        aboutTextArea = new javax.swing.JTextArea();
        aboutTextArea.setText("This software is part of Neuroph Project, and it\n" +
            "demonstrates how neural networks can be applied for\n" +
            "handwritting recognition.\n\n" +
            "See http://neuroph.sourceforge.net for more info\n\n" +
            "--------------Mentor--------------\n" +
            "Zoran Sevarac\n " +
            "email: sevarac@gmail.com\n\n" +
            "-----------Developers-----------\n" +
            "Boris Horvat\n " +
            "email: horvat.z.boris@gmail.com\n" +
            "Nemanja Jovanovic\n " +
            "email: nemanja.jovanovic.1987@gmail.com\n" +
            "Damir Kocic\n " +
            "email: kocicdamir87@gmail.com\n\n" +
            "----------Project page----------\n" +
            "http://www.netbeans-serbia.org/projects/handwritingrecognition");

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Neuroph OCR - Handwriting Recognition");
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setMinimumSize(new java.awt.Dimension(800, 600));

        southPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0));
        southPanel.add(jLabel1);

        getContentPane().add(southPanel, java.awt.BorderLayout.PAGE_END);

        centerTabbedPane.setPreferredSize(new java.awt.Dimension(300, 130));

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

        jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Create picture"));
        jPanel5.setMinimumSize(new java.awt.Dimension(200, 50));
        jPanel5.setPreferredSize(new java.awt.Dimension(300, 200));

        jPanel7.setLayout(new java.awt.GridBagLayout());

        saveLetterTrainingButton.setText("Save");
        saveLetterTrainingButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveLetterTrainingButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        jPanel7.add(saveLetterTrainingButton, gridBagConstraints);

        clearLetterTrainingButton.setText("Clear");
        clearLetterTrainingButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearLetterTrainingButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.insets = new java.awt.Insets(0, 1, 0, 1);
        jPanel7.add(clearLetterTrainingButton, gridBagConstraints);

        jPanel6.setPreferredSize(new java.awt.Dimension(200, 250));
        jPanel6.setLayout(new java.awt.GridBagLayout());

        DrawingListener dl1 = new DrawingListener(drawingPanelTrening);
        drawingPanelTrening.addMouseMotionListener(dl1);
        drawingPanelTrening.addMouseListener(dl1);
        drawingPanelTrening.setPreferredSize(new java.awt.Dimension(200, 250));
        jPanel6.add(drawingPanelTrening, new java.awt.GridBagConstraints());

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
                .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
                    .addComponent(jPanel7, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE))
                .addGap(10, 10, 10))
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, 334, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        trainingPanel.add(jPanel5, java.awt.BorderLayout.LINE_START);

        jPanel8.setBorder(javax.swing.BorderFactory.createTitledBorder("Training set pictures"));

        jImagePanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jImagePanel.setPreferredSize(new java.awt.Dimension(150, 150));

        javax.swing.GroupLayout jImagePanelLayout = new javax.swing.GroupLayout(jImagePanel);
        jImagePanel.setLayout(jImagePanelLayout);
        jImagePanelLayout.setHorizontalGroup(
            jImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 146, Short.MAX_VALUE)
        );
        jImagePanelLayout.setVerticalGroup(
            jImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 146, Short.MAX_VALUE)
        );

        jTree1.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent evt) {
                TreePath[] paths = evt.getPaths();
                for (int i=0; i<paths.length; i++) {
                    if(!paths[i].getLastPathComponent().toString().contains("Lette")) {
                        if (evt.isAddedPath(i)) {
                            String path = new String();
                            String folder = TreeManager.getPath();
                            String file = paths[i].getLastPathComponent().toString();
                            path = folder + "/" + file;
                            jLabel2.setText(paths[i].getLastPathComponent().toString());
                            jImagePanel.setImage(path);
                            if(!jImagePanel.isVisible())
                            jImagePanel.setVisible(true);
                            break;
                        } else {

                            break;
                        }
                    } else {
                        jImagePanel.setVisible(false);
                        jLabel2.setText(new String());
                    }
                }
            }
        });
        jScrollPane3.setViewportView(jTree1);

        trainingButton.setText("Create Training set");
        trainingButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                trainingButtonActionPerformed(evt);
            }
        });

        nextButton.setText("Next > ");
        nextButton.setEnabled(false);
        nextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8);
        jPanel8.setLayout(jPanel8Layout);
        jPanel8Layout.setHorizontalGroup(
            jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel8Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel8Layout.createSequentialGroup()
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jImagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(jPanel8Layout.createSequentialGroup()
                                .addGap(14, 14, 14)
                                .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(jPanel8Layout.createSequentialGroup()
                        .addComponent(trainingButton)
                        .addGap(18, 18, 18)
                        .addComponent(nextButton)))
                .addContainerGap(83, Short.MAX_VALUE))
        );
        jPanel8Layout.setVerticalGroup(
            jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel8Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel8Layout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jImagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 79, Short.MAX_VALUE)
                .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(trainingButton)
                    .addComponent(nextButton))
                .addContainerGap())
        );

        trainingPanel.add(jPanel8, java.awt.BorderLayout.CENTER);

        centerTabbedPane.addTab("Images & training set", trainingPanel);

        createNetworkButton.setText("Create Network");
        createNetworkButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                createNetworkButtonActionPerformed(evt);
            }
        });

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Neural Netowrk Settings"));
        jPanel4.setLayout(new java.awt.GridBagLayout());

        jLabel6.setText("Neural network label:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.RELATIVE;
        gridBagConstraints.ipadx = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
        jPanel4.add(jLabel6, gridBagConstraints);

        neuralNetworkNameTextField.setPreferredSize(new java.awt.Dimension(100, 25));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 0);
        jPanel4.add(neuralNetworkNameTextField, gridBagConstraints);

        jLabel4.setText("Function:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
        jPanel4.add(jLabel4, gridBagConstraints);

        NeuralNetworkFunctionTypeComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[]{TransferFunctionType.valueOf("SIGMOID").getTypeLabel(),TransferFunctionType.valueOf("TANH").getTypeLabel()}));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 0);
        jPanel4.add(NeuralNetworkFunctionTypeComboBox, gridBagConstraints);

        jLabel5.setText("Hidden Layers Neurons Count:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
        jPanel4.add(jLabel5, gridBagConstraints);

        hiddenLayerNeuronsTextField.setPreferredSize(new java.awt.Dimension(100, 25));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel4.add(hiddenLayerNeuronsTextField, gridBagConstraints);

        javax.swing.GroupLayout networkPanelLayout = new javax.swing.GroupLayout(networkPanel);
        networkPanel.setLayout(networkPanelLayout);
        networkPanelLayout.setHorizontalGroup(
            networkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(networkPanelLayout.createSequentialGroup()
                .addGroup(networkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(networkPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(networkPanelLayout.createSequentialGroup()
                        .addGap(59, 59, 59)
                        .addComponent(createNetworkButton)))
                .addContainerGap(543, Short.MAX_VALUE))
        );
        networkPanelLayout.setVerticalGroup(
            networkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(networkPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 202, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(createNetworkButton)
                .addContainerGap(231, Short.MAX_VALUE))
        );

        centerTabbedPane.addTab("Neural Network", networkPanel);

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

        jSplitPane1.setDividerLocation(250);

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

        jSplitPane2.setDividerLocation(180);
        jSplitPane2.setDividerSize(3);
        jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane2.setEnabled(false);

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

        acceptLetterButton.setText("accept");
        acceptLetterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                acceptLetterButtonActionPerformed(evt);
            }
        });
        jPanel1.add(acceptLetterButton);

        discardLetterButton.setText("discard");
        discardLetterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                discardLetterButtonActionPerformed(evt);
            }
        });
        jPanel1.add(discardLetterButton);

        jCheckBox1.setText("auto add");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });
        jPanel1.add(jCheckBox1);

        upperPanel.add(jPanel1, java.awt.BorderLayout.PAGE_END);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Probabilites"));
        jPanel2.setLayout(new java.awt.BorderLayout());

        probabilitiesList.setModel(new javax.swing.DefaultListModel());
        probabilitiesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane2.setViewportView(probabilitiesList);

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

        upperPanel.add(jPanel2, java.awt.BorderLayout.CENTER);

        jSplitPane2.setTopComponent(upperPanel);

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

        recognizeLetterButton.setText("recognize");
        recognizeLetterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                recognizeLetterButtonActionPerformed(evt);
            }
        });
        bottomPanelII.add(recognizeLetterButton);

        clearLetterButton.setText("clear");
        clearLetterButton.setPreferredSize(new java.awt.Dimension(79, 23));
        clearLetterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearLetterButtonActionPerformed(evt);
            }
        });
        bottomPanelII.add(clearLetterButton);

        botomPanel.add(bottomPanelII, java.awt.BorderLayout.PAGE_END);

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Drawing area"));
        jPanel3.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                jPanel3ComponentResized(evt);
            }
        });
        jPanel3.setLayout(new java.awt.BorderLayout());

        DrawingListener dl = new DrawingListener(drawingPanelRecognition);
        drawingPanelRecognition.addMouseListener(dl);
        drawingPanelRecognition.addMouseMotionListener(dl);
        jPanel3.add(drawingPanelRecognition, java.awt.BorderLayout.CENTER);

        botomPanel.add(jPanel3, java.awt.BorderLayout.CENTER);

        jSplitPane2.setRightComponent(botomPanel);

        leftPanel.add(jSplitPane2, java.awt.BorderLayout.CENTER);

        jSplitPane1.setLeftComponent(leftPanel);

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

        jSpinner1.setModel(new javax.swing.SpinnerListModel(new String[] {"20", "24", "28", "32", "36"}));
        jSpinner1.setEditor(new javax.swing.JSpinner.ListEditor(jSpinner1));
        jSpinner1.setFocusable(false);
        jSpinner1.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jSpinner1StateChanged(evt);
            }
        });
        jSpinner1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jSpinner1KeyReleased(evt);
            }
        });
        rightBotomPanel.add(jSpinner1);

        jToggleButton1.setText("B");
        jToggleButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jToggleButton1ActionPerformed(evt);
            }
        });
        rightBotomPanel.add(jToggleButton1);

        jToggleButton2.setText("I");
        jToggleButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jToggleButton2ActionPerformed(evt);
            }
        });
        rightBotomPanel.add(jToggleButton2);

        jToggleButton3.setText("U");
        jToggleButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jToggleButton3ActionPerformed(evt);
            }
        });
        rightBotomPanel.add(jToggleButton3);

        rightPanel.add(rightBotomPanel, java.awt.BorderLayout.PAGE_END);

        jTextArea1.setFont(new java.awt.Font("Serif", 0, 20));
        jScrollPane1.setViewportView(jTextArea1);

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

        jSplitPane1.setRightComponent(rightPanel);

        recognitionPanel.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        centerTabbedPane.addTab("Test", recognitionPanel);

        aboutTextArea.setColumns(20);
        aboutTextArea.setEditable(false);
        aboutTextArea.setRows(5);
        jScrollPane5.setViewportView(aboutTextArea);

        javax.swing.GroupLayout aboutPanelLayout = new javax.swing.GroupLayout(aboutPanel);
        aboutPanel.setLayout(aboutPanelLayout);
        aboutPanelLayout.setHorizontalGroup(
            aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(aboutPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 743, Short.MAX_VALUE)
                .addContainerGap())
        );
        aboutPanelLayout.setVerticalGroup(
            aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(aboutPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE)
                .addContainerGap())
        );

        centerTabbedPane.addTab("About", aboutPanel);

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

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

    private void discardLetterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_discardLetterButtonActionPerformed
        DefaultListModel model = (DefaultListModel) probabilitiesList.getModel();
        model.clear();
        drawingPanelRecognition.clearDrawingArea();
    }//GEN-LAST:event_discardLetterButtonActionPerformed

    private void clearLetterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearLetterButtonActionPerformed
        drawingPanelRecognition.clearDrawingArea();
        ((DefaultListModel) probabilitiesList.getModel()).clear();
        new File("letter.png").delete();
    }//GEN-LAST:event_clearLetterButtonActionPerformed

    private void jPanel3ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanel3ComponentResized
        drawingPanelRecognition.setPreferredSize(new Dimension(jPanel3.getWidth(), jPanel3.getHeight()));
}//GEN-LAST:event_jPanel3ComponentResized

    private void recognizeLetterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recognizeLetterButtonActionPerformed
        ((DefaultListModel) probabilitiesList.getModel()).clear();

        OcrPlugin ocrPlugin = (OcrPlugin)activeNeuralNetwork.getPlugin(OcrPlugin.OCR_PLUGIN_NAME);
        HashMap recognitionResult = ocrPlugin.recognizeCharacterProbabilities(drawingPanelRecognition.getDrawnLetter());

        String [] outputResult = formatOutput(recognitionResult.toString());
        DefaultListModel model = (DefaultListModel) probabilitiesList.getModel();

        for (int i = 0; i < outputResult.length; i++) {
                model.addElement(outputResult[i]);
        }

        probabilitiesList.setSelectedIndex(0);
        if (jCheckBox1.isSelected()) {
            String letter = model.getElementAt(0).toString().substring(0, 1);
            model.clear();
            jTextArea1.append(letter);
            drawingPanelRecognition.clearDrawingArea();
        }
    }//GEN-LAST:event_recognizeLetterButtonActionPerformed

    private void clearLetterTrainingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearLetterTrainingButtonActionPerformed
        drawingPanelTrening.clearDrawingArea();
    }//GEN-LAST:event_clearLetterTrainingButtonActionPerformed

    private void saveLetterTrainingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveLetterTrainingButtonActionPerformed

        createTrainingSetFolder();

        String letter = JOptionPane.showInputDialog("Enter the drawn letter:").toUpperCase();
        drawingPanelTrening.saveDrawnLetter(letter);
        drawingPanelTrening.clearDrawingArea();
        TreeManager.setLettersTreeModel(jTree1);
    }//GEN-LAST:event_saveLetterTrainingButtonActionPerformed

    private void acceptLetterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_acceptLetterButtonActionPerformed
        if (probabilitiesList.getSelectedIndex() > -1) {
            DefaultListModel model = (DefaultListModel) probabilitiesList.getModel();
            String letter = model.getElementAt(probabilitiesList.getSelectedIndex()).toString().substring(0, 1);
            model.clear();
            jTextArea1.append(letter);
            drawingPanelRecognition.clearDrawingArea();
        } else {
            //todo
        }
    }//GEN-LAST:event_acceptLetterButtonActionPerformed

    private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleButton1ActionPerformed
        if (evt.getActionCommand().equals("B")) {
            styles.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
            jToggleButton1.setText(" B");
        } else {
            styles.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
            jToggleButton1.setText("B");
        }
        font = font.deriveFont(styles);
        jTextArea1.setFont(font);
    }//GEN-LAST:event_jToggleButton1ActionPerformed

    private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleButton2ActionPerformed
        if (evt.getActionCommand().equals("I")) {
            styles.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
            jToggleButton2.setText(" I");
        } else {
            styles.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
            jToggleButton2.setText("I");
        }
        font = font.deriveFont(styles);
        jTextArea1.setFont(font);
    }//GEN-LAST:event_jToggleButton2ActionPerformed

    private void jToggleButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jToggleButton3ActionPerformed
        if (evt.getActionCommand().equals("U")) {
            styles.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
            jToggleButton3.setText(" U");
        } else {
            styles.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE);
            jToggleButton3.setText("U");
        }
        font = font.deriveFont(styles);
        jTextArea1.setFont(font);
    }//GEN-LAST:event_jToggleButton3ActionPerformed

    private void jSpinner1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jSpinner1KeyReleased
        jSpinner1.setValue(20);
    }//GEN-LAST:event_jSpinner1KeyReleased

    private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner1StateChanged
        int i = Integer.parseInt((String) jSpinner1.getValue());
        styles.put(TextAttribute.SIZE, i);
        font = font.deriveFont(styles);
        jTextArea1.setFont(font);
    }//GEN-LAST:event_jSpinner1StateChanged

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

    private void trainingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainingButtonActionPerformed
        HashMap<String, FractionRgbData> rgbDataMap = new HashMap<String, FractionRgbData>();
        String imageDir = "Letters/Training Set/";
        try {
            File labeledImagesDir = new File(imageDir);
            rgbDataMap.putAll(ImagesLoader.getFractionRgbDataForDirectory(labeledImagesDir,
                    new Dimension(DrawingPanel.FIXED_WIDTH, DrawingPanel.FIXED_HIGHT)));

            for (String imgName : rgbDataMap.keySet()) {
                StringTokenizer st = new StringTokenizer(imgName, "._");
                String imageLabel = st.nextToken();
                if (!imageLabels.contains(imageLabel)) {
                    imageLabels.add(imageLabel);
                }
            }
            Collections.sort(imageLabels);
        } catch (IOException ioe) {
            System.err.println("Unable to load images from labeled images dir: '" + imageDir + "'");
            System.err.println(ioe.toString());
        }
        
        activeTrainingSet = ImageRecognitionHelper.createBlackAndWhiteTrainingSet(imageLabels, rgbDataMap);
        activeTrainingSet.setLabel("NewLettersTrainingSet");
        ProjectManager.getInstance().updateTrainingSets(activeTrainingSet);
        
        int neurons=0;
        if (imageLabels.size()<12) neurons = 12;
            else neurons = imageLabels.size();

        hiddenLayerNeuronsTextField.setText(Integer.toString(neurons));

        nextButton.setEnabled(true);
    }//GEN-LAST:event_trainingButtonActionPerformed

    private void createNetworkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createNetworkButtonActionPerformed
        TransferFunctionType transferFunctionType = TransferFunctionType.valueOf(NeuralNetworkFunctionTypeComboBox.getSelectedItem().toString().toUpperCase());
        String name = neuralNetworkNameTextField.getText();
        String hiddenLayersStr = hiddenLayerNeuronsTextField.getText();

        Vector<Integer> hiddenLayersNeuronsCount;

        try {
            hiddenLayersNeuronsCount = VectorParser.parseInteger(hiddenLayersStr);
        } catch (Exception ex) {
            JOptionPane.showConfirmDialog(null,
                    "Invalid input! Hidden Layers Neuron Counts must be entered as space separated integers.",
                    "Error", JOptionPane.DEFAULT_OPTION);
            return;
        }

        // create neural network
        activeNeuralNetwork = OcrHelper.createNewNeuralNetwork(name, new Dimension(DrawingPanel.FIXED_WIDTH, DrawingPanel.FIXED_HIGHT), ColorMode.BLACK_AND_WHITE, imageLabels, hiddenLayersNeuronsCount, transferFunctionType);

        ProjectManager.getInstance().addNewNetworkToProject(activeNeuralNetwork);

        /*  activeNeuralNetwork.learnInNewThread(activeTrainingSet);
        activeNeuralNetwork.save(name + ".nnet");   */
        centerTabbedPane.setSelectedIndex(2);

        ((LabelsPlugin)activeNeuralNetwork.getPlugin(LabelsPlugin.LABELS_PLUGIN_NAME)).setLabel(activeNeuralNetwork, name + ".nnet");
//        recognition = new LetterRecognition(activeNeuralNetwork);

    }//GEN-LAST:event_createNetworkButtonActionPerformed

    /**
     * This method creates the folder that will conatin all of the letters
     * designated for the training set
     */
    public static void createTrainingSetFolder() {
        File f = new File("Letters");
        f.mkdir();
        File f1 = new File("Letters/Training Set");
        f1.mkdir();
    }
    

    private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
        centerTabbedPane.setSelectedIndex(1);
    }//GEN-LAST:event_nextButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox NeuralNetworkFunctionTypeComboBox;
    private javax.swing.JPanel aboutPanel;
    private javax.swing.JTextArea aboutTextArea;
    private javax.swing.JButton acceptLetterButton;
    private javax.swing.JPanel botomPanel;
    private javax.swing.JPanel bottomPanelII;
    private javax.swing.JTabbedPane centerTabbedPane;
    private javax.swing.JButton clearLetterButton;
    private javax.swing.JButton clearLetterTrainingButton;
    private javax.swing.JButton createNetworkButton;
    private javax.swing.JButton discardLetterButton;
    private org.neuroph.easyneurons.ocr.hwr.DrawingPanel drawingPanelRecognition;
    private org.neuroph.easyneurons.ocr.hwr.DrawingPanel drawingPanelTrening;
    private javax.swing.JTextField hiddenLayerNeuronsTextField;
    private javax.swing.JCheckBox jCheckBox1;
    private org.neuroph.easyneurons.ocr.hwr.JImagePanel jImagePanel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JSpinner jSpinner1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JToggleButton jToggleButton1;
    private javax.swing.JToggleButton jToggleButton2;
    private javax.swing.JToggleButton jToggleButton3;
    private javax.swing.JTree jTree1;
    private javax.swing.JPanel leftPanel;
    private javax.swing.JPanel networkPanel;
    private javax.swing.JTextField neuralNetworkNameTextField;
    private javax.swing.JButton nextButton;
    private javax.swing.JList probabilitiesList;
    private javax.swing.JPanel recognitionPanel;
    private javax.swing.JButton recognizeLetterButton;
    private javax.swing.JPanel rightBotomPanel;
    private javax.swing.JPanel rightPanel;
    private javax.swing.JButton saveLetterTrainingButton;
    private javax.swing.JPanel southPanel;
    private javax.swing.JButton trainingButton;
    private javax.swing.JPanel trainingPanel;
    private javax.swing.JPanel upperPanel;
    // End of variables declaration//GEN-END:variables
    //private LetterRecognition recognition;
    NeuralNetwork activeNeuralNetwork;
    private Map<TextAttribute, Object> styles = new Hashtable<TextAttribute, Object>();
    private Font font = new Font(Font.SERIF, Font.PLAIN, 20);
    TrainingSet activeTrainingSet;
    ArrayList<String> imageLabels = new ArrayList<String>();
}
