/*
 * SATPanel.java
 *
 * Created on March 8, 2006, 11:02 PM
 */

package cz.pcland.sat;

import cz.pcland.ga.GAConfiguration;
import cz.pcland.ga.PopulationType;
import cz.pcland.ga.crossover.CrossoverOpearator;
import cz.pcland.ga.crossover.SimpleCrossover;
import cz.pcland.ga.crossover.UniformCrossover;
import cz.pcland.ga.crossover.twoPointCrossover;
import cz.pcland.ga.fitness.Evaluator;
import cz.pcland.ga.fitness.SATFitness;
import cz.pcland.gavisualization.BaseProblemPanel;
import cz.pcland.gavisualization.*;
import cz.pcland.gavisualization.MainApplet3;
import cz.pcland.knapsack.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import cz.pcland.io.*;
/**
 *
 * @author  petr
 */
public class SATPanel extends BaseProblemPanel {
    
    public Vector SATInstances = new Vector();
    
    SATInstance instanceToSolve;
    public boolean noneSelected;
    
    SATListRender renderer = new SATListRender();
    
    SATInstancesRenderer SATRenderer = new SATInstancesRenderer();
    int selected[];
    
    
    /** Creates new form SATPanel */
    public SATPanel(MainApplet3 parent) {
        super(parent);
        initComponents();
        this.lstProgress.setCellRenderer(renderer);
        this.lstSATList.setCellRenderer(SATRenderer);
        
    }
    
    public void visualizeFitness() {
        this.panelVisualization = new GAVisualizationFitness(10,10, "Fitness");
        this.jTabbedPane1.setComponentAt(2, panelVisualization);
        this.pnlVisualization = panelVisualization;
       // panelVisualization.setGAConfig(this.GAConfig);
        panelVisualization.updateGraph(infoData);
    }
    
    public void visualizeRank() {
        this.panelVisualization = new GAVisualizationEvaluation(10,10, "Number of satisfied clauses");
        this.jTabbedPane1.setComponentAt(2, panelVisualization);
        this.pnlVisualization = panelVisualization;
     //   panelVisualization.setGAConfig(this.GAConfig);
        panelVisualization.updateGraph(infoData);
    }
    
    /**
     * Returns list of available evaluators specific for selected problem.
     */
    public Evaluator[] getEvaluators() {
        Evaluator[] ret = {new SATFitness()};
        return ret;
    }
    
    /**
     * Returns list of available crossover operators specific for selected problem.
     */
    public CrossoverOpearator[] getCrossoverOperators() {
        CrossoverOpearator[] ret = {new SimpleCrossover(), new twoPointCrossover(), new UniformCrossover()};
        return ret;
    }
    
    /**
     * Button start or steps pressed. User must call start method to start GA.
     */
    public Object run(boolean reset) {
        selected = this.lstSATList.getSelectedIndices();
        
        
        
        if(this.SATInstances.size() == 0) {
            JOptionPane.showMessageDialog(null, "You must add at least one instance to be solved !");
            parent.btnSteps.setEnabled(true);
            parent.btnStart.setEnabled(true);
            parent.btnCancel.setEnabled(false);
            return "Nothing done";
        }
        
        initWorker(((BaseVisualization)this.pnlVisualization), this.lstProgress, PopulationType.BINARY, reset, null);
        
        
        if(selected.length == 0) {
            noneSelected = true;
            start(this.SATInstances.size());
        }else{
            noneSelected = false;
            start(selected.length);
        }

        this.lstSATList.setSelectedIndices(selected);
        return "All instances checked ...";
        
    }
    
    public void finish(){}
    
    /**
     * Called whenever new population is created. That coresponds to button start pressed.
     */
    public void onInitBegin() {
        this.setStrLen(instanceToSolve.varsCount);
    }
    
    public void onInitEnd() {
        
    }
    
    public void onDoWorkBegin() {
        
        if(!noneSelected) {
            instanceToSolve = ((SATInstance)SATInstances.get(selected[this.getCurrentIteration()]));
        } else {
            instanceToSolve = ((SATInstance)SATInstances.get(this.getCurrentIteration()));
        }
        
        //System.out.println("instance " + reset);
        
        ((SATFitness)GAConfiguration.firnessObj).setSATInstance(instanceToSolve);
        renderer.setInstance(instanceToSolve);
    }
    
    /**
     * Called whenever GA invoked. That coresponds to button start or step pressed.
     */
    public void onDoWorkRunBegin() {
        instanceToSolve.checked = false;
    }
    
    public void onDoWorkStepsBegin() {
        this.infoData = instanceToSolve.infoData;
        this.population = instanceToSolve.population;
    }
    
    
    public void setSelected(int[] sel) {
       lstSATList.setSelectedIndices(sel); 
    }
    
    /**
     * Called whenever GA ends.
     */
    public void onDoWorkEnd() {
        if(population.isEnd()) { //tests best individual from last generation for current instanceToSolve
            instanceToSolve.canSatisfy = true;
        }else {
            instanceToSolve.canSatisfy = false;
        }
        
        instanceToSolve.infoData = infoData; //stores info data to this instance.
        instanceToSolve.population = this.population;
        instanceToSolve.checked = true;
        
        this.setSelected(this.selected);
        
        updateSATList();
        
    }
    
    public void onProgress() {
        
    }
    
    public void updateInfoList() {
        Runnable doSetData = new Runnable() {
            public void run() {
                lstProgress.setListData(infoData);
            }
        };
        SwingUtilities.invokeLater(doSetData);
    }
    
    public void updateSATList() {
        Runnable doSetData = new Runnable() {
            public void run() {
                lstSATList.setListData(SATInstances);
            }
        };
        SwingUtilities.invokeLater(doSetData);
    }
    
    
    
