package turgen.plugin.plturbo;

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

public class PlTurboROMPluginPanel extends javax.swing.JPanel {
    
    InOutProvider ioProvider;
    
    private static final int DTB_NOT_RECOGNIZED=0;
    private static final int DTB_COMPATIBLE=1;
    private static final int DTB_NONCOMPATIBLE=2;

    /** Creates new PlTurboROMPluginPanel */
    public PlTurboROMPluginPanel() {
        initComponents();
        setupToolTips();
    }
    
    /** 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;

        pTHeader = new javax.swing.JPanel();
        jtfName = new javax.swing.JTextField();
        jlbName = new javax.swing.JLabel();
        btnGuessHeader = new javax.swing.JButton();
        pHandling = new javax.swing.JPanel();
        jcoConversionType = new javax.swing.JComboBox();
        jbtCheckLoader = new javax.swing.JButton();
        pOther = new javax.swing.JPanel();
        pFiller = new javax.swing.JPanel();
        pBinaryFile = new javax.swing.JPanel();
        jlbPauses = new javax.swing.JLabel();
        jtfPauses = new javax.swing.JTextField();

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

        pTHeader.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Header block"));
        pTHeader.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.insets = new java.awt.Insets(4, 4, 0, 0);
        pTHeader.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, 0, 0);
        pTHeader.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);
        pTHeader.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(pTHeader, gridBagConstraints);

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

        jcoConversionType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Turbo ROM compatible binary file", "Binary file ", "Tokenized BASIC" }));
        jcoConversionType.setToolTipText("Choose type of the input file");
        jcoConversionType.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                on_cvTypeChanged(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(4, 4, 4, 0);
        pHandling.add(jcoConversionType, gridBagConstraints);

        jbtCheckLoader.setText("Check loader");
        jbtCheckLoader.setEnabled(false);
        jbtCheckLoader.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                onCheckLoader(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        pHandling.add(jbtCheckLoader, 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);

        pOther.setLayout(new java.awt.GridBagLayout());
        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(pOther, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.weighty = 1.0;
        add(pFiller, 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>\nPlace <b>comma-separated list of numebrs</b> here. <br>\nEach number is <b>length of silence</b> (in seconds) generated <b>after INIT segments.</b><br>\nThis is useful only if the MOTOR CTRL signal is ignored by device you are using.<br>\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.weightx = 1.0;
        add(pBinaryFile, 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 idx = this.jcoConversionType.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;
        }

        /*File name*/
        String fn=f.getName();
        if (fn.length()>20) fn=fn.substring(0,20);

        /*Setting header according to conversion type*/
        switch (idx) {

            /*Turbo ROM compatible binary file*/
            case PlTurboROMPlaylistItem.CV_COMPATIBLE_BINARY: {

                DOS2Binary dtb = new DOS2Binary(ioProvider.getInFile());
                try {
                    dtb.analyzeFromFile();
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(this, Utils.getTitledExceptionMessage("Unable to set header", e),"Unable to set header",JOptionPane.ERROR_MESSAGE);
                    return;
                }

                if (!dtb.isPlTurboROMCompatible()) {
                    JOptionPane.showMessageDialog(this, NONCOMPATIBLE_MSG, "Not a Turbo ROM compatible binary file", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                break;
            }
        }

    /*File name is common*/
    jtfName.setText(fn.toUpperCase());
    

    }//GEN-LAST:event_on_guess_header

    private void on_cvTypeChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_on_cvTypeChanged
        if (jcoConversionType.getSelectedIndex()==PlTurboROMPlaylistItem.CV_BINARY) {
            jbtCheckLoader.setEnabled(true);
        }
        else {
            jbtCheckLoader.setEnabled(false);
        }
    }//GEN-LAST:event_on_cvTypeChanged

    private void onCheckLoader(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onCheckLoader
        
        String fname=ioProvider.getInFile();
        
        String msg=Utils.checkForBinaryLoader(fname, 0x0800, 0x0987, 0x0800, 0x0987, Integer.MAX_VALUE);
        JOptionPane.showMessageDialog(null, msg,"Loader check",JOptionPane.INFORMATION_MESSAGE);
        
    }//GEN-LAST:event_onCheckLoader
    
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnGuessHeader;
    private javax.swing.JButton jbtCheckLoader;
    private javax.swing.JComboBox jcoConversionType;
    private javax.swing.JLabel jlbName;
    private javax.swing.JLabel jlbPauses;
    private javax.swing.JTextField jtfName;
    private javax.swing.JTextField jtfPauses;
    private javax.swing.JPanel pBinaryFile;
    private javax.swing.JPanel pFiller;
    private javax.swing.JPanel pHandling;
    private javax.swing.JPanel pOther;
    private javax.swing.JPanel pTHeader;
    // End of variables declaration//GEN-END:variables
    
    
    void clear() {
        jtfName.setText("");
    }
    
    
    public PlTurboROMPlaylistItem getRecord() {
        PlTurboROMPlaylistItem trpi = new PlTurboROMPlaylistItem(ioProvider.getInFile(),ioProvider.getOutFile(),ioProvider.getPulses(),jtfName.getText(),jcoConversionType.getSelectedIndex(),Utils.parseNumberList(jtfPauses.getText().trim()));
        return trpi;
    }
    
    
    public void fill(PlTurboROMPlaylistItem trpi) {
        jtfName.setText(trpi.fname);
        jcoConversionType.setSelectedIndex(trpi.conversionType);
        jtfPauses.setText(Utils.createNumberList(trpi.silenceList));

    }
    
    public String verify() {
        
        if (jcoConversionType.getSelectedIndex()==PlTurboROMPlaylistItem.CV_COMPATIBLE_BINARY) {
            int rt=verifyTurboROMCompatible();
            if (rt==DTB_NONCOMPATIBLE) {
                JOptionPane.showMessageDialog(this,NONCOMPATIBLE_MSG,"Not a Turbo ROM compatible binary file",JOptionPane.WARNING_MESSAGE);
            }
        }
        return null;
    }

    private int verifyTurboROMCompatible() {

        /*Load and analyze file*/
        DOS2Binary ae = new DOS2Binary(ioProvider.getInFile());
        try {
            ae.analyzeFromFile();
        }
        catch (Exception e) {
            return DTB_NOT_RECOGNIZED;
        }

        /*Test whether file is monolithic*/
        boolean nonmonolithic = !ae.isPlTurboROMCompatible();
        /*Return appropriate result*/
        return nonmonolithic==true?DTB_NONCOMPATIBLE:DTB_COMPATIBLE;

    }
    
    
    private void setupToolTips() {
        
    }
    
    
    private static final String NONCOMPATIBLE_MSG
            = "<HTML>Input file is not a Turbo ROM compatible binary file.</B><BR><BR>"
            + "You have chosen the \"Turbo ROM compatible binary file\" input file type,<BR> but the input file is not a Turbo ROM compatible binary file.<BR><BR>"
            + "To convert the binary file, use the <U>Binary file</U>  input file type.<BR><BR>"
            + "<I>Technical note: Turbo ROM compatible binary files are binary files that contain<BR> exactly one DATA segment and at most one RUN segment and at most one INIT segment.</I>"
            + "</HTML>";


}


   



