/*
 * TSPPanel.java
 *
 * Created on March 25, 2006, 9:31 PM
 */

package cz.pcland.tsp;
import cz.pcland.ga.PopulationType;
import cz.pcland.ga.crossover.*;
import cz.pcland.ga.fitness.Evaluator;
import cz.pcland.ga.fitness.TSPFitness;
import cz.pcland.gavisualization.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import cz.pcland.functions.lexan.*;
import cz.pcland.functions.nodes.*;
import cz.pcland.functions.syntax.*;
import cz.pcland.io.*;
import cz.pcland.ga.*;
/**
 *
 * @author  petr
 */
public class TSPPanel extends BaseProblemPanel {
    TSPInstance instance;
    /**
     * Creates new form TSPPanel
     */
    public TSPPanel(MainApplet3 ma) {
        super(ma);
        initComponents();
        setInstance(new TSPInstance());
    }
    
    public void setInstance(TSPInstance instance) {
        this.instance = instance;
        ((CitiesPanel)this.panelCities).setInstance(instance);
        
    }
    
    
    public void visualizeFitness() {
        this.pnlVisualization = panelVisualization;
        this.panelVisualization = new GAVisualizationFitness(10,10, "Fitness");
        this.pnlVisualization = panelVisualization;
        this.jTabbedPane1.setComponentAt(2, panelVisualization);
        //  panelVisualization.setGAConfig(this.GAConfig);
        panelVisualization.updateGraph(infoData);
    }
    
    public void visualizeRank() {
        this.panelVisualization = new GAVisualizationEvaluation(10,10, "Length of tour");
        this.pnlVisualization = panelVisualization;
        this.jTabbedPane1.setComponentAt(2, panelVisualization);
        panelVisualization.updateGraph(infoData);
    }
    
    
    /**
     * Returns list of available evaluators specific for selected problem.
     */
    public Evaluator[] getEvaluators() {
        Evaluator[] ret = {new TSPFitness()};
        return ret;
    }
    
    /**
     * Returns list of available crossover operators specific for selected problem.
     */
    public CrossoverOpearator[] getCrossoverOperators() {
        CrossoverOpearator[] ret = {new TSPPartiallyMapped(), new TSPOrderOne(), new OnePointTSPCrossover()};
        return ret;
    }
    
    /**
     * Button start or steps pressed. User must call start method to start GA.
     */
    public Object run(boolean steps) {
        if(instance.getCount() < 2) {
            JOptionPane.showMessageDialog(null, "Add at least two cities !");
            parent.btnSteps.setEnabled(true);
            parent.btnStart.setEnabled(true);
            parent.btnCancel.setEnabled(false);
            
            return "Not enought cities";
        }
        this.btnClear.setEnabled(false);
        this.btnRandom.setEnabled(false);
        this.btnLoad.setEnabled(false);
        this.btnSave.setEnabled(false);
        
        
        initWorker(((BaseVisualization)this.pnlVisualization), this.lstProgress, PopulationType.INTEGER, steps, instance);
        return start(1);
    }
    
    public void finish(){
        this.btnClear.setEnabled(true);
        this.btnRandom.setEnabled(true);
        this.btnLoad.setEnabled(true);
        this.btnSave.setEnabled(true);
    }
    
    /**
     * Called whenever new population is created. That coresponds to button start pressed.
     */
    public void onInitBegin() {
        this.setStrLen(instance.getCount());
    }
    
    public void onInitEnd() {
        
    }
    
    public void onDoWorkBegin() {
        
    }
    
    /**
     * Called whenever GA invoked. That coresponds to button start or step pressed.
     */
    public void onDoWorkRunBegin() {
        
    }
    
    /**
     * Called whenever GA ends.
     */
    public void onDoWorkEnd() {
        this.instance.setGaInfo(gi);
        this.panelCities.repaint();
    }
    
    public void onDoWorkStepsBegin() {
        
    }
    
    public void onProgress() {
        this.instance.setGaInfo(gi);
        this.panelCities.repaint();
    }
    
    
    
    
    public void updateInfoList(){
        Runnable doSetData = new Runnable() {
            public void run() {
                lstProgress.setListData(infoData);
            }
        };
        SwingUtilities.invokeLater(doSetData);
    }
    
    
    /** 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() {
        java.awt.GridBagConstraints gridBagConstraints;

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        lstProgress = new javax.swing.JList();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        panelCities = new CitiesPanel();
        btnRandom = new javax.swing.JButton();
        btnClear = new javax.swing.JButton();
        btnLoad = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        pnlVisualization = new GAVisualizationEvaluation(10,10, "Length of tour");

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

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

        jScrollPane2.setViewportView(lstProgress);

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

        jTabbedPane1.addTab("Progress", jPanel3);

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

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

        panelCities.setBackground(new java.awt.Color(255, 255, 255));
        jScrollPane1.setViewportView(panelCities);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel1.add(jScrollPane1, gridBagConstraints);

        btnRandom.setText("Random");
        btnRandom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRandomActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
        jPanel1.add(btnRandom, gridBagConstraints);

        btnClear.setText("Clear");
        btnClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnClearActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0);
        jPanel1.add(btnClear, gridBagConstraints);

        btnLoad.setText("Load");
        btnLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoadActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 7, 0, 6);
        jPanel1.add(btnLoad, gridBagConstraints);

        btnSave.setText("Save");
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 7);
        jPanel1.add(btnSave, gridBagConstraints);

        jTabbedPane1.addTab("Settings", jPanel1);

        pnlVisualization.setLayout(null);

        jTabbedPane1.addTab("Visualization", pnlVisualization);

        add(jTabbedPane1, java.awt.BorderLayout.CENTER);

    }// </editor-fold>//GEN-END:initComponents
    
    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
// TODO add your handling code here:
        MyOptionPane.save(instance.getString(), this, parent.jSplitPane1);
    }//GEN-LAST:event_btnSaveActionPerformed
    
    private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed
// TODO add your handling code here:
        TSPInstance tsm = new TSPInstance();
        MyOptionPane.load(tsm,this,parent.jSplitPane1);
        this.instance = tsm;
        ((CitiesPanel)this.panelCities).setInstance(instance);
        this.panelCities.repaint();
    }//GEN-LAST:event_btnLoadActionPerformed
    
    private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed
// TODO add your handling code here:
        this.instance.deleteAll();
        this.panelCities.repaint();
    }//GEN-LAST:event_btnClearActionPerformed
    
    private void btnRandomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRandomActionPerformed
// TODO add your handling code here:
        
        String s = (String)JOptionPane.showInputDialog("Number of new cities: ", new Integer(30));
        int count = 0;
        if(s!=null)
            try {
                count = Integer.parseInt(s);
                
                instance.deleteAll();
                instance.makeRandom(count, this.panelCities.getWidth() - 5, this.panelCities.getHeight() - 5);
                
                
                ((CitiesPanel)this.panelCities).setInstance(instance);
                panelCities.repaint();
                
            }catch(NumberFormatException e){
                JOptionPane.showMessageDialog(null,"Error occured: " + e.toString(), "Input error", JOptionPane.ERROR_MESSAGE);
            }
        
        
        
    }//GEN-LAST:event_btnRandomActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnClear;
    private javax.swing.JButton btnLoad;
    private javax.swing.JButton btnRandom;
    private javax.swing.JButton btnSave;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JList lstProgress;
    private javax.swing.JPanel panelCities;
    private javax.swing.JPanel pnlVisualization;
    // End of variables declaration//GEN-END:variables
    
}
