/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gui;

import compose.GeneticComposer;
import compose.MarkovComposer;
import data.INote;
import data.IPhrase;
import data.IScore;
import data.InstrumentStatics;
import database.DatabaseInterface;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jm.util.Write;
import midi.MIDIPlayer;

/**
 *
 * @author smuRf
 */
public class ComposingDialog extends javax.swing.JDialog implements ChangeListener{
    private static final int MARKOV = 0;
    private static final int GENETIC = 1;
    private AnalyserForm parent;
    private ArrayList<IPhrase> composeInput = new ArrayList();
    private IScore result;
    private GeneticComposer gc = null;
    private MarkovComposer mc = null;
    
    /**
     * Creates new form ComposingDialog
     */
    public ComposingDialog(java.awt.Frame parent, boolean modal, HashMap composeMotifs) {
        super(parent, modal);
        initComponents();
        
        cbInitPopMotifs.setVisible(false);
        lblHoldProp.setVisible(false);
        spHoldProp.setVisible(false);
        lblShortestRhythm.setVisible(false);
        cbShortestRhythm.setVisible(false);
        
        this.parent = (AnalyserForm)parent;
        
        Rectangle parentBounds = this.parent.getBounds();
        this.setBounds((int)(parentBounds.getWidth()/2-getBounds().getWidth()/2) + (int)parentBounds.getX(), 
                       (int)(parentBounds.getHeight()/2-getBounds().getHeight()/2) + (int)parentBounds.getY(), 
                       (int)getBounds().getWidth(), (int)getBounds().getHeight());
        
        slDepth.addChangeListener(this);
        slNoteCount.addChangeListener(this);

        lblDepthValue.setText("" + slDepth.getValue());
        lblNoteCountValue.setText("" + slNoteCount.getValue());
        
        spTempo.setValue(130);
        
        for(String instrument:InstrumentStatics.instruments.keySet())
            cbInstrumentSubject.insertItemAt(instrument, 0);
        cbInstrumentSubject.setSelectedItem("PIANO");
        
        for(String instrument:InstrumentStatics.instruments.keySet())
            cbInstrumentCounter.insertItemAt(instrument, 0);
        cbInstrumentCounter.setSelectedItem("PIANO");
        
        for(String instrument:InstrumentStatics.instruments.keySet())
            cbInstrumentAnswer.insertItemAt(instrument, 0);
        cbInstrumentAnswer.setSelectedItem("PIANO");
        
        for(String instrument:InstrumentStatics.drums.keySet())
            cbInstrumentDrum.insertItemAt(instrument, 0);
        cbInstrumentDrum.setSelectedItem("BASS_DRUM_1");
        
        toolbar.setVisible(false);
        
        createComposingInput(composeMotifs);
    }
    
    private void createComposingInput(HashMap<Integer, Boolean> composeMotifs)
    {
        DatabaseInterface databaseInterface = new DatabaseInterface(this.parent.DB_USER, this.parent.DB_PASSWORD, this.parent.DB_URL);
        if(composeMotifs == null)
        {
            ArrayList<Integer> motifIds = databaseInterface.getMotifsIds(null);
            composeMotifs = new HashMap();
            for(int id:motifIds)
                composeMotifs.put(id, true);
        }
        
        for(int id:composeMotifs.keySet())
        {
            if(composeMotifs.get(id))
            {
                ArrayList<INote> motifNotes = databaseInterface.getMotifDetails(id);
                IPhrase iPhrase = new IPhrase("newPhrase", 0);

                for(INote iNote:motifNotes)
                    iPhrase.addINote(iNote);

                composeInput.add(iPhrase);
            }
        }
        databaseInterface.closeConnection();
    }

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

