package turgen.plugin.standard;

import java.awt.Component;
import javax.swing.*;
import java.io.*;
import turgen.Utils;
import turgen.dtb.DOS2Binary;
import turgen.plugin.InOutProvider;

public class StandardPluginPanel extends javax.swing.JPanel {
    
    
    InOutProvider ioProvider;
    
    private static final int GAPS_LONGSHORT=0;
    private static final int GAPS_CLOAD_LOAD=1;
    
    private StandardPlugin plugin;
    
    /** Creates new PlTurboROMPluginPanel */
    public StandardPluginPanel(StandardPlugin plugin) {
        initComponents();
        setupToolTips();
        onInputTypeChanged(null);
        this.plugin=plugin;
    }
    
    /** 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;

        bgGaps = new javax.swing.ButtonGroup();
        pHeader = new javax.swing.JPanel();
        jtfName = new javax.swing.JTextField();
        jlbName = new javax.swing.JLabel();
        btnGuessHeader = new javax.swing.JButton();
        pHandling = new javax.swing.JPanel();
        jcoInputType = new javax.swing.JComboBox();
        btnCheckLoader = new javax.swing.JButton();
        pBinaryFile = new javax.swing.JPanel();
        jlbPauses = new javax.swing.JLabel();
        jtfPauses = new javax.swing.JTextField();
        pFiller = new javax.swing.JPanel();
        pDataFile = new javax.swing.JPanel();
        jrbLongGaps = new javax.swing.JRadioButton();
        jrbShortGaps = new javax.swing.JRadioButton();

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

        pHeader.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Header"));
        pHeader.setLayout(new java.awt.GridBagLayout());

        jtfName.setColumns(22);
        jtfName.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        jtfName.setToolTipText("File name");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.2;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 0);
        pHeader.add(jtfName, gridBagConstraints);

        jlbName.setText("File name:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 0);
        pHeader.add(jlbName, gridBagConstraints);

        btnGuessHeader.setMnemonic('h');
        btnGuessHeader.setText("Auto set header");
        btnGuessHeader.setToolTipText("<HTML>\nAutomatically fill the turbo header using:<BR>\n1.Analysis of input file<BR>\n2.Selected conversion type<BR>\n</HTML>\n\n");
        btnGuessHeader.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                on_guess_header(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weighty = 0.2;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 0);
        pHeader.add(btnGuessHeader, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        add(pHeader, gridBagConstraints);

        pHandling.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Input file type"));
        pHandling.setLayout(new java.awt.GridBagLayout());

        jcoInputType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Monolithic binary file", "Binary file", "Data file", "BASIC tokenized", "BASIC source" }));
        jcoInputType.setToolTipText("Choose type of the input file");
        jcoInputType.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                onInputTypeChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 0);
        pHandling.add(jcoInputType, gridBagConstraints);

        btnCheckLoader.setMnemonic('c');
        btnCheckLoader.setText("Check loader");
        btnCheckLoader.setEnabled(false);
        btnCheckLoader.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCheckLoaderActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        pHandling.add(btnCheckLoader, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        add(pHandling, gridBagConstraints);

        pBinaryFile.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Binary file"));
        pBinaryFile.setLayout(new java.awt.GridBagLayout());

        jlbPauses.setText("Silence list:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 0);
        pBinaryFile.add(jlbPauses, gridBagConstraints);

        jtfPauses.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        jtfPauses.setToolTipText("<HTML>\nEnter comma-separated list of silence specifications<br>\nEach silence specification will be used to generate silence or pause the signal generator after an INIT segment<br><br>\nSilence specification can be the following:<br>\nNumber of seconds (e.g. <b>3</b>)<br>\nNumber of seconds followed by P (e.g. <b>3P</b>)<br>\nP (e.g. <b>P</b>)\n</HTML>");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        pBinaryFile.add(jtfPauses, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
        add(pBinaryFile, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weighty = 1.0;
        add(pFiller, gridBagConstraints);

        pDataFile.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Gaps between records"));
        pDataFile.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 5, 4));

        bgGaps.add(jrbLongGaps);
        jrbLongGaps.setSelected(true);
        jrbLongGaps.setText("Long");
        pDataFile.add(jrbLongGaps);

        bgGaps.add(jrbShortGaps);
        jrbShortGaps.setText("Short");
        pDataFile.add(jrbShortGaps);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
        add(pDataFile, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents
    
    private void on_guess_header(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_on_guess_header

        /*What conversion type was selected*/
        int inputType = comboIndex2InputType(jcoInputType.getSelectedIndex());
        /*Clearing text fields*/
        jtfName.setText("");

