package turgen.tapeimageextractor;

import java.awt.event.ItemEvent;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.JTextField;
import javax.swing.SpinnerListModel;

public class SetHintDialog extends javax.swing.JDialog {

    
    private HintsCrate hintsCrate=null;
    private HintsCrate.Map hintsMap=null;
    
    private HintSpinnerModel hspSkipHead;
    private HintSpinnerModel hspSkipTail;
    private HintSpinnerModel hspLengthOffsetLow;
    private HintSpinnerModel hspLengthOffsetHigh;
    
    
    
    /**
     * Creates new form SetHintDialog
     */
    public SetHintDialog() {
        
        
        createSpinnerModels();
        setModal(true);
        initComponents();
        initComponentsForVaryingValues();
        
        
    }
    
    

    /**
     * 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() {
        java.awt.GridBagConstraints gridBagConstraints;

        jrbgLengthWidth = new javax.swing.ButtonGroup();
        jrbgExtractData = new javax.swing.ButtonGroup();
        pButtons = new javax.swing.JPanel();
        jbtOK = new javax.swing.JButton();
        jbtCancel = new javax.swing.JButton();
        pMainControls = new javax.swing.JPanel();
        pExtractionRange = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jspSkipHead = new javax.swing.JSpinner();
        jLabel2 = new javax.swing.JLabel();
        jspSkipTail = new javax.swing.JSpinner();
        jlbFiller1 = new javax.swing.JLabel();
        pExtractionLength = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jspLengthOffsetLow = new javax.swing.JSpinner();
        jrbLength8Bit = new javax.swing.JRadioButton();
        jrbLength16Bit = new javax.swing.JRadioButton();
        jspLengthOffsetHigh = new javax.swing.JSpinner();
        jLabel4 = new javax.swing.JLabel();
        jrbLengthNone = new javax.swing.JRadioButton();
        pFiller = new javax.swing.JPanel();
        jrbLengthVarying = new javax.swing.JRadioButton();
        jLabel5 = new javax.swing.JLabel();
        pExtractData = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        jrbExtractDataYes = new javax.swing.JRadioButton();
        jrbExtractDataNo = new javax.swing.JRadioButton();
        jlbFiller2 = new javax.swing.JLabel();
        jrbExtractDataVarying = new javax.swing.JRadioButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Set Extraction Hints");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                onClose(evt);
            }
        });

        jbtOK.setMnemonic('O');
        jbtOK.setText("OK");
        jbtOK.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                onOK(evt);
            }
        });
        pButtons.add(jbtOK);

        jbtCancel.setText("Cancel");
        jbtCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                onCancel(evt);
            }
        });
        pButtons.add(jbtCancel);

        getContentPane().add(pButtons, java.awt.BorderLayout.SOUTH);

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

        pExtractionRange.setBorder(javax.swing.BorderFactory.createTitledBorder("Extraction range"));
        pExtractionRange.setLayout(new java.awt.GridBagLayout());

        jLabel1.setText("Head bytes to skip");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        pExtractionRange.add(jLabel1, gridBagConstraints);

        jspSkipHead.setModel(hspSkipHead);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pExtractionRange.add(jspSkipHead, gridBagConstraints);

        jLabel2.setText("Tail bytes to skip");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        pExtractionRange.add(jLabel2, gridBagConstraints);

        jspSkipTail.setModel(hspSkipTail);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pExtractionRange.add(jspSkipTail, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        pExtractionRange.add(jlbFiller1, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pMainControls.add(pExtractionRange, gridBagConstraints);

        pExtractionLength.setBorder(javax.swing.BorderFactory.createTitledBorder("Number of valid bytes in chunk"));
        pExtractionLength.setLayout(new java.awt.GridBagLayout());

        jLabel3.setText("Low byte offset");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        pExtractionLength.add(jLabel3, gridBagConstraints);

        jspLengthOffsetLow.setModel(hspLengthOffsetLow);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pExtractionLength.add(jspLengthOffsetLow, gridBagConstraints);

        jrbgLengthWidth.add(jrbLength8Bit);
        jrbLength8Bit.setSelected(true);
        jrbLength8Bit.setText("8-bit");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        pExtractionLength.add(jrbLength8Bit, gridBagConstraints);

        jrbgLengthWidth.add(jrbLength16Bit);
        jrbLength16Bit.setText("16-bit");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        pExtractionLength.add(jrbLength16Bit, gridBagConstraints);

        jspLengthOffsetHigh.setModel(hspLengthOffsetHigh);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pExtractionLength.add(jspLengthOffsetHigh, gridBagConstraints);

        jLabel4.setText("High byte offset");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        pExtractionLength.add(jLabel4, gridBagConstraints);

        jrbgLengthWidth.add(jrbLengthNone);
        jrbLengthNone.setText("None");
        jrbLengthNone.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                onLengthTypeChanged(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        pExtractionLength.add(jrbLengthNone, gridBagConstraints);

        pFiller.setLayout(null);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        pExtractionLength.add(pFiller, gridBagConstraints);

        jrbgLengthWidth.add(jrbLengthVarying);
        jrbLengthVarying.setText("0");
        jrbLengthVarying.setEnabled(false);
        jrbLengthVarying.setFocusable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        pExtractionLength.add(jrbLengthVarying, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pMainControls.add(pExtractionLength, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        pMainControls.add(jLabel5, gridBagConstraints);

        pExtractData.setBorder(javax.swing.BorderFactory.createTitledBorder("Extraction"));
        pExtractData.setLayout(new java.awt.GridBagLayout());

        jLabel6.setText("Extract data");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        pExtractData.add(jLabel6, gridBagConstraints);

        jrbgExtractData.add(jrbExtractDataYes);
        jrbExtractDataYes.setSelected(true);
        jrbExtractDataYes.setText("Yes");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
        pExtractData.add(jrbExtractDataYes, gridBagConstraints);

        jrbgExtractData.add(jrbExtractDataNo);
        jrbExtractDataNo.setText("No");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
        pExtractData.add(jrbExtractDataNo, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        pExtractData.add(jlbFiller2, gridBagConstraints);

        jrbgExtractData.add(jrbExtractDataVarying);
        jrbExtractDataVarying.setText("0");
        pExtractData.add(jrbExtractDataVarying, new java.awt.GridBagConstraints());

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 0);
        pMainControls.add(pExtractData, gridBagConstraints);

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

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

    private void onCancel(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onCancel
            hintsCrate=null;
            setVisible(false);
            dispose();
    }//GEN-LAST:event_onCancel

    private void onClose(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_onClose
        onCancel(null);
    }//GEN-LAST:event_onClose

    private void onOK(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onOK
        hintsMap=createHintsMap();
        hintsCrate=createHintsCrate();
        setVisible(false);
        dispose();
    }//GEN-LAST:event_onOK

    private void onLengthTypeChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_onLengthTypeChanged
        if (evt.getStateChange()==ItemEvent.DESELECTED) return;
        
        if (hintsMap!=null) {
            if (hintsMap.lengthType==false) {
                hintsMap.lengthType=true;
            }
        }
    }//GEN-LAST:event_onLengthTypeChanged

    /**
     * @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(SetHintDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(SetHintDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(SetHintDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(SetHintDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new SetHintDialog().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JButton jbtCancel;
    private javax.swing.JButton jbtOK;
    private javax.swing.JLabel jlbFiller1;
    private javax.swing.JLabel jlbFiller2;
    private javax.swing.JRadioButton jrbExtractDataNo;
    private javax.swing.JRadioButton jrbExtractDataVarying;
    private javax.swing.JRadioButton jrbExtractDataYes;
    private javax.swing.JRadioButton jrbLength16Bit;
    private javax.swing.JRadioButton jrbLength8Bit;
    private javax.swing.JRadioButton jrbLengthNone;
    private javax.swing.JRadioButton jrbLengthVarying;
    private javax.swing.ButtonGroup jrbgExtractData;
    private javax.swing.ButtonGroup jrbgLengthWidth;
    private javax.swing.JSpinner jspLengthOffsetHigh;
    private javax.swing.JSpinner jspLengthOffsetLow;
    private javax.swing.JSpinner jspSkipHead;
    private javax.swing.JSpinner jspSkipTail;
    private javax.swing.JPanel pButtons;
    private javax.swing.JPanel pExtractData;
    private javax.swing.JPanel pExtractionLength;
    private javax.swing.JPanel pExtractionRange;
    private javax.swing.JPanel pFiller;
    private javax.swing.JPanel pMainControls;
    // End of variables declaration//GEN-END:variables
    
    void fillValues(HintsCrate c,HintsCrate.Map map) {
        
        /* Extraction*/
        if (c.extractData==true) {
            jrbExtractDataYes.setSelected(true);
        }
        else {
            jrbExtractDataNo.setSelected(true);
        }
        