        composerSelector = new javax.swing.JTabbedPane();
        pnlMarkov = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        pnlNoteCount = new javax.swing.JPanel();
        lblNoteCount = new javax.swing.JLabel();
        slNoteCount = new javax.swing.JSlider();
        lblNoteCountValue = new javax.swing.JLabel();
        pnlDepth = new javax.swing.JPanel();
        lblDepth = new javax.swing.JLabel();
        slDepth = new javax.swing.JSlider();
        lblDepthValue = new javax.swing.JLabel();
        pnlParams = new javax.swing.JPanel();
        pnlParamTitle = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        pnlParamBoxes = new javax.swing.JPanel();
        cbPitch = new javax.swing.JCheckBox();
        cbRhythmvalue = new javax.swing.JCheckBox();
        cbDynamics = new javax.swing.JCheckBox();
        pnlGenetic = new javax.swing.JPanel();
        lblNrBars = new javax.swing.JLabel();
        spNrBars = new javax.swing.JSpinner();
        lblPop = new javax.swing.JLabel();
        spPop = new javax.swing.JSpinner();
        lblPitchRange = new javax.swing.JLabel();
        spPitchRange = new javax.swing.JSpinner();
        lblLowestNote = new javax.swing.JLabel();
        cbLowestNote = new javax.swing.JComboBox();
        lblOctave = new javax.swing.JLabel();
        cbOctave = new javax.swing.JComboBox();
        lblShortestRhythm = new javax.swing.JLabel();
        cbShortestRhythm = new javax.swing.JComboBox();
        lblHoldProp = new javax.swing.JLabel();
        spHoldProp = new javax.swing.JSpinner();
        lblTourSize = new javax.swing.JLabel();
        spTourSize = new javax.swing.JSpinner();
        lblMutationProp = new javax.swing.JLabel();
        spMutationProp = new javax.swing.JSpinner();
        lblIterations = new javax.swing.JLabel();
        spIterations = new javax.swing.JSpinner();
        cbInitPopMotifs = new javax.swing.JCheckBox();
        cbMixInMotifs = new javax.swing.JCheckBox();
        lblMixProp = new javax.swing.JLabel();
        spMixProp = new javax.swing.JSpinner();
        jLabel2 = new javax.swing.JLabel();
        pnlControl = new javax.swing.JPanel();
        pnlScoreProperties = new javax.swing.JPanel();
        pnlTempo = new javax.swing.JPanel();
        lblTempo = new javax.swing.JLabel();
        spTempo = new javax.swing.JSpinner();
        pnlInstruments = new javax.swing.JPanel();
        cbInstrumentSubject = new javax.swing.JComboBox();
        lblSubject = new javax.swing.JLabel();
        cbInstrumentCounter = new javax.swing.JComboBox();
        lblCounter = new javax.swing.JLabel();
        cbCounterPhrase = new javax.swing.JCheckBox();
        cbInstrumentAnswer = new javax.swing.JComboBox();
        lblAnswer = new javax.swing.JLabel();
        cbAnswerPhrase = new javax.swing.JCheckBox();
        cbInstrumentDrum = new javax.swing.JComboBox();
        lblDrum = new javax.swing.JLabel();
        cbDrum = new javax.swing.JCheckBox();
        pnlButton = new javax.swing.JPanel();
        btnCompose = new javax.swing.JButton();
        toolbar = new javax.swing.JToolBar();
        btnPlay = new javax.swing.JButton();
        btnStop = new javax.swing.JButton();
        pnlControlButton = new javax.swing.JPanel();
        btnSave = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Composer");
        setIconImage(null);
        setResizable(false);