   /* public void cancel(){
    
    }*/
    
    /** 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();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        lstProgress = new javax.swing.JList();
        jPanel2 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        lstSATList = new javax.swing.JList();
        jButton3 = new javax.swing.JButton();
        inputVarsCount = new javax.swing.JTextField();
        inputClasesCount = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        pnlVisualization = new GAVisualizationEvaluation(15,15, "Number of satisfied clauses");

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

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

        jScrollPane2.setViewportView(lstProgress);

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

        jTabbedPane1.addTab("SAT progress", jPanel1);

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

        jButton1.setText("Load from file");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
        jPanel2.add(jButton1, gridBagConstraints);

        jButton2.setText("Generate random");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(11, 10, 0, 0);
        jPanel2.add(jButton2, gridBagConstraints);

        lstSATList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                lstSATListValueChanged(evt);
            }
        });
        lstSATList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                lstSATListMouseClicked(evt);
            }
        });
        lstSATList.addAncestorListener(new javax.swing.event.AncestorListener() {
            public void ancestorMoved(javax.swing.event.AncestorEvent evt) {
            }
            public void ancestorAdded(javax.swing.event.AncestorEvent evt) {
                lstSATListAncestorAdded(evt);
            }
            public void ancestorRemoved(javax.swing.event.AncestorEvent evt) {
            }
        });

        jScrollPane1.setViewportView(lstSATList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 7;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridheight = 9;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 418;
        gridBagConstraints.ipady = 398;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 9, 0, 0);
        jPanel2.add(jScrollPane1, gridBagConstraints);

        jButton3.setText("Remove selected");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 6;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(45, 10, 0, 0);
        jPanel2.add(jButton3, gridBagConstraints);

        inputVarsCount.setText("20");
        inputVarsCount.setMinimumSize(new java.awt.Dimension(40, 19));
        inputVarsCount.setPreferredSize(new java.awt.Dimension(40, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
        jPanel2.add(inputVarsCount, gridBagConstraints);

        inputClasesCount.setText("90");
        inputClasesCount.setMinimumSize(new java.awt.Dimension(40, 19));
        inputClasesCount.setPreferredSize(new java.awt.Dimension(40, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
        jPanel2.add(inputClasesCount, gridBagConstraints);

        jLabel1.setText("Clauses count:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
        jPanel2.add(jLabel1, gridBagConstraints);

        jLabel2.setText("Variables count:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(11, 10, 0, 0);
        jPanel2.add(jLabel2, gridBagConstraints);

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

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 10, 0, 0);
        jPanel2.add(jButton4, gridBagConstraints);

        jButton5.setText("Save to file");
        jButton5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton5ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(8, 9, 0, 0);
        jPanel2.add(jButton5, gridBagConstraints);

        jTabbedPane1.addTab("SAT instances", jPanel2);

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

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

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

        jTabbedPane1.addTab("Visualization", jPanel3);

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

    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
// TODO add your handling code here:
        SATInstance instance = new SATInstance();
        MyOptionPane.load(instance, this, parent.jSplitPane1);
        SATInstances.add(instance);
        updateSATList();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
// TODO add your handling code here:
        if(this.lstSATList.getSelectedIndex() != -1)
        MyOptionPane.save(((SATInstance)this.SATInstances.get(this.lstSATList.getSelectedIndex())).getString(), this, parent.jSplitPane1);
    }//GEN-LAST:event_jButton5ActionPerformed
    
    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
// TODO add your handling code here:
        
        int selected[] = this.lstSATList.getSelectedIndices();
        SATInstance si = (SATInstance)this.SATInstances.get(selected[0]);
        if(si != null){
            //JOptionPane.showMessageDialog(null, "dgfdsgdf");
            renderer.setInstance(si);
            this.infoData = si.infoData;
            this.updateInfoList();
            ((GAVisualizationEvaluation)this.panelVisualization).updateGraph(infoData);
        }
        
    }//GEN-LAST:event_jButton4ActionPerformed
    
    private void lstSATListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lstSATListMouseClicked
// TODO add your handling code here:
        JList lst = (JList)evt.getSource();
        
    }//GEN-LAST:event_lstSATListMouseClicked
    
    private void lstSATListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_lstSATListValueChanged
// TODO add your handling code here:
        
    }//GEN-LAST:event_lstSATListValueChanged
    
    private void lstSATListAncestorAdded(javax.swing.event.AncestorEvent evt) {//GEN-FIRST:event_lstSATListAncestorAdded
// TODO add your handling code here:
    }//GEN-LAST:event_lstSATListAncestorAdded
    
    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
// TODO add your handling code here:
        int[] selected = this.lstSATList.getSelectedIndices();
        if(selected.length > 0){
            for(int i=selected.length-1;i>=0;i--){
                this.SATInstances.remove(selected[i]);
            }
            updateSATList();
        }
    }//GEN-LAST:event_jButton3ActionPerformed
    
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
// TODO add your handling code here:
        try {
            SATGen satGen = new SATGen();
            int varsCount = Integer.parseInt(this.inputVarsCount.getText());
            int clausesCount = Integer.parseInt(this.inputClasesCount.getText());
            System.out.println("generating " + varsCount + ", " + clausesCount);
            SATInstances.add(satGen.generate(varsCount,clausesCount));
            System.out.println("generated");
            updateSATList();
            System.out.println("updated");
        }catch(NumberFormatException e) {
            System.out.println("Bad number format !!! " + e.getMessage());
        }
        
    }//GEN-LAST:event_jButton2ActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField inputClasesCount;
    private javax.swing.JTextField inputVarsCount;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    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.JList lstSATList;
    private javax.swing.JPanel pnlVisualization;
    // End of variables declaration//GEN-END:variables
    
}
