/*
 * NeuralNetworkViewFrame.java
 *
 * Created on October 4, 2008, 12:58 PM
 */

package org.neuroph.easyneurons;

import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.JPanel;

import org.jdesktop.application.Action;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.learning.TrainingSet;
import org.neuroph.easyneurons.dialog.BackpropagationTrainingDialog;
import org.neuroph.easyneurons.dialog.HebbianTrainingDialog;
import org.neuroph.easyneurons.dialog.SetNetworkInputDialog;
import org.neuroph.easyneurons.dialog.SupervisedTrainingDialog;
import org.neuroph.easyneurons.view.JNeuralNetwork;
import org.neuroph.nnet.learning.DynamicBackPropagation;
import org.neuroph.util.NeuralNetworkType;

/**
 * 
 * @author Zoran Sevarac <sevarac@gmail.com>
 */
public class NeuralNetworkViewFrame extends javax.swing.JInternalFrame
		implements Observer {
	private static final long serialVersionUID = 1L;
	
	private NeuralNetwork neuralNetwork;
	private Vector<TrainingSet> trainingSets;
	private JNeuralNetwork blockView = new JNeuralNetwork();
	private NeuralGraphRenderer neuralGraphRenderer;
	private JPanel graphView;
	private NeuralNetworkTraining trainingController;
	private boolean graphViewActive = false;
        private String filePath;
        private EasyNeuronsApplicationView mainFrame;

	public static final int BLOCK_VIEW = 1;
	public static final int GRAPH_VIEW = 2;

	/** Creates new form NeuralNetworkViewFrame */
	public NeuralNetworkViewFrame(NeuralNetwork neuralNetwork, Vector<TrainingSet> trainingSets) {
		this.neuralNetwork = neuralNetwork;
		this.trainingSets = trainingSets;
                this.mainFrame = EasyNeuronsApplicationView.getInstance();
		this.trainingController = new NeuralNetworkTraining(this.neuralNetwork);
		neuralNetwork.addObserver(this);

		initComponents();
                
                blockView.setNetwork(neuralNetwork);
		this.scrollPanel.getViewport().add(blockView);


		this.setTitle(neuralNetwork.toString());

		Iterator<TrainingSet> iterator = trainingSets.iterator();
		while (iterator.hasNext()) {
			TrainingSet ts = iterator.next();
			this.trainingSetsComboBox.addItem(ts);
		}

	}

	/**
	 * 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() {

                scrollPanel = new javax.swing.JScrollPane();
                buttonPanel = new javax.swing.JPanel();
                jLabel1 = new javax.swing.JLabel();
                trainingSetsComboBox = new javax.swing.JComboBox();
                trainButton = new javax.swing.JButton();
                setInputButton = new javax.swing.JButton();
                calculateButton = new javax.swing.JButton();
                randomizeButton = new javax.swing.JButton();
                resetButton = new javax.swing.JButton();

                setClosable(true);
                setIconifiable(true);
                setMaximizable(true);
                org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(org.neuroph.easyneurons.EasyNeuronsApplication.class).getContext().getResourceMap(NeuralNetworkViewFrame.class);
                setTitle(resourceMap.getString("Form.title")); // NOI18N
                setAutoscrolls(true);
                setDoubleBuffered(true);
                setMaximumSize(null);
                setName("Form"); // NOI18N
                setNormalBounds(null);

                scrollPanel.setName("scrollPanel"); // NOI18N
                scrollPanel.setPreferredSize(new java.awt.Dimension(700, 600));
                getContentPane().add(scrollPanel, java.awt.BorderLayout.CENTER);

                buttonPanel.setName("buttonPanel"); // NOI18N
                buttonPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

                jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
                jLabel1.setName("jLabel1"); // NOI18N
                buttonPanel.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 4, 70, -1));

                trainingSetsComboBox.setName("trainingSetsComboBox"); // NOI18N
                trainingSetsComboBox.addFocusListener(new java.awt.event.FocusAdapter() {
                        public void focusGained(java.awt.event.FocusEvent evt) {
                                trainingSetsComboBoxFocusGained(evt);
                        }
                });
                buttonPanel.add(trainingSetsComboBox, new org.netbeans.lib.awtextra.AbsoluteConstraints(70, 0, 140, 23));

                javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(org.neuroph.easyneurons.EasyNeuronsApplication.class).getContext().getActionMap(NeuralNetworkViewFrame.class, this);
                trainButton.setAction(actionMap.get("train")); // NOI18N
                trainButton.setFont(resourceMap.getFont("trainButton.font")); // NOI18N
                trainButton.setText(resourceMap.getString("trainButton.text")); // NOI18N
                trainButton.setName("trainButton"); // NOI18N
                buttonPanel.add(trainButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(210, 0, -1, -1));

                setInputButton.setAction(actionMap.get("setInput")); // NOI18N
                setInputButton.setFont(resourceMap.getFont("setInputButton.font")); // NOI18N
                setInputButton.setName("setInputButton"); // NOI18N
                buttonPanel.add(setInputButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 0, 100, -1));

                calculateButton.setAction(actionMap.get("calculate")); // NOI18N
                calculateButton.setFont(resourceMap.getFont("calculateButton.font")); // NOI18N
                calculateButton.setText(resourceMap.getString("calculateButton.text")); // NOI18N
                calculateButton.setName("calculateButton"); // NOI18N
                buttonPanel.add(calculateButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(380, 0, -1, -1));

                randomizeButton.setAction(actionMap.get("randomize")); // NOI18N
                randomizeButton.setFont(resourceMap.getFont("randomizeButton.font")); // NOI18N
                randomizeButton.setText(resourceMap.getString("randomizeButton.text")); // NOI18N
                randomizeButton.setName("randomizeButton"); // NOI18N
                buttonPanel.add(randomizeButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(530, 0, -1, -1));

                resetButton.setAction(actionMap.get("reset")); // NOI18N
                resetButton.setFont(resourceMap.getFont("resetButton.font")); // NOI18N
                resetButton.setName("resetButton"); // NOI18N
                buttonPanel.add(resetButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(470, 0, -1, -1));

                getContentPane().add(buttonPanel, java.awt.BorderLayout.NORTH);

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

	private void trainingSetsComboBoxFocusGained(java.awt.event.FocusEvent evt) {// GEN-FIRST:event_trainingSetsComboBoxFocusGained
		this.trainingSetsComboBox.removeAllItems();
		Iterator<TrainingSet> iterator = trainingSets.iterator();
		while (iterator.hasNext()) {
			TrainingSet ts = iterator.next();
			this.trainingSetsComboBox.addItem(ts);
		}
	}// GEN-LAST:event_trainingSetsComboBoxFocusGained

	@Action
	public void train() {
		TrainingSet trainingSet = (TrainingSet) trainingSetsComboBox
				.getSelectedItem();
		trainingController.setTrainingSet(trainingSet);

		NeuralNetworkType nnetType = neuralNetwork.getNetworkType(); // kod tipa
																	// mreze

		switch (nnetType) {
		case ADALINE:
			showLmsTrainingDialog();
			break;
		case PERCEPTRON:
			showLmsTrainingDialog(); /* perceptronTraining(); */
			break;
		case MULTI_LAYER_PERCEPTRON:
			showMLPTrainingDialog();
			break;
		case RBF_NETWORK:
			showLmsTrainingDialog(); /* showRbfTrainingDialog */
			break;
		case HOPFIELD:
			trainingController.train();
			break;
		case KOHONEN: /* KohonenTrainDlg(); */
			break;
		case NEURO_FUZZY_REASONER:
			showLmsTrainingDialog();
			break;
		case SUPERVISED_HEBBIAN_NET:
			showHebbianTrainingDialog();
			break;

		default:
			trainingController.train();
			break;
		} // switch*/

	}

	private void showLmsTrainingDialog() {     
		SupervisedTrainingDialog trainingDialog = new SupervisedTrainingDialog(null, mainFrame, true,
				this.trainingController);
		trainingDialog.setLocationRelativeTo(this);
		trainingDialog.setVisible(true);
	}

	private void showMLPTrainingDialog() {
                if (trainingController.getNetwork().getLearningRule() instanceof DynamicBackPropagation) {
                    BackpropagationTrainingDialog trainingDialog = new BackpropagationTrainingDialog(null, mainFrame, true,
                                    this.trainingController);
                    trainingDialog.setLocationRelativeTo(this);
                    trainingDialog.setVisible(true);
                } else {
                    showLmsTrainingDialog();
                }
	}

	private void showHebbianTrainingDialog() {
		HebbianTrainingDialog trainingDialog = new HebbianTrainingDialog(null,
				true, mainFrame, this.trainingController);
		trainingDialog.setLocationRelativeTo(this);
		trainingDialog.setVisible(true);
	}

	@Action
	public void calculateNetwork() {
		this.neuralNetwork.calculate();
	}

	@Action
	public void setInput() {
		SetNetworkInputDialog dialog = new SetNetworkInputDialog(null, true,
				this.trainingController);
		dialog.setLocationRelativeTo(this);
		dialog.setVisible(true);
	}

	@Action
	public void calculate() {
		trainingController.calculate();
	}

	public NeuralNetworkTraining getController() {
		return this.trainingController;
	}

	@Action
	public void randomize() {
		trainingController.randomize();
	}

	@Action
	public void reset() {
		trainingController.reset();
	}

	public void switchToView(int view) {
		if (view == GRAPH_VIEW) {
		// za rekurzivne modele baca exception
                        this.scrollPanel.getViewport().remove(blockView);
                        blockView = null;
                        try {
                                neuralGraphRenderer = new NeuralGraphRenderer(this.neuralNetwork);
                                graphView = neuralGraphRenderer.getGraphPanel();
                        } catch (Exception ex) {
                        }

			this.getContentPane().remove(scrollPanel);
			this.getContentPane().add(graphView);
			graphViewActive = true;
		
		} else if (view == BLOCK_VIEW) {
                        neuralGraphRenderer = null;
			this.getContentPane().remove(graphView);

                        blockView = new JNeuralNetwork();
                        blockView.setNetwork(neuralNetwork);
                        this.scrollPanel.getViewport().add(blockView);

			this.getContentPane().add(scrollPanel);
			graphViewActive = false;
			
		}
		refresh();
		this.repaint();
	}

        @Override
	public void update(Observable o, Object arg) {
		if (graphViewActive) {
			graphView = neuralGraphRenderer.getGraphPanel();
			graphView.revalidate();
			graphView.repaint();
		} else {
			blockView.update();
		}
	}

	public void refresh() {

		if (graphViewActive) {
			this.getContentPane().remove(graphView);
			graphView = null;
			graphView = neuralGraphRenderer.getGraphPanel();
			this.getContentPane().add(graphView);
			graphView.revalidate();
			graphView.repaint();
		} else {
			blockView.update();
		}

	}

	public void updateTitle() {
		this.setTitle(neuralNetwork.toString());
	}
	
	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

	public NeuralNetwork getNeuralNetwork() {
		return neuralNetwork;
	}
        
        
        
        

        // Variables declaration - do not modify//GEN-BEGIN:variables
        private javax.swing.JPanel buttonPanel;
        private javax.swing.JButton calculateButton;
        private javax.swing.JLabel jLabel1;
        private javax.swing.JButton randomizeButton;
        private javax.swing.JButton resetButton;
        private javax.swing.JScrollPane scrollPanel;
        private javax.swing.JButton setInputButton;
        private javax.swing.JButton trainButton;
        private javax.swing.JComboBox trainingSetsComboBox;
        // End of variables declaration//GEN-END:variables

}