        composerSelector.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                composerSelectorStateChanged(evt);
            }
        });

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

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

        pnlNoteCount.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        lblNoteCount.setText("#notes");
        lblNoteCount.setPreferredSize(new java.awt.Dimension(90, 60));
        pnlNoteCount.add(lblNoteCount);

        slNoteCount.setMaximum(200);
        slNoteCount.setMinimum(10);
        slNoteCount.setValue(25);
        slNoteCount.setPreferredSize(new java.awt.Dimension(450, 23));
        pnlNoteCount.add(slNoteCount);
        pnlNoteCount.add(lblNoteCountValue);

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

        pnlDepth.setPreferredSize(new java.awt.Dimension(628, 50));
        pnlDepth.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        lblDepth.setText("depth");
        lblDepth.setPreferredSize(new java.awt.Dimension(90, 60));
        pnlDepth.add(lblDepth);

        slDepth.setMaximum(5);
        slDepth.setMinimum(1);
        slDepth.setValue(2);
        slDepth.setPreferredSize(new java.awt.Dimension(450, 23));
        pnlDepth.add(slDepth);
        pnlDepth.add(lblDepthValue);

        jPanel1.add(pnlDepth, java.awt.BorderLayout.PAGE_START);

        pnlMarkov.add(jPanel1, java.awt.BorderLayout.PAGE_START);

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

        pnlParamTitle.setPreferredSize(new java.awt.Dimension(95, 191));
        pnlParamTitle.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        jLabel1.setText("consider");
        jLabel1.setPreferredSize(new java.awt.Dimension(90, 14));
        pnlParamTitle.add(jLabel1);

        pnlParams.add(pnlParamTitle, java.awt.BorderLayout.WEST);

        pnlParamBoxes.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        cbPitch.setSelected(true);
        cbPitch.setText("pitch");
        pnlParamBoxes.add(cbPitch);

        cbRhythmvalue.setSelected(true);
        cbRhythmvalue.setText("rhythmvalue");
        pnlParamBoxes.add(cbRhythmvalue);

        cbDynamics.setSelected(true);
        cbDynamics.setText("dynamics");
        pnlParamBoxes.add(cbDynamics);

        pnlParams.add(pnlParamBoxes, java.awt.BorderLayout.CENTER);

        pnlMarkov.add(pnlParams, java.awt.BorderLayout.CENTER);

        composerSelector.addTab("Markov Chains", pnlMarkov);

        lblNrBars.setText("initial number of bars:");

        spNrBars.setModel(new javax.swing.SpinnerNumberModel(15, 10, 50, 1));
        spNrBars.setVerifyInputWhenFocusTarget(false);

        lblPop.setText("initial population size:");

        spPop.setModel(new javax.swing.SpinnerNumberModel(500, 20, 1000, 1));

        lblPitchRange.setText("initial pitch range:");

        spPitchRange.setModel(new javax.swing.SpinnerNumberModel(2, 1, 5, 1));

        lblLowestNote.setText("lowest inital note:");

        cbLowestNote.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "C", "D", "E", "F", "G", "A", "H" }));

        lblOctave.setText("octave:");

        cbOctave.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "2", "3", "4", "5", "6" }));
        cbOctave.setSelectedIndex(2);

        lblShortestRhythm.setText("shortest inital rhythm value:");

        cbShortestRhythm.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0.25", "0.5", "1.0" }));
        cbShortestRhythm.setSelectedIndex(1);

        lblHoldProp.setText("inital hold propability:");

        spHoldProp.setModel(new javax.swing.SpinnerNumberModel(0.8d, 0.1d, 0.9d, 0.1d));

        lblTourSize.setText("tour size:");

        spTourSize.setModel(new javax.swing.SpinnerNumberModel(4, 2, 8, 1));

        lblMutationProp.setText("mutation propability:");

        spMutationProp.setModel(new javax.swing.SpinnerNumberModel(0.2d, 0.1d, 9.0d, 0.1d));

        lblIterations.setText("number of interations:");

        spIterations.setModel(new javax.swing.SpinnerNumberModel(70, 1, 600, 1));

        cbInitPopMotifs.setSelected(true);
        cbInitPopMotifs.setText("use motifs as initial population");
        cbInitPopMotifs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbInitPopMotifsActionPerformed(evt);
            }
        });

        cbMixInMotifs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbMixInMotifsActionPerformed(evt);
            }
        });

        lblMixProp.setText("motif mix propability:");
        lblMixProp.setEnabled(false);

        spMixProp.setModel(new javax.swing.SpinnerNumberModel(0.1d, 0.1d, 0.9d, 0.1d));
        spMixProp.setEnabled(false);

        jLabel2.setText("mix in motifs:");

        javax.swing.GroupLayout pnlGeneticLayout = new javax.swing.GroupLayout(pnlGenetic);
        pnlGenetic.setLayout(pnlGeneticLayout);
        pnlGeneticLayout.setHorizontalGroup(
            pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGeneticLayout.createSequentialGroup()
                .addGap(49, 49, 49)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lblIterations)
                    .addComponent(lblNrBars)
                    .addComponent(lblLowestNote)
                    .addComponent(lblPop)
                    .addComponent(lblMutationProp)
                    .addComponent(lblPitchRange)
                    .addComponent(lblTourSize))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlGeneticLayout.createSequentialGroup()
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(spNrBars, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(spPop, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(spPitchRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(pnlGeneticLayout.createSequentialGroup()
                                .addComponent(cbLowestNote, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(lblOctave)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(cbOctave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(spTourSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(spIterations, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(33, 33, 33)
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(cbInitPopMotifs)
                            .addGroup(pnlGeneticLayout.createSequentialGroup()
                                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(lblShortestRhythm)
                                    .addComponent(lblHoldProp))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(cbShortestRhythm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(spHoldProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                    .addGroup(pnlGeneticLayout.createSequentialGroup()
                        .addComponent(spMutationProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(118, 118, 118)
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(pnlGeneticLayout.createSequentialGroup()
                                .addComponent(jLabel2)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(cbMixInMotifs))
                            .addGroup(pnlGeneticLayout.createSequentialGroup()
                                .addComponent(lblMixProp)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(spMixProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap(196, Short.MAX_VALUE))
        );
        pnlGeneticLayout.setVerticalGroup(
            pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlGeneticLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblNrBars)
                    .addComponent(spNrBars, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cbInitPopMotifs))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(pnlGeneticLayout.createSequentialGroup()
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblPop)
                            .addComponent(spPop, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblPitchRange)
                            .addComponent(spPitchRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblLowestNote)
                            .addComponent(cbLowestNote, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblOctave)
                            .addComponent(cbOctave, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(pnlGeneticLayout.createSequentialGroup()
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblShortestRhythm)
                            .addComponent(cbShortestRhythm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(lblHoldProp)
                            .addComponent(spHoldProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addGap(71, 71, 71)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(lblTourSize)
                        .addComponent(spTourSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jLabel2))
                    .addComponent(cbMixInMotifs))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblMutationProp)
                    .addComponent(spMutationProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblMixProp)
                    .addComponent(spMixProp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(pnlGeneticLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblIterations)
                    .addComponent(spIterations, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(165, Short.MAX_VALUE))
        );

        composerSelector.addTab("Genetic Algorithm", pnlGenetic);

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

        pnlControl.setPreferredSize(new java.awt.Dimension(633, 100));
        pnlControl.setLayout(new java.awt.BorderLayout());

        pnlScoreProperties.setPreferredSize(new java.awt.Dimension(556, 25));
        pnlScoreProperties.setLayout(new java.awt.BorderLayout());

        pnlTempo.setPreferredSize(new java.awt.Dimension(100, 25));
        pnlTempo.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 2));

        lblTempo.setText("tempo");
        pnlTempo.add(lblTempo);

        spTempo.setPreferredSize(new java.awt.Dimension(60, 23));
        spTempo.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                spTempoStateChanged(evt);
            }
        });
        pnlTempo.add(spTempo);

        pnlScoreProperties.add(pnlTempo, java.awt.BorderLayout.LINE_START);

        pnlInstruments.setPreferredSize(new java.awt.Dimension(150, 25));
        pnlInstruments.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 2));

        cbInstrumentSubject.setMinimumSize(new java.awt.Dimension(56, 23));
        cbInstrumentSubject.setPreferredSize(new java.awt.Dimension(300, 23));
        cbInstrumentSubject.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbInstrumentSubjectItemStateChanged(evt);
            }
        });
        pnlInstruments.add(cbInstrumentSubject);

        lblSubject.setText("phrase");
        pnlInstruments.add(lblSubject);

        cbInstrumentCounter.setMinimumSize(new java.awt.Dimension(56, 23));
        cbInstrumentCounter.setPreferredSize(new java.awt.Dimension(300, 23));
        cbInstrumentCounter.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbInstrumentCounterItemStateChanged(evt);
            }
        });
        pnlInstruments.add(cbInstrumentCounter);

        lblCounter.setText("counter phrase");
        pnlInstruments.add(lblCounter);

        cbCounterPhrase.setSelected(true);
        cbCounterPhrase.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbCounterPhraseActionPerformed(evt);
            }
        });
        pnlInstruments.add(cbCounterPhrase);

        cbInstrumentAnswer.setMinimumSize(new java.awt.Dimension(56, 23));
        cbInstrumentAnswer.setPreferredSize(new java.awt.Dimension(300, 23));
        cbInstrumentAnswer.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbInstrumentAnswerItemStateChanged(evt);
            }
        });
        pnlInstruments.add(cbInstrumentAnswer);

        lblAnswer.setText("answer phrase");
        pnlInstruments.add(lblAnswer);

        cbAnswerPhrase.setSelected(true);
        cbAnswerPhrase.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbAnswerPhraseActionPerformed(evt);
            }
        });
        pnlInstruments.add(cbAnswerPhrase);

        cbInstrumentDrum.setMinimumSize(new java.awt.Dimension(56, 23));
        cbInstrumentDrum.setPreferredSize(new java.awt.Dimension(300, 23));
        cbInstrumentDrum.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbInstrumentDrumItemStateChanged(evt);
            }
        });
        pnlInstruments.add(cbInstrumentDrum);

        lblDrum.setText("drum");
        pnlInstruments.add(lblDrum);

        cbDrum.setSelected(true);
        cbDrum.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbDrumActionPerformed(evt);
            }
        });
        pnlInstruments.add(cbDrum);

        pnlScoreProperties.add(pnlInstruments, java.awt.BorderLayout.CENTER);

        pnlControl.add(pnlScoreProperties, java.awt.BorderLayout.CENTER);

        pnlButton.setPreferredSize(new java.awt.Dimension(100, 33));
        pnlButton.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.TRAILING));

        btnCompose.setText("Compose");
        btnCompose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnComposeActionPerformed(evt);
            }
        });
        pnlButton.add(btnCompose);

        pnlControl.add(pnlButton, java.awt.BorderLayout.LINE_END);

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

        toolbar.setRollover(true);

        btnPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play.png"))); // NOI18N
        btnPlay.setToolTipText("Play");
        btnPlay.setFocusable(false);
        btnPlay.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnPlay.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnPlay.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPlayActionPerformed(evt);
            }
        });
        toolbar.add(btnPlay);

        btnStop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/stop.png"))); // NOI18N
        btnStop.setToolTipText("Stop");
        btnStop.setFocusable(false);
        btnStop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnStop.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnStopActionPerformed(evt);
            }
        });
        toolbar.add(btnStop);

        pnlControlButton.setPreferredSize(new java.awt.Dimension(558, 30));
        pnlControlButton.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT, 5, 0));

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

        toolbar.add(pnlControlButton);

        getContentPane().add(toolbar, java.awt.BorderLayout.PAGE_START);

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

    private void btnComposeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnComposeActionPerformed
        int selectedComposer=  composerSelector.getSelectedIndex();
        
        toolbar.setVisible(false);
        switch(selectedComposer)
        {
            case MARKOV:
                mc = new MarkovComposer(this, composeInput, (int)spTempo.getValue(), slDepth.getValue(), slNoteCount.getValue(), cbPitch.isSelected(), cbRhythmvalue.isSelected(), cbDynamics.isSelected());
                mc.compose();
                break;
            case GENETIC:
                gc = new GeneticComposer(this, composeInput, (int)spTempo.getValue());
                gc.compose();
                break;
        }
    }//GEN-LAST:event_btnComposeActionPerformed

    public boolean mixInMotifs()
    {
        return cbMixInMotifs.isSelected();
    }
    
    public boolean areMotifsUsedForPopulation()
    {
        return cbInitPopMotifs.isSelected();
    }
    
    public int getPhraseInstrument()
    {
        return InstrumentStatics.instruments.get(cbInstrumentSubject.getSelectedItem());
    }
    
    public int getCounterPhraseInstrument()
    {
        return InstrumentStatics.instruments.get(cbInstrumentCounter.getSelectedItem());
    }
    
    public int getAnswerPhraseInstrument()
    {
        return InstrumentStatics.instruments.get(cbInstrumentAnswer.getSelectedItem());
    }
    
    public int getDrumPhraseInstrument()
    {
        return InstrumentStatics.drums.get(cbInstrumentDrum.getSelectedItem());
    }
    
    public boolean getAnswerPhraseMute()
    {
        return !cbAnswerPhrase.isSelected();
    }
    
    public boolean getCounterPhraseMute()
    {
        return !cbCounterPhrase.isSelected();
    }
    
    public boolean getDrumPhraseMute()
    {
        return !cbDrum.isSelected();
    }
    
    private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed
        MIDIPlayer.play(result);
    }//GEN-LAST:event_btnPlayActionPerformed

    private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopActionPerformed
        MIDIPlayer.stop();
    }//GEN-LAST:event_btnStopActionPerformed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        Write.midi(result.getMusicStructure());
    }//GEN-LAST:event_btnSaveActionPerformed

    private void composerSelectorStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_composerSelectorStateChanged
        toolbar.setVisible(false);
        mc = null;
        gc = null;
    }//GEN-LAST:event_composerSelectorStateChanged

    private void cbInstrumentSubjectItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbInstrumentSubjectItemStateChanged
        if(gc != null)
        {
            gc.setPhraseInstrument();
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.setPhraseInstrument();
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbInstrumentSubjectItemStateChanged

    private void cbInstrumentCounterItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbInstrumentCounterItemStateChanged
        if(gc != null)
        {
            gc.setCounterInstrument();
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.setCounterInstrument();
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbInstrumentCounterItemStateChanged

    private void cbInstrumentAnswerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbInstrumentAnswerItemStateChanged
        if(gc != null)
        {
            gc.setAnswerInstrument();
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.setAnswerInstrument();
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbInstrumentAnswerItemStateChanged

    private void cbInstrumentDrumItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbInstrumentDrumItemStateChanged
        if(gc != null)
        {
            gc.setDrumInstrument();
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.setDrumInstrument();
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbInstrumentDrumItemStateChanged

    private void cbInitPopMotifsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbInitPopMotifsActionPerformed
        if(cbInitPopMotifs.isSelected())
        {
            lblPitchRange.setEnabled(false);
            spPitchRange.setEnabled(false);
            lblShortestRhythm.setEnabled(false);
            cbShortestRhythm.setEnabled(false);
            lblHoldProp.setEnabled(false);
            spHoldProp.setEnabled(false);
        }
        else
        {
            lblPitchRange.setEnabled(true);
            spPitchRange.setEnabled(true);
            lblShortestRhythm.setEnabled(true);
            cbShortestRhythm.setEnabled(true);
            lblHoldProp.setEnabled(true);
            spHoldProp.setEnabled(true);
        }
    }//GEN-LAST:event_cbInitPopMotifsActionPerformed

    private void cbMixInMotifsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbMixInMotifsActionPerformed
        if(cbMixInMotifs.isSelected())
        {
            lblMixProp.setEnabled(true);
            spMixProp.setEnabled(true);
        }
        else
        {
            lblMixProp.setEnabled(false);
            spMixProp.setEnabled(false);
        }
    }//GEN-LAST:event_cbMixInMotifsActionPerformed

    private void spTempoStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spTempoStateChanged
        if(gc != null)
        {
            gc.setTempo((int)spTempo.getValue());
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.setTempo((int)spTempo.getValue());
            result = mc.getIScore();
        }
    }//GEN-LAST:event_spTempoStateChanged

    private void cbCounterPhraseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbCounterPhraseActionPerformed
        if(gc != null)
        {
            gc.muteCounterPhrase(!cbCounterPhrase.isSelected());
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.muteCounterPhrase(!cbCounterPhrase.isSelected());
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbCounterPhraseActionPerformed

    private void cbAnswerPhraseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbAnswerPhraseActionPerformed
        if(gc != null)
        {
            gc.muteAnswerPhrase(!cbAnswerPhrase.isSelected());
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.muteAnswerPhrase(!cbAnswerPhrase.isSelected());
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbAnswerPhraseActionPerformed

    private void cbDrumActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDrumActionPerformed
        if(gc != null)
        {
            gc.muteDrumPhrase(!cbDrum.isSelected());
            result = gc.getIScore();
        }
        if(mc != null)
        {
            mc.muteDrumPhrase(!cbDrum.isSelected());
            result = mc.getIScore();
        }
    }//GEN-LAST:event_cbDrumActionPerformed

    public double getMotifMixPropability()
    {
        return (double)spMixProp.getValue();
    }
    
    public int getNumberOfIterations()
    {
        return (int)spIterations.getValue();
    }
    
    public int getNumberOfBars()
    {
        return (int)spNrBars.getValue();
    }
    
    public int getInitialPopulationSize()
    {
        return (int)spPop.getValue();
    }
    
    public int getInitialPitchRange()
    {
        return (int)spPitchRange.getValue();
    }
    
    public int getLowestNote()
    {
        int[] pitches = new int[]{24, 26, 28, 29, 31, 33, 35};
        
        int pitch = pitches[cbLowestNote.getSelectedIndex()];
        int octave = Integer.parseInt((String)cbOctave.getSelectedItem());
        
        return (pitch + (octave - 1) * 12);
    }
    
    public double getShortestRhythmValue()
    {
        return Double.parseDouble((String)cbShortestRhythm.getSelectedItem());
    }
    
    public double getInitialHoldPorpability()
    {
        return (double)spHoldProp.getValue();
    }
    
    public int getTourSize()
    {
        return (int)spTourSize.getValue();
    }
    
    public double getMutationPropability()
    {
        return (double)spMutationProp.getValue();
    }
    
    public void composerFinished(IScore result)
    {
        if(result != null)
        {
            toolbar.setVisible(true);
            this.result = result;
        }
        else
            JOptionPane.showMessageDialog(this, "All chromosomes died", "Error", JOptionPane.ERROR_MESSAGE);
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ComposingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ComposingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ComposingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ComposingDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the dialog
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                ComposingDialog dialog = new ComposingDialog(new javax.swing.JFrame(), true, null);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCompose;
    private javax.swing.JButton btnPlay;
    private javax.swing.JButton btnSave;
    private javax.swing.JButton btnStop;
    private javax.swing.JCheckBox cbAnswerPhrase;
    private javax.swing.JCheckBox cbCounterPhrase;
    private javax.swing.JCheckBox cbDrum;
    private javax.swing.JCheckBox cbDynamics;
    private javax.swing.JCheckBox cbInitPopMotifs;
    private javax.swing.JComboBox cbInstrumentAnswer;
    private javax.swing.JComboBox cbInstrumentCounter;
    private javax.swing.JComboBox cbInstrumentDrum;
    private javax.swing.JComboBox cbInstrumentSubject;
    private javax.swing.JComboBox cbLowestNote;
    private javax.swing.JCheckBox cbMixInMotifs;
    private javax.swing.JComboBox cbOctave;
    private javax.swing.JCheckBox cbPitch;
    private javax.swing.JCheckBox cbRhythmvalue;
    private javax.swing.JComboBox cbShortestRhythm;
    private javax.swing.JTabbedPane composerSelector;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel lblAnswer;
    private javax.swing.JLabel lblCounter;
    private javax.swing.JLabel lblDepth;
    private javax.swing.JLabel lblDepthValue;
    private javax.swing.JLabel lblDrum;
    private javax.swing.JLabel lblHoldProp;
    private javax.swing.JLabel lblIterations;
    private javax.swing.JLabel lblLowestNote;
    private javax.swing.JLabel lblMixProp;
    private javax.swing.JLabel lblMutationProp;
    private javax.swing.JLabel lblNoteCount;
    private javax.swing.JLabel lblNoteCountValue;
    private javax.swing.JLabel lblNrBars;
    private javax.swing.JLabel lblOctave;
    private javax.swing.JLabel lblPitchRange;
    private javax.swing.JLabel lblPop;
    private javax.swing.JLabel lblShortestRhythm;
    private javax.swing.JLabel lblSubject;
    private javax.swing.JLabel lblTempo;
    private javax.swing.JLabel lblTourSize;
    private javax.swing.JPanel pnlButton;
    private javax.swing.JPanel pnlControl;
    private javax.swing.JPanel pnlControlButton;
    private javax.swing.JPanel pnlDepth;
    private javax.swing.JPanel pnlGenetic;
    private javax.swing.JPanel pnlInstruments;
    private javax.swing.JPanel pnlMarkov;
    private javax.swing.JPanel pnlNoteCount;
    private javax.swing.JPanel pnlParamBoxes;
    private javax.swing.JPanel pnlParamTitle;
    private javax.swing.JPanel pnlParams;
    private javax.swing.JPanel pnlScoreProperties;
    private javax.swing.JPanel pnlTempo;
    private javax.swing.JSlider slDepth;
    private javax.swing.JSlider slNoteCount;
    private javax.swing.JSpinner spHoldProp;
    private javax.swing.JSpinner spIterations;
    private javax.swing.JSpinner spMixProp;
    private javax.swing.JSpinner spMutationProp;
    private javax.swing.JSpinner spNrBars;
    private javax.swing.JSpinner spPitchRange;
    private javax.swing.JSpinner spPop;
    private javax.swing.JSpinner spTempo;
    private javax.swing.JSpinner spTourSize;
    private javax.swing.JToolBar toolbar;
    // End of variables declaration//GEN-END:variables

    @Override
    public void stateChanged(ChangeEvent e) {
        if(e.getSource() == slDepth)
            lblDepthValue.setText("" + slDepth.getValue());
        if(e.getSource() == slNoteCount)
            lblNoteCountValue.setText("" + slNoteCount.getValue());
    }
}