        /* Handle length*/
        switch (c.lengthType) {
            case HintsCrate.LENGTH_TYPE_NONE: {
                jspLengthOffsetLow.setValue(Integer.toString(0));
                jspLengthOffsetHigh.setValue(Integer.toString(0));
                jrbLengthNone.setSelected(true);    
                break;
            }
            case HintsCrate.LENGTH_TYPE_8BIT: {
                jspLengthOffsetLow.setValue(Integer.toString(c.lengthOffsetLow));
                jspLengthOffsetHigh.setValue(Integer.toString(0));
                jrbLength8Bit.setSelected(true);    
                break;
            }
            case HintsCrate.LENGTH_TYPE_16BIT: {
                jspLengthOffsetLow.setValue(Integer.toString(c.lengthOffsetLow));
                jspLengthOffsetHigh.setValue(Integer.toString(c.lengthOffsetHigh));
                jrbLength16Bit.setSelected(true);    
                break;
            }
        }
        
        /* Handle head and tail*/
        jspSkipHead.setValue(Integer.toString(c.skipHead));
        jspSkipTail.setValue(Integer.toString(c.skipTail));
        hintsMap = map;
        
        /*Varying values*/
        if (map.skipHead==false) {
            jspSkipHead.setValue(Integer.toString(HintSpinnerModel.DIFFERENT_VALUES));
        }
        if (map.skipTail==false) {
            jspSkipTail.setValue(Integer.toString(HintSpinnerModel.DIFFERENT_VALUES));
        }
        if (map.lengthOffsetLow==false) {
            jspLengthOffsetLow.setValue(Integer.toString(HintSpinnerModel.DIFFERENT_VALUES));
        }
        if (map.lengthOffsetHigh==false) {
            jspLengthOffsetHigh.setValue(Integer.toString(HintSpinnerModel.DIFFERENT_VALUES));
        }
        if (map.lengthType==false) {
            jrbLengthVarying.setSelected(true);
        }
        if (map.extractData==false) {
            jrbExtractDataVarying.setSelected(true);
        }
        
    }
    
    private HintsCrate createHintsCrate() {
        
        hintsMap=createHintsMap();
        
        int skipHead = 0;
        int skipTail  = 0;
        int lengthOffsetLow = 0;
        int lengthOffsetHigh = 0;
        int lengthType=HintsCrate.LENGTH_TYPE_NONE;
        boolean extractData=true;
        
        /*Extract data*/
        if (hintsMap.extractData==true) {
            extractData=jrbExtractDataYes.isSelected();
        }
        /*Head and tail*/
        if (hintsMap.skipHead==true) {
            skipHead=Integer.parseInt((String)jspSkipHead.getValue());
        }
        if (hintsMap.skipTail==true) {
            skipTail=Integer.parseInt((String)jspSkipTail.getValue());
        }
        
        /* Length offset*/
        if (hintsMap.lengthOffsetLow==true) {
            lengthOffsetLow = Integer.parseInt((String)jspLengthOffsetLow.getValue());
        }
        if (hintsMap.lengthOffsetHigh==true) {
            lengthOffsetHigh = Integer.parseInt((String)jspLengthOffsetHigh.getValue());
        }
        
        /*Length type*/
        if (hintsMap.lengthType == true) {
            if (jrbLength8Bit.isSelected()) {
                lengthType = HintsCrate.LENGTH_TYPE_8BIT;
            }
            if (jrbLength16Bit.isSelected()) {
                lengthType = HintsCrate.LENGTH_TYPE_16BIT;
            }
        }
        
        return new HintsCrate(skipHead,skipTail,lengthOffsetLow,lengthOffsetHigh,lengthType,extractData);
        
    }
    
    private HintsCrate.Map createHintsMap() {
        HintsCrate.Map map = new HintsCrate.Map(true);
        
        /*Head*/
        if (((String)jspSkipHead.getValue()).equals(HintSpinnerModel.DIFFERENT_VALUES_STRING)) {
            map.skipHead=false;
        }
        /*Tail*/
        if (((String)jspSkipTail.getValue()).equals(HintSpinnerModel.DIFFERENT_VALUES_STRING)) {
            map.skipTail=false;
        }
        /*Length offsets*/
        if (((String)jspLengthOffsetLow.getValue()).equals(HintSpinnerModel.DIFFERENT_VALUES_STRING)) {
            map.lengthOffsetLow=false;
        }
        if (((String)jspLengthOffsetHigh.getValue()).equals(HintSpinnerModel.DIFFERENT_VALUES_STRING)) {
            map.lengthOffsetHigh=false;
        }
        
        if (jrbExtractDataVarying.isSelected()) {
            map.extractData=false;
        }
        if (jrbLengthVarying.isSelected()) {
            map.lengthType=false;
        }
        
        return map;
        
    }
    
    
    HintsCrate getHintsCrate() {
        return hintsCrate;
    }
    
    HintsCrate.Map getHintsMap() {
        return hintsMap;
    }

    private void initComponentsForVaryingValues() {
        jrbLengthVarying.setVisible(false);
        jrbExtractDataVarying.setVisible(false);
        updateSpinnerEditorTextField(jspSkipHead);
        updateSpinnerEditorTextField(jspSkipTail);
        updateSpinnerEditorTextField(jspLengthOffsetLow);
        updateSpinnerEditorTextField(jspLengthOffsetHigh);
    }
    
   static class HintSpinnerModel extends SpinnerListModel {
        
        private int currentValue;
        static final int DIFFERENT_VALUES=-1;
        static final String DIFFERENT_VALUES_STRING="<Different values>";
        
        
        private final int minValue;
        private final int maxValue;

        private HintSpinnerModel(int min, int max) {
            super();
            minValue=min;
            maxValue=max;
            
        }
        
        public Object getValue() {
            
            if (currentValue==DIFFERENT_VALUES) {
                return DIFFERENT_VALUES_STRING;
            }
            else {
                return Integer.toString(currentValue);
            }
            
        }
        
        public void setValue(Object value) {
            currentValue = Integer.parseInt((String)value);
            fireStateChanged();
        }
        
        public Object getPreviousValue() {
            
            int retVal = currentValue;
            
            if (currentValue==DIFFERENT_VALUES) {
                retVal = minValue;
            }
            if (currentValue>minValue) {
                retVal--;
            }
            return Integer.toString(retVal);
            
        }
        public Object getNextValue() {
            
            int retVal = currentValue;
            
            if (currentValue==DIFFERENT_VALUES) {
                retVal=minValue;
                return Integer.toString(retVal);
            }
            if (currentValue<maxValue) {
                retVal++;
            }
            return Integer.toString(retVal);
            
        }
        
        public Object findNextMatch(Object value) {
            return null;
        }
        
    }
   
    private void createSpinnerModels() {
        hspSkipHead = new HintSpinnerModel(0,65536);
        hspSkipTail = new HintSpinnerModel(0,65536);
        hspLengthOffsetLow = new HintSpinnerModel(0,65535);
        hspLengthOffsetHigh = new HintSpinnerModel(0,65535);
    }
    
    private void updateSpinnerEditorTextField(JSpinner s) {
        JTextField tf = ((DefaultEditor)(s.getEditor())).getTextField();
        tf.setColumns(HintSpinnerModel.DIFFERENT_VALUES_STRING.length());
    }
    
    
}