        /*Testing existence*/
        File f = new File(ioProvider.getInFile());
        /*Testing existence*/
        String msg = Utils.checkIfHeaderCanBeSet(f);
        if (msg!=null) {
            JOptionPane.showMessageDialog(null, msg,"Unable to set header",JOptionPane.ERROR_MESSAGE);
            return;
        }


        /*Setting header according to conversion type*/
        switch (inputType) {
            case StandardPlaylistItem.IT_BASIC_SOURCE: break;
            case StandardPlaylistItem.IT_BASIC_TOKENIZED: break;
            case StandardPlaylistItem.IT_MONOLITHIC_BINARY: break;
            case StandardPlaylistItem.IT_DATA: break;
            case StandardPlaylistItem.IT_BINARY:  {
                String fn=f.getName();
                if (fn.length()>20) fn=fn.substring(0,20);
                jtfName.setText(fn);
            }
        }


    }//GEN-LAST:event_on_guess_header

    private void onInputTypeChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_onInputTypeChanged

        int inputType = comboIndex2InputType(jcoInputType.getSelectedIndex());
        switch (inputType) {
            case StandardPlaylistItem.IT_MONOLITHIC_BINARY: {
                setPanelEnabled(pHeader,false);
                setPanelEnabled(pBinaryFile,false);
                setPanelEnabled(pDataFile,false);
                btnCheckLoader.setEnabled(false);
                setGapsPanel(GAPS_LONGSHORT);
                break;        
            }
            case StandardPlaylistItem.IT_BINARY: {
                setPanelEnabled(pHeader,true);
                setPanelEnabled(pBinaryFile,true);
                setPanelEnabled(pDataFile,false);
                btnCheckLoader.setEnabled(true);
                setGapsPanel(GAPS_LONGSHORT);
                break;
            }
            case StandardPlaylistItem.IT_DATA: {
                setPanelEnabled(pHeader,false);
                setPanelEnabled(pBinaryFile,false);
                setPanelEnabled(pDataFile,true);
                btnCheckLoader.setEnabled(false);
                setGapsPanel(GAPS_LONGSHORT);
                break;
            }
            case StandardPlaylistItem.IT_BASIC_TOKENIZED: {
                setPanelEnabled(pHeader,false);
                setPanelEnabled(pBinaryFile,false);
                setPanelEnabled(pDataFile,true);
                btnCheckLoader.setEnabled(false);
                setGapsPanel(GAPS_CLOAD_LOAD);
                break;
            }
            case StandardPlaylistItem.IT_BASIC_SOURCE: {
                setPanelEnabled(pHeader,false);
                setPanelEnabled(pBinaryFile,false);
                setPanelEnabled(pDataFile,false);
                btnCheckLoader.setEnabled(false);
                setGapsPanel(GAPS_LONGSHORT);
                break;
            }
        }
        
    }//GEN-LAST:event_onInputTypeChanged

    private void btnCheckLoaderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckLoaderActionPerformed

        String message = Utils.checkForBinaryLoader(ioProvider.getInFile(), 0x6f2, 0x085d, 0x6f2, 0x085d, 254);
        JOptionPane.showMessageDialog(null, message,"Loader check",JOptionPane.INFORMATION_MESSAGE);

    }//GEN-LAST:event_btnCheckLoaderActionPerformed
    
    private void setPanelEnabled(JPanel p,boolean enabled) {
        p.setEnabled(enabled);
        Component[] comps = p.getComponents();
        for (int i=0;i<comps.length;i++) {
            comps[i].setEnabled(enabled);
        }
    }
    
    private int comboIndex2InputType(int index) {
        switch (index) {
            case 0: return StandardPlaylistItem.IT_MONOLITHIC_BINARY;
            case 1: return StandardPlaylistItem.IT_BINARY;
            case 2: return StandardPlaylistItem.IT_DATA;
            case 3: return StandardPlaylistItem.IT_BASIC_TOKENIZED;
            case 4: return StandardPlaylistItem.IT_BASIC_SOURCE;
            default: return StandardPlaylistItem.IT_MONOLITHIC_BINARY;     
        }
    }
    
    private int InputType2ComboIndex(int inputType) {
        switch (inputType) {
            case StandardPlaylistItem.IT_MONOLITHIC_BINARY: return 0;
            case StandardPlaylistItem.IT_BINARY: return 1;
            case StandardPlaylistItem.IT_DATA: return 2;
            case StandardPlaylistItem.IT_BASIC_TOKENIZED: return 3;
            case StandardPlaylistItem.IT_BASIC_SOURCE: return 4;
            default: return 0;
        }
    }
    
    
    
    
    private void setGapsPanel(int panelType) {
        
        switch(panelType) {
            case GAPS_LONGSHORT: {
                jrbLongGaps.setText("Long");
                jrbShortGaps.setText("Short");
                break;
            }
            case GAPS_CLOAD_LOAD: {
                jrbLongGaps.setText("LOAD");
                jrbShortGaps.setText("CLOAD");
                break;
            }
            
        }
        
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup bgGaps;
    private javax.swing.JButton btnCheckLoader;
    private javax.swing.JButton btnGuessHeader;
    private javax.swing.JComboBox jcoInputType;
    private javax.swing.JLabel jlbName;
    private javax.swing.JLabel jlbPauses;
    private javax.swing.JRadioButton jrbLongGaps;
    private javax.swing.JRadioButton jrbShortGaps;
    private javax.swing.JTextField jtfName;
    private javax.swing.JTextField jtfPauses;
    private javax.swing.JPanel pBinaryFile;
    private javax.swing.JPanel pDataFile;
    private javax.swing.JPanel pFiller;
    private javax.swing.JPanel pHandling;
    private javax.swing.JPanel pHeader;
    // End of variables declaration//GEN-END:variables
    
    
    void clear() {
        jtfName.setText("");
        jcoInputType.setSelectedIndex(0);
    }
    
    
    public StandardPlaylistItem getRecord() {
        StandardPlaylistItem item = new StandardPlaylistItem(ioProvider.getInFile(),
                ioProvider.getOutFile(),
                jtfName.getText(),
                comboIndex2InputType(jcoInputType.getSelectedIndex()),
                Utils.parseSilenceList(jtfPauses.getText().trim()),
                jrbShortGaps.isSelected()
        );
        return item;
    }

    
    public void fill(StandardPlaylistItem item) {
        jtfName.setText(item.fname);
        jcoInputType.setSelectedIndex(InputType2ComboIndex(item.inputType));
        jtfPauses.setText(Utils.silenceListToString(item.silenceList));
        jrbShortGaps.setSelected(item.shortIRG);

    }
    
    public String verify() {
        int inputType = comboIndex2InputType(jcoInputType.getSelectedIndex());
        switch(inputType) {
            case StandardPlaylistItem.IT_MONOLITHIC_BINARY: {
                
                try {
                    DOS2Binary binary = new DOS2Binary(ioProvider.getInFile());
                    return plugin.verifyMonolithicBinary(null, binary);
                }
                catch(Exception e) {
                    return "Unable to verify playlist item: "+Utils.getExceptionMessage(e);
                }
                
            }
            default: return null;
        }
    }
    
    
    private void setupToolTips() {
        
    }


}


   



