/*
 * LmsTrainingMonitor.java
 *
 * Created on December 24, 2008, 2:58 AM
 */

package org.neuroph.easyneurons.dialog;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.swing.SwingUtilities;

import org.jdesktop.application.Action;
import org.neuroph.easyneurons.TrainingController;
import org.neuroph.nnet.learning.LMS;




/**
 * 
 * @author Zoran Sevarac <sevarac@gmail.com>
 */
public class SupervisedTrainingMonitor extends javax.swing.JDialog implements Observer, Runnable {
	private static final long serialVersionUID = 1L;
	
	TrainingController controller;
        private ConcurrentLinkedQueue<LearningInfo> dataQueue = new ConcurrentLinkedQueue<LearningInfo>();
        boolean doneTraining = false;



	/** Creates new form LmsTrainingMonitor */
	public SupervisedTrainingMonitor(java.awt.Frame parent, boolean modal) {
		super(parent, modal);
		initComponents();
	}

	public SupervisedTrainingMonitor(java.awt.Frame parent, boolean modal,
			TrainingController controller) {
		super(parent, modal);
		initComponents();

		this.controller = controller;

	}

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

        fieldPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        totalNetErrorField = new javax.swing.JTextField();
        currentIterationField = new javax.swing.JTextField();
        buttonPanel = new javax.swing.JPanel();
        stopButton = new javax.swing.JButton();
        helpButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(org.neuroph.easyneurons.EasyNeuronsApplication.class).getContext().getResourceMap(SupervisedTrainingMonitor.class);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        getContentPane().setLayout(new java.awt.GridBagLayout());

        fieldPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        fieldPanel.setName("fieldPanel"); // NOI18N
        fieldPanel.setLayout(new java.awt.GridBagLayout());

        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 5, 5);
        fieldPanel.add(jLabel1, gridBagConstraints);

        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 10, 10, 5);
        fieldPanel.add(jLabel2, gridBagConstraints);

        totalNetErrorField.setColumns(18);
        totalNetErrorField.setText(resourceMap.getString("totalNetErrorField.text")); // NOI18N
        totalNetErrorField.setName("totalNetErrorField"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(10, 5, 5, 10);
        fieldPanel.add(totalNetErrorField, gridBagConstraints);

        currentIterationField.setColumns(10);
        currentIterationField.setText(resourceMap.getString("currentIterationField.text")); // NOI18N
        currentIterationField.setName("currentIterationField"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 10);
        fieldPanel.add(currentIterationField, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 3, 5);
        getContentPane().add(fieldPanel, gridBagConstraints);

        buttonPanel.setName("buttonPanel"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(org.neuroph.easyneurons.EasyNeuronsApplication.class).getContext().getActionMap(SupervisedTrainingMonitor.class, this);
        stopButton.setAction(actionMap.get("stop")); // NOI18N
        stopButton.setText(resourceMap.getString("stopButton.text")); // NOI18N
        stopButton.setName("stopButton"); // NOI18N
        buttonPanel.add(stopButton);

        helpButton.setText(resourceMap.getString("helpButton.text")); // NOI18N
        helpButton.setEnabled(false);
        helpButton.setName("helpButton"); // NOI18N
        buttonPanel.add(helpButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(buttonPanel, gridBagConstraints);

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

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				SupervisedTrainingMonitor dialog = new SupervisedTrainingMonitor(
						new javax.swing.JFrame(), true);
				dialog.addWindowListener(new java.awt.event.WindowAdapter() {
					public void windowClosing(java.awt.event.WindowEvent e) {
						System.exit(0);
					}
				});
				dialog.setVisible(true);
			}
		});
	}

        public TrainingController getTrainingController() {
            return this.controller;
        }

        // update with data from learning rule
	public void update(Observable o, Object arg) {
		LMS learningRule = (LMS) o;
                dataQueue.add(new LearningInfo( learningRule.getCurrentIteration(),
                                                learningRule.getTotalNetworkError()));
                SwingUtilities.invokeLater(this);
	}


        public void run() {
            //Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

                if (!dataQueue.isEmpty()) {
                    LearningInfo learningInfo = dataQueue.poll();
                    this.currentIterationField.setText(learningInfo.getIteration().toString());
                    this.totalNetErrorField.setText(learningInfo.getError().toString());
                }
        }

	@Action
	public void stop() {

		this.controller.stopTraining();
                doneTraining = true;
		this.dispose();
	}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JTextField currentIterationField;
    private javax.swing.JPanel fieldPanel;
    private javax.swing.JButton helpButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JButton stopButton;
    private javax.swing.JTextField totalNetErrorField;
    // End of variables declaration//GEN-END:variables

        private class LearningInfo {
            Integer iteration;
            Double error;


            public LearningInfo(Integer iteration, Double error) {
                this.iteration = iteration;
                this.error = error;
            }

            public Double getError() {
                return error;
            }

            public Integer getIteration() {
                return iteration;
            }


        }

}

