/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.gui.panel;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.WindowConstants;

import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.gui.grid.JaxoPaintableGrid;
import net.sf.jaxodraw.gui.panel.button.JaxoColorButton;
import net.sf.jaxodraw.gui.panel.edit.JaxoOptionsPanel;
import net.sf.jaxodraw.gui.swing.JaxoFontStyleRenderer;
import net.sf.jaxodraw.gui.swing.JaxoTitledBorder;
import net.sf.jaxodraw.gui.swing.spinner.JaxoFixedJSpinner;
import net.sf.jaxodraw.gui.swing.spinner.JaxoSpinnerComboBox;
import net.sf.jaxodraw.gui.swing.spinner.JaxoSpinnerIntModel;
import net.sf.jaxodraw.gui.swing.spinner.JaxoSpinnerRotationModel;
import net.sf.jaxodraw.object.text.JaxoPSText;
import net.sf.jaxodraw.util.JaxoPrefs;
import net.sf.jaxodraw.util.JaxoColor;
import net.sf.jaxodraw.util.JaxoConstants;
import net.sf.jaxodraw.util.JaxoInfo;
import net.sf.jaxodraw.util.JaxoLanguage;



/** Responsible for editing user preferences.
 * @since 2.0
 */
public final class JaxoPrefsPanel extends JDialog implements ItemListener {
    private static final long serialVersionUID = 7526471155622776147L;

    /** The available system fonts. */
    private static final List<String> SYSTEM_FONTS =
        Collections.unmodifiableList(Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment()
                                                                      .getAvailableFontFamilyNames()));

/////////////////////////////////////////////////////////////////////
    private List<String> knownLanguages;
    private String[] gridTypes;
    private final Dimension screenSize = JaxoInfo.SCREEN_SIZE;

    // General
    private JTextField htmlTextField;
    private JTextField editorTextField;
    private JTextField psTextField;
    private JTextField latexPathTextField;
    private JTextField dvipsPathTextField;

    // Appearance
    private JaxoLookAndFeelPanel lookAndFeelPanel;
    private JComboBox chooseLanguage;
    private SpinnerNumberModel modelXin;
    private SpinnerNumberModel modelYin;
    private JCheckBox splashCheckBox;
    private JCheckBox toolBarCheckBox;
    private JCheckBox gridBarCheckBox;
    private JCheckBox statusBarCheckBox;
    private JCheckBox antialiasCheckBox;

    // Grid
    private JCheckBox gridCheckBox;
    private JCheckBox snapCheckBox;
    private JComboBox chooseGridType;
    private JComboBox chooseGridStyle;
    private JaxoColorButton gridColorButton;
    private JaxoColorButton canvasBackgroundButton;
    private JaxoSpinnerIntModel modelgrid;

    // Objects
    private JaxoColorButton colorButton;
    private SpinnerNumberModel modelwidth;
    private JCheckBox arrowCheckBox;
    private SpinnerNumberModel modelsep;
    private SpinnerNumberModel modelvert;
    private SpinnerNumberModel modelamp;

    // Arrows
    private JSpinner arsppos;
    private JSpinner arsplength;
    private JSpinner arspwidth;
    private JSpinner arspinset;
    private JCheckBox arlockcb;
    private SpinnerNumberModel modelArPosition;
    private SpinnerNumberModel modelArLength;
    private SpinnerNumberModel modelArWidth;
    private SpinnerNumberModel modelArInset;
    private float arlwRatio;
    private boolean aradjusting;

    // Text
    private JaxoColorButton textColorButton;
    private JComboBox chooseTextFamily;
    private JSpinner chooseTextSize;
    private JComboBox chooseTextStyle;
    private JaxoSpinnerRotationModel modelTextRotation;
    private JaxoSpinnerRotationModel modelTeXRotation;
    private JComboBox chooseTeXAlignment;
    private JComboBox chooseTeXSize;

    // Misc
    private JComboBox chooseDefaultMode;
    private SpinnerNumberModel modelundo;
    private JComboBox chooseCSpaceType;
    private final JaxoColorChooser colorChooser;

    /**
     * Creates a new JaxoPrefsPanel dialog which is always modal.
     *
     * @param owner the Frame from which the dialog is displayed.
     */
    public JaxoPrefsPanel(final Frame owner) {
        super(owner, true);

        setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        setKnownLanguages();
        setGridTypes();

        colorChooser = new JaxoColorChooser(this);
        colorChooser.setPermanent(true);

        // General tab
        final JPanel fPreview = getFPreviewPanel();

        // Appearance tab
        final JPanel fAppearance = getFAppearancePanel();

        // Behavior tab
        final JTabbedPane fBehaviorPanel = new JTabbedPane();
        fBehaviorPanel.setTabPlacement(fBehaviorPanel.getComponentOrientation()
                                                     .isLeftToRight()
            ? JTabbedPane.LEFT : JTabbedPane.RIGHT);
        //fBehaviorPanel.add(JaxoLanguage.translate("Default"), getBDefCont());
        //fBehaviorPanel.add(JaxoLanguage.translate("Undo_depth"),
        //    getBDepthCont());
        fBehaviorPanel.add(JaxoLanguage.translate("JaxoPrefsPanel.gridTab"),
            getBGridCont());
        fBehaviorPanel.add(JaxoLanguage.translate("JaxoPrefsPanel.objectTab"),
            getBObjectCont());
        fBehaviorPanel.add(JaxoLanguage.translate("JaxoPrefsPanel.textTab"),
            getBTextCont());
        fBehaviorPanel.add(JaxoLanguage.translate("JaxoPrefsPanel.miscTab"),
            getBMiscCont());

        // Main window
        final JTabbedPane jtb = new JTabbedPane();
        jtb.add(JaxoLanguage.translate("JaxoPrefsPanel.generalTab"), fPreview);
        jtb.add(JaxoLanguage.translate("JaxoPrefsPanel.appearanceTab"),
            fAppearance);
        jtb.add(JaxoLanguage.translate("JaxoPrefsPanel.behaviorTab"),
            fBehaviorPanel);

        this.setTitle(JaxoDialogs.windowTitle("JaxoPrefsPanel.title"));
        this.getContentPane().add(jtb, BorderLayout.CENTER);
        this.getContentPane().add(createOptionContainer(),
            BorderLayout.PAGE_END);

        this.pack();
        this.setLocationRelativeTo(getOwner());
    }

    /** The available system fonts as an immutable List of Strings.
     * @return The available system fonts.
     */
    public static List<String> getSystemFonts() {
        return SYSTEM_FONTS;
    }

    /** Set shown values from preferences. */
    public void setFromPrefs() {
        psTextField.setText(JaxoPrefs.getStringPref(JaxoPrefs.PREF_PSVIEWER));
        htmlTextField.setText(JaxoPrefs.getStringPref(JaxoPrefs.PREF_BROWSER));
        editorTextField.setText(JaxoPrefs.getStringPref(JaxoPrefs.PREF_EDITOR));
        latexPathTextField.setText(JaxoPrefs.getStringPref(
                JaxoPrefs.PREF_LATEXPATH));
        dvipsPathTextField.setText(JaxoPrefs.getStringPref(
                JaxoPrefs.PREF_DVIPSPATH));

        lookAndFeelPanel.setValue(JaxoPrefs.getStringPref(
                JaxoPrefs.PREF_LOOKNFEEL));

        // language
        int selected = 0;

        for (int i = 0; i < knownLanguages.size(); i++) {
            if (knownLanguages.get(i).equals(JaxoPrefs.getStringPref(
                            JaxoPrefs.PREF_LANGUAGE))) {
                selected = i;
            }
        }

        chooseLanguage.setSelectedIndex(selected);

        // grid type
        int selectedg = 0;

        for (int i = 0; i < gridTypes.length; i++) {
            if (gridTypes[i].equals(JaxoPrefs.getStringPref(
                            JaxoPrefs.PREF_GRIDTYPE))) {
                selectedg = i;
            }
        }

        chooseCSpaceType.setSelectedIndex(JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_COLORSPACE) - 1);

        splashCheckBox.setSelected(JaxoPrefs.getBooleanPref(
                JaxoPrefs.PREF_SHOWSPLASHWINDOW));

        gridCheckBox.setSelected(JaxoPrefs.getBooleanPref(
                JaxoPrefs.PREF_GRIDONOFF));
        snapCheckBox.setSelected(JaxoPrefs.getBooleanPref(
                JaxoPrefs.PREF_SNAPONOFF));
        chooseGridType.setSelectedIndex(selectedg);
        chooseGridStyle.setSelectedIndex(JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_GRIDSTYLE));

        // color
        colorButton.setColor(JaxoColor.getColor(JaxoPrefs.getStringPref(
                    JaxoPrefs.PREF_COLOR),
                JaxoPrefs.getIntPref(JaxoPrefs.PREF_COLORSPACE)));
        textColorButton.setColor(JaxoColor.getColor(JaxoPrefs.getStringPref(
                    JaxoPrefs.PREF_TEXTCOLOR),
                JaxoPrefs.getIntPref(JaxoPrefs.PREF_COLORSPACE)));
        gridColorButton.setColor(JaxoColor.getColor(JaxoPrefs.getStringPref(
                    JaxoPrefs.PREF_GRIDCOLOR), JaxoColor.ALL_COLORS_MODE));
        canvasBackgroundButton.setColor(JaxoColor.getColor(JaxoPrefs.getStringPref(
                    JaxoPrefs.PREF_CANVASBACKGROUND), JaxoColor.ALL_COLORS_MODE));

        // PS font
        final int fontIndex =
            SYSTEM_FONTS.indexOf(JaxoPrefs.getStringPref(
                    JaxoPrefs.PREF_PSFAMILY));
        chooseTextFamily.setSelectedIndex((fontIndex == -1) ? 0 : fontIndex);
        chooseTextStyle.setSelectedItem(Integer.valueOf(JaxoPrefs.getIntPref(
                    JaxoPrefs.PREF_PSSTYLE)));
        chooseTextSize.setValue(Integer.valueOf(JaxoPrefs.getIntPref(
                    JaxoPrefs.PREF_PSSIZE)));

        // TeX alignment/size
        chooseTeXAlignment.setSelectedIndex(JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_TEXALIGN));
        chooseTeXSize.setSelectedIndex(JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_TEXSIZE));

        modelTextRotation.setRotationValue(-JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_PSROTANGLE));
        modelTeXRotation.setRotationValue(-JaxoPrefs.getIntPref(
                JaxoPrefs.PREF_TEXROTANGLE));

        // Default action
        setDefIndex(JaxoPrefs.getIntPref(JaxoPrefs.PREF_DEFAULTACTION));

        final float prefLINEWIDTH = JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH);

        final int prefAMPLITUDE = JaxoPrefs.getIntPref(JaxoPrefs.PREF_AMPLITUDE);
        final float prefDLSEP = JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP);
        final int prefVERTEXSIZE = JaxoPrefs.getIntPref(JaxoPrefs.PREF_VERTEXSIZE);
        final boolean prefSHOWTOOL =
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_SHOWTOOL);
        final boolean prefSHOWSTATUS =
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_SHOWSTATUS);
        final boolean prefSHOWGRIDBAR =
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_SHOWGRIDBAR);
        final boolean prefANTIALIASON =
            JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_ANTIALIAS);
        final boolean prefARROW = JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_ARROW);

        //boolean prefGRIDONOFF =
        //    JaxoPrefs.getBooleanPref(JaxoPrefs.PREF_GRIDONOFF);
        modelgrid.setIntValue(JaxoPrefs.getIntPref(JaxoPrefs.PREF_GRIDSIZE));
        modelwidth.setValue(Double.valueOf(prefLINEWIDTH));

        modelamp.setValue(Integer.valueOf(prefAMPLITUDE));
        modelXin.setValue(Integer.valueOf(JaxoPrefs.getIntPref(
                    JaxoPrefs.PREF_SCREENSIZEX)));
        modelYin.setValue(Integer.valueOf(JaxoPrefs.getIntPref(
                    JaxoPrefs.PREF_SCREENSIZEY)));
        modelsep.setValue(Double.valueOf(prefDLSEP));
        modelvert.setValue(Integer.valueOf(prefVERTEXSIZE));

        modelundo.setValue(Integer.valueOf(JaxoPrefs.getIntPref(
                    JaxoPrefs.PREF_UNDODEPTH)));

        toolBarCheckBox.setSelected(prefSHOWTOOL);
        statusBarCheckBox.setSelected(prefSHOWSTATUS);
        gridBarCheckBox.setSelected(prefSHOWGRIDBAR);
        antialiasCheckBox.setSelected(prefANTIALIASON);
        arrowCheckBox.setSelected(prefARROW);

        arsppos.setValue(Float.valueOf(JaxoPrefs.getFloatPref(
                JaxoPrefs.PREF_ARROWPOSITION)));
        arsplength.setValue(Float.valueOf(JaxoPrefs.getFloatPref(
                JaxoPrefs.PREF_ARROWLENGTH)));
        arspwidth.setValue(Float.valueOf(JaxoPrefs.getFloatPref(
                JaxoPrefs.PREF_ARROWWIDTH)));
        arspinset.setValue(Float.valueOf(JaxoPrefs.getFloatPref(
                JaxoPrefs.PREF_ARROWINSET)));
    }

    /** {@inheritDoc}
     *  Currently handles color space changes and grid type changes.
     *
     * @param e the ItemEvent.
     */
    public void itemStateChanged(final ItemEvent e) {
        if (e.getStateChange() != ItemEvent.SELECTED) {
            return;
        }

        final Object source = e.getSource();

        if (source.equals(chooseCSpaceType)) {
            colorButton.setChooserMode(chooseCSpaceType.getSelectedIndex() + 1);
            textColorButton.setChooserMode(chooseCSpaceType.getSelectedIndex()
                + 1);
        } else if (source.equals(chooseGridType)) {
            if (chooseGridType.getSelectedItem().equals(JaxoLanguage.translate(
                            "Rectangular"))) {
                if (chooseGridStyle.getItemCount() == (
                            JaxoPaintableGrid.STYLE_LINE_HONEYCOMB + 1
                        )) {
                    chooseGridStyle.removeItemAt(JaxoPaintableGrid.STYLE_LINE_HONEYCOMB);
                }
                modelgrid.setIntStepSize(1);
            } else {
                if (chooseGridStyle.getItemCount() < (
                            JaxoPaintableGrid.STYLE_LINE_HONEYCOMB + 1
                        )) {
                    chooseGridStyle.insertItemAt(JaxoLanguage.translate(
                            "Honeycomb"), JaxoPaintableGrid.STYLE_LINE_HONEYCOMB);
                }
                modelgrid.setIntStepSize(2);
            }
        }
    }

      //
     // private
    //

    private void clearButtonClicked() {
        psTextField.setText("");
        htmlTextField.setText("");
        editorTextField.setText("");
        latexPathTextField.setText("");
        dvipsPathTextField.setText("");
    }

    private void saveButtonClicked() {
        // temporarily save the current settings in case a user
        // wants to save the preferences without applying them

        final Map<String, Object> state = JaxoPrefs.getState();
        pushPrefs();
        JaxoPrefs.savePrefs();
        JaxoPrefs.setState(state);
    }

    private void okButtonClicked() {
        pushPrefs();
        setVisible(false);
    }

    private void cancelButtonClicked() {
        setVisible(false);
    }

    private void resetButtonClicked() {
        setFromPrefs();
    }

    private void setDefIndex(final int defaultMode) {
        int i = 0;
        if (JaxoConstants.isDefaultMode(defaultMode)) {
            i = getDefIndex(defaultMode);
        }
        chooseDefaultMode.setSelectedIndex(i);
    }

    private int getDefIndex(final int value) {
        final int nofDefaults = JaxoConstants.defaultModes().length;
        int j = nofDefaults + 1;

        for (int jj = 0; jj < nofDefaults; jj++) {
            if (value == JaxoConstants.defaultModes()[jj]) {
                j = jj;
                break;
            }
        }

        return j;
    }

    /**
     * Pushes the preferences indicated in this dialog to JaxoPrefs,
     * so they become valid for the current session.
     */
    private void pushPrefs() {
        final int screenSizeX = modelXin.getNumber().intValue();
        final int screenSizeY = modelYin.getNumber().intValue();
        final float lineWidth = modelwidth.getNumber().floatValue();
        final float dlSep = modelsep.getNumber().floatValue();
        final float arrowPosition = modelArPosition.getNumber().floatValue();
        final float arrowLength = modelArLength.getNumber().floatValue();
        final float arrowWidth = modelArWidth.getNumber().floatValue();
        final float arrowInset = modelArInset.getNumber().floatValue();
        final int vertexSize = modelvert.getNumber().intValue();
        final int amp = modelamp.getNumber().intValue();
        final String lang =
            knownLanguages.get(chooseLanguage.getSelectedIndex());
        final String gridType = gridTypes[chooseGridType.getSelectedIndex()];

        final String col =
            JaxoColor.getColorName(colorButton.getColor(),
                chooseCSpaceType.getSelectedIndex() + 1);
        final String colT =
            JaxoColor.getColorName(textColorButton.getColor(),
                chooseCSpaceType.getSelectedIndex() + 1);
        final String colG =
            JaxoColor.getColorName(gridColorButton.getColor(),
                JaxoColor.ALL_COLORS_MODE);

        JaxoPrefs.setStringPref(JaxoPrefs.PREF_BROWSER, htmlTextField.getText());
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_EDITOR,
            editorTextField.getText());
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_PSVIEWER, psTextField.getText());

        JaxoPrefs.setStringPref(JaxoPrefs.PREF_LOOKNFEEL,
            lookAndFeelPanel.getValue());

        JaxoPrefs.setStringPref(JaxoPrefs.PREF_CANVASBACKGROUND,
            JaxoColor.getColorName(canvasBackgroundButton.getColor(),
            JaxoColor.ALL_COLORS_MODE));
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_GRIDTYPE, gridType);
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_COLORSPACE,
            chooseCSpaceType.getSelectedIndex() + 1);
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_COLOR, col);
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_PSFAMILY,
            (String) chooseTextFamily.getSelectedItem());
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_TEXTCOLOR, colT);
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_LATEXPATH,
            latexPathTextField.getText());
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_DVIPSPATH,
            dvipsPathTextField.getText());
        JaxoPrefs.setStringPref(JaxoPrefs.PREF_GRIDCOLOR, colG);

        JaxoPrefs.setIntPref(JaxoPrefs.PREF_SCREENSIZEX, screenSizeX);
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_SCREENSIZEY, screenSizeY);
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_GRIDSIZE, modelgrid.getIntValue());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_GRIDSTYLE,
            chooseGridStyle.getSelectedIndex());

        JaxoPrefs.setIntPref(JaxoPrefs.PREF_AMPLITUDE, amp);
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_PSSTYLE,
            ((Integer) chooseTextStyle.getSelectedItem()).intValue());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_PSSIZE,
            ((Integer) chooseTextSize.getValue()).intValue());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_TEXSIZE,
            chooseTeXSize.getSelectedIndex());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_TEXALIGN,
            chooseTeXAlignment.getSelectedIndex());

        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_LINEWIDTH, lineWidth);
        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_DLSEP, dlSep);

        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_ARROWPOSITION, arrowPosition);
        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_ARROWLENGTH, arrowLength);
        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_ARROWWIDTH, arrowWidth);
        JaxoPrefs.setFloatPref(JaxoPrefs.PREF_ARROWINSET, arrowInset);

        JaxoPrefs.setIntPref(JaxoPrefs.PREF_VERTEXSIZE, vertexSize);
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_PSROTANGLE,
            modelTextRotation.getRotationValue());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_TEXROTANGLE,
            modelTeXRotation.getRotationValue());
        JaxoPrefs.setIntPref(JaxoPrefs.PREF_UNDODEPTH,
            modelundo.getNumber().intValue());

        JaxoPrefs.setStringPref(JaxoPrefs.PREF_LANGUAGE, lang);
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_SHOWTOOL, toolBarCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_SHOWSTATUS, statusBarCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_SHOWGRIDBAR, gridBarCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_ANTIALIAS, antialiasCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_ARROW, arrowCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_GRIDONOFF, gridCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_SNAPONOFF, snapCheckBox.isSelected());
        JaxoPrefs.setBooleanPref(JaxoPrefs.PREF_SHOWSPLASHWINDOW, splashCheckBox.isSelected());

        JaxoPrefs.setIntPref(JaxoPrefs.PREF_DEFAULTACTION,
            JaxoConstants.defaultModes()[chooseDefaultMode.getSelectedIndex()]);
    }

    private JPanel createOptionContainer() {
        final JButton okBt =
            new JButton(JaxoLanguage.translate("JaxoPrefsPanel.buttons.OK"));
        okBt.setToolTipText(JaxoLanguage.translate(
                "JaxoPrefsPanel.buttons.OK.toolTip"));
        okBt.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent evt) {
                    okButtonClicked();
                }
            });

        this.getRootPane().setDefaultButton(okBt);

        final JButton saveBt =
            new JButton(JaxoLanguage.translate("JaxoPrefsPanel.buttons.save"));
        saveBt.setToolTipText(JaxoLanguage.translate(
                "JaxoPrefsPanel.buttons.save.toolTip"));
        saveBt.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent evt) {
                    saveButtonClicked();
                }
            });

        final JButton resetBt =
            new JButton(JaxoLanguage.translate("JaxoPrefsPanel.buttons.reset"));
        resetBt.setToolTipText(JaxoLanguage.translate(
                "JaxoPrefsPanel.buttons.reset.toolTip"));
        resetBt.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent evt) {
                    resetButtonClicked();
                }
            });

        final JButton cancelBt =
            new JButton(JaxoLanguage.translate("JaxoPrefsPanel.buttons.cancel"));
        cancelBt.setToolTipText(JaxoLanguage.translate(
                "JaxoPrefsPanel.buttons.cancel.toolTip"));
        cancelBt.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent evt) {
                    cancelButtonClicked();
                }
            });

        final JPanel btPanel = new JPanel(new GridBagLayout(), false);

        final GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(5, 5, 5, 5);
        c.gridy = 0;
        btPanel.add(saveBt, c);
        c.weightx = 1;
        btPanel.add(Box.createHorizontalGlue(), c);
        c.weightx = 0;
        btPanel.add(okBt, c);
        btPanel.add(resetBt, c);
        btPanel.add(cancelBt, c);

        return btPanel;
    }

    private JPanel getLanguagePanel() {
        final String[] i18nKnownLanguages =
        {
            JaxoLanguage.translate("JaxoLanguage.english"),
            JaxoLanguage.translate("JaxoLanguage.german"),
            JaxoLanguage.translate("JaxoLanguage.french"),
            JaxoLanguage.translate("JaxoLanguage.spanish"),
            JaxoLanguage.translate("JaxoLanguage.italian")
        };

        chooseLanguage = new JComboBox(i18nKnownLanguages);

        final JPanel languagePanel =
            JaxoDialogs.newTitledFlowLayoutPanel("JaxoPrefsPanel.language.title");

        final JLabel languageLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.language"));
        languagePanel.add(languageLabel);
        languagePanel.add(chooseLanguage);

        return languagePanel;
    }

    private void setKnownLanguages() {
        knownLanguages = new ArrayList<String>(Arrays.asList(JaxoLanguage.knownLanguages()));
    }

    private void setGridTypes() {
        gridTypes = new String[2];
        gridTypes[0] = "rectangular";
        gridTypes[1] = "hexagonal";
    }

    private JPanel getLookNFeelPanel() {
        final JPanel lookNFeelPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Look_and_Feel");

        lookAndFeelPanel = new JaxoLookAndFeelPanel();

        lookNFeelPanel.add(lookAndFeelPanel.getRoot());

        return lookNFeelPanel;
    }

    private JPanel getLafPanel() {
        final JPanel lafPanel = new JPanel(false);
        lafPanel.add(getLookNFeelPanel());
        lafPanel.add(getLanguagePanel());

        return lafPanel;
    }

    private JPanel getFAppearancePanel() {
        final JPanel fAppearancePanel = JaxoDialogs.newPageBoxLayoutPanel();

        fAppearancePanel.add(getLafPanel());
        fAppearancePanel.add(getStartUpPanel());
        fAppearancePanel.add(getCheckBoxPanel());

        return fAppearancePanel;
    }

    private JPanel getCheckBoxPanel() {
        final JPanel checkBoxPanel =
            JaxoDialogs.newTitledLayoutPanel("Other_options",
                new GridLayout(2, 2));

        toolBarCheckBox =
            new JCheckBox(JaxoLanguage.translate("Show_toolbar"));
        checkBoxPanel.add(toolBarCheckBox);

        statusBarCheckBox =
            new JCheckBox(JaxoLanguage.translate("Show_status_bar"));
        checkBoxPanel.add(statusBarCheckBox);

        gridBarCheckBox =
            new JCheckBox(JaxoLanguage.translate("Show_Gridbar"));
        checkBoxPanel.add(gridBarCheckBox);

        antialiasCheckBox =
            new JCheckBox(JaxoLanguage.translate("Antialias_on"));
        checkBoxPanel.add(antialiasCheckBox);

        return checkBoxPanel;
    }

    private JPanel getStartUpPanel() {
        final JPanel gridPanel = new JPanel(false);
        gridPanel.add(getSplashWindowPanel());
        gridPanel.add(getInitScreenPanel());

        final JPanel bGrid = JaxoDialogs.newPageBoxLayoutPanel();

        bGrid.add(gridPanel);

        return bGrid;
    }

    private JPanel getInitScreenPanel() {
        // screenSize as maximum value is arbitrary choice
        final JPanel pxin = new JPanel(false);
        modelXin = new SpinnerNumberModel(0, 0, screenSize.width, 1);

        final JLabel xin =
            new JLabel(JaxoLanguage.label(
                    "JaxoPrefsPanel.canvas.preferredWidth"), JLabel.TRAILING);
        pxin.add(xin);

        final JSpinner spxin = new JaxoFixedJSpinner(modelXin);
        pxin.add(spxin);

        final JPanel pyin = new JPanel(false);

        modelYin = new SpinnerNumberModel(0, 0, screenSize.height, 1);

        final JLabel yin =
            new JLabel(JaxoLanguage.label(
                    "JaxoPrefsPanel.canvas.preferredHeight"), JLabel.TRAILING);
        pyin.add(yin);

        final JSpinner spyin = new JaxoFixedJSpinner(modelYin);
        pyin.add(spyin);

        final JPanel dimSPanel = new JPanel(new GridBagLayout());
        final GridBagConstraints sc = new GridBagConstraints();

        sc.gridx = 0;
        sc.gridy = 0;
        sc.insets = new Insets(0, 0, 5, 0);
        dimSPanel.add(pxin, sc);

        sc.gridx = 1;
        sc.gridy = 0;
        sc.insets = new Insets(0, 0, 5, 5);
        dimSPanel.add(pyin, sc);

        final JPanel initScreenPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Initial_screen_size");
        initScreenPanel.add(dimSPanel);

        return initScreenPanel;
    }

    private JPanel getPreviewPanel() {
        final JPanel previewPanel =
            JaxoDialogs.newTitledLayoutPanel("Preview_options",
                new GridBagLayout());

        final JLabel htmlLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.path.HTMLViewer"),
                JLabel.TRAILING);
        htmlTextField = new JTextField("", 25);

        final JLabel editorLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.path.textEditor"),
                JLabel.TRAILING);
        editorTextField = new JTextField("", 25);

        final JLabel psLabel =
            new JLabel(JaxoLanguage.label(
                    "JaxoPrefsPanel.path.postScriptViewer"), JLabel.TRAILING);
        psTextField = new JTextField("", 25);

        final GridBagConstraints con = new GridBagConstraints();

        con.gridx = 0;
        JaxoDialogs.newTitledFlowLayoutPanel("Look_and_Feel");

        lookAndFeelPanel = new JaxoLookAndFeelPanel();
        con.gridy = 0;
        con.fill = GridBagConstraints.HORIZONTAL;
        previewPanel.add(htmlLabel, con);

        con.gridx = 0;
        con.gridy = 1;
        previewPanel.add(editorLabel, con);

        con.gridx = 0;
        con.gridy = 2;
        previewPanel.add(psLabel, con);

        con.gridx = 1;
        con.gridy = 0;
        previewPanel.add(htmlTextField, con);

        con.gridx = 1;
        con.gridy = 1;
        previewPanel.add(editorTextField, con);

        con.gridx = 1;
        con.gridy = 2;
        previewPanel.add(psTextField, con);

        return previewPanel;
    }

    private JPanel getPathPanel() {
        final JPanel pathPanel =
            JaxoDialogs.newTitledLayoutPanel("Paths", new GridBagLayout());

        final JLabel latexPathLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.path.LaTeX"),
                JLabel.TRAILING);
        latexPathTextField = new JTextField("", 25);

        final JLabel dvipsPathLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.path.dvips"),
                JLabel.TRAILING);
        dvipsPathTextField = new JTextField("", 25);

        final GridBagConstraints con1 = new GridBagConstraints();

        con1.gridx = 0;
        con1.gridy = 0;
        con1.fill = GridBagConstraints.HORIZONTAL;
        pathPanel.add(latexPathLabel, con1);

        con1.gridx = 0;
        con1.gridy = 1;
        pathPanel.add(dvipsPathLabel, con1);

        con1.gridx = 1;
        con1.gridy = 0;
        pathPanel.add(latexPathTextField, con1);

        con1.gridx = 1;
        con1.gridy = 1;
        pathPanel.add(dvipsPathTextField, con1);

        return pathPanel;
    }

    private JPanel getFPreviewPanel() {
        final JPanel fPreviewPanel = JaxoDialogs.newPageBoxLayoutPanel();

        fPreviewPanel.add(getPreviewPanel());
        fPreviewPanel.add(getPathPanel());

        final JButton clearBt = new JButton(JaxoLanguage.translate("Clear"));
        clearBt.setAlignmentX(0.5f);
        clearBt.setToolTipText(JaxoLanguage.translate(
                "Clear_all_the_text_fields"));
        clearBt.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent evt) {
                    clearButtonClicked();
                }
            });

        fPreviewPanel.add(clearBt);

        return fPreviewPanel;
    }

    private JPanel getSplashWindowPanel() {
        final JPanel splashCheckBoxPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("JaxoPrefsPanel.splash_window");

        splashCheckBox = new JCheckBox(JaxoLanguage.translate("JaxoPrefsPanel.splash_on"));

        splashCheckBoxPanel.add(splashCheckBox);

        return splashCheckBoxPanel;
    }

    private JPanel getGridOnOffPanel() {
        final JPanel gridCheckBoxPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Grid_on_off");

        gridCheckBox = new JCheckBox(JaxoLanguage.translate("Grid_on"));

        gridCheckBoxPanel.add(gridCheckBox);

        return gridCheckBoxPanel;
    }

    private JPanel getSnapOnOffPanel() {
        final JPanel snapCheckBoxPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Snap_on_off");

        snapCheckBox = new JCheckBox(JaxoLanguage.translate("Snap_on"));

        snapCheckBoxPanel.add(snapCheckBox);

        return snapCheckBoxPanel;
    }

    private JPanel getGridTypePanel() {
        final String[] gridCombTypes =
        {
            JaxoLanguage.translate("Rectangular"),
            JaxoLanguage.translate("Hexagonal")
        };

        chooseGridType = new JComboBox(gridCombTypes);
        // Initial state is hexagonal
        chooseGridType.setSelectedIndex(1);

        chooseGridType.addItemListener(this);

        final JPanel gridTypePanel = JaxoDialogs.newTitledFlowLayoutPanel("Grid_type");

        final JLabel gridTypeLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.grid.type"));
        gridTypePanel.add(gridTypeLabel);
        gridTypePanel.add(chooseGridType);

        return gridTypePanel;
    }

    private JPanel getGridStylePanel() {
        final List<String> gridCombStyles = new ArrayList<String>(4);
        gridCombStyles.add(JaxoLanguage.translate("Dot"));
        gridCombStyles.add(JaxoLanguage.translate("Cross"));
        gridCombStyles.add(JaxoLanguage.translate("Line"));
        gridCombStyles.add(JaxoLanguage.translate("Honeycomb"));

        chooseGridStyle = new JComboBox(gridCombStyles.toArray());

        int width = -1;
        int widestIndex = -1;

        for (int i = 0; i < gridCombStyles.size(); i++) {
            chooseGridStyle.setPrototypeDisplayValue(gridCombStyles.get(i));
            final int currentWidth = chooseGridStyle.getPreferredSize().width;

            if (currentWidth > width) {
                width = currentWidth;
                widestIndex = i;
            }
        }

        chooseGridStyle.setPrototypeDisplayValue(gridCombStyles.get(
                widestIndex));

        final JPanel gridStylePanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Grid_style");

        final JLabel gridStyleLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.grid.style"));
        gridStylePanel.add(gridStyleLabel);
        gridStylePanel.add(chooseGridStyle);

        return gridStylePanel;
    }

    private JPanel getGridColorPanel() {
        final JPanel gridColorPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("Grid_color");
        gridColorButton = new JaxoColorButton();
        gridColorButton.setChooser(colorChooser);
        gridColorButton.setChooserMode(JaxoColor.ALL_COLORS_MODE);

        final JLabel gridColorLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.grid.color"),
                JLabel.TRAILING);

        gridColorPanel.add(gridColorLabel);
        gridColorPanel.add(gridColorButton);

        return gridColorPanel;
    }

    private JPanel getCanvasBackgroundPanel() {
        final JPanel canvasBackgroundPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("JaxoPrefsPanel.canvas.background.title");
        canvasBackgroundButton = new JaxoColorButton();
        canvasBackgroundButton.setChooser(colorChooser);
        canvasBackgroundButton.setChooserMode(JaxoColor.ALL_COLORS_MODE);

        final JLabel canvasBackgroundLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.canvas.background.label"),
                JLabel.TRAILING);

        canvasBackgroundPanel.add(canvasBackgroundLabel);
        canvasBackgroundPanel.add(canvasBackgroundButton);

        return canvasBackgroundPanel;
    }

    private JPanel getColorSpacePanel() {
        final String[] cspaceCombTypes =
        {
            JaxoLanguage.translate("JaxoPrefsPanel.colorSpace.type.colordvi"),
            JaxoLanguage.translate("JaxoPrefsPanel.colorSpace.type.full")
        };

        chooseCSpaceType = new JComboBox(cspaceCombTypes);

        chooseCSpaceType.addItemListener(this);

        final JPanel cspaceTypePanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.colorSpace.title");

        final JLabel cspaceTypeLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.colorSpace.type"));
        cspaceTypePanel.add(cspaceTypeLabel);
        cspaceTypePanel.add(chooseCSpaceType);

        return cspaceTypePanel;
    }

    private JPanel getGridSizePanel() {
        final JPanel pgrid = new JPanel();

        final JLabel lgrid =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.grid.size"),
                JLabel.TRAILING);
        pgrid.add(lgrid);

        modelgrid = new JaxoSpinnerIntModel(1, 76, 2, 0);

        final JSpinner spgrid = new JaxoFixedJSpinner(modelgrid);
        pgrid.add(new JaxoSpinnerComboBox(spgrid,
                JaxoGridBar.getGridSizeDefaults()));

        final JPanel gridSizePanel = JaxoDialogs.newTitledFlowLayoutPanel("Grid_size");
        gridSizePanel.add(pgrid);

        return gridSizePanel;
    }

    private JPanel getColorPanel() {
        colorButton = new JaxoColorButton();
        colorButton.setChooserMode(JaxoColor.JAXO_COLORS_NO_GRAYSCALES_MODE);
        colorButton.setChooser(colorChooser);

        final JPanel colorPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.line.color.title");
        colorPanel.add(colorButton);

        return colorPanel;
    }

    private JPanel getLineWidthPanel() {
        final JPanel pwidth = new JPanel(false);
        modelwidth = new SpinnerNumberModel(0.2, 0.2, 100.0, 0.1);

        final JLabel lwidth =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.line.width"),
                JLabel.TRAILING);
        pwidth.add(lwidth);

        final JSpinner spwidth = new JaxoFixedJSpinner(modelwidth);
        pwidth.add(spwidth);

        final JPanel lineWidthPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.line.width.title");
        lineWidthPanel.add(pwidth);

        return lineWidthPanel;
    }

    private JPanel getArrowPositionPanel() {
        final JPanel arPosPanel = new JPanel();
        final GridLayout layout = new GridLayout(0, 2);
        arPosPanel.setLayout(layout);

        final JLabel arjpos = new JLabel(JaxoLanguage.label("JaxoArrowPositionEditPanel.position"),
                JLabel.TRAILING);
        arPosPanel.add(arjpos);

        modelArPosition =
            new SpinnerNumberModel(Float.valueOf(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWPOSITION)),
                Float.valueOf(0.f), Float.valueOf(1.f), Float.valueOf(0.005f));

        this.arsppos = new JaxoFixedJSpinner(modelArPosition);
        arsppos.setName("sppos");
        arPosPanel.add(arsppos);

        final JPanel arrowPositionPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoArrowPositionEditPanel.title");
        arrowPositionPanel.add(arPosPanel);

        return arrowPositionPanel;
    }

    private JPanel getArrowOptionsPanel() {
        final float length = JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWLENGTH);
        final float width = JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWWIDTH);
        arlwRatio = length / width;
        arrowCheckBox = new JCheckBox(JaxoLanguage.translate("Arrows"));

        final JPanel arrowPanel = new JPanel(); //JaxoDialogs.newTitledFlowLayoutPanel("Arrows");
        final Dimension size = new Dimension(120, 20);

        final JPanel arplength = getArrowLengthPanel();
        final JPanel arpwidth = getArrowWidthPanel();
        final JPanel arpinset = getArrowInsetPanel();
        final JPanel arplockar = getLockArrowPanel();

        final GridBagLayout gb = new GridBagLayout();
        final GridBagConstraints sc = new GridBagConstraints();
        arrowPanel.setLayout(gb);

        sc.gridx = 0;
        sc.gridy = 1;
       // sc.gridheight = 3;
        arrowPanel.add(arrowCheckBox, sc);

        sc.gridx = 1;
        sc.gridy = 0;
        arplength.setPreferredSize(size);
        arrowPanel.add(arplength, sc);

        sc.gridx = 1;
        sc.gridy = 1;
        sc.insets = new Insets(5, 0, 5, 0);
        arpwidth.setPreferredSize(size);
        arrowPanel.add(arpwidth, sc);

        sc.gridx = 1;
        sc.gridy = 3;
        sc.insets = new Insets(0, 0, 5, 0);
        arpinset.setPreferredSize(size);
        arrowPanel.add(arpinset, sc);

        sc.gridx = 2;
        sc.gridy = 0;
        sc.gridheight = 2;
        sc.insets = new Insets(0, 10, 5, 0);
        arrowPanel.add(arplockar, sc);

        final TitledBorder arrowTitle =
            new JaxoTitledBorder(JaxoLanguage.translate("JaxoArrowOptionsEditPanel.title"));

        arrowPanel.setBorder(arrowTitle);
        return arrowPanel;
    }

    private JPanel getArrowLengthPanel() {
        final JPanel arplength = new JPanel();
        final GridLayout layout = new GridLayout(0, 2);
        arplength.setLayout(layout);

        final JLabel jarlength = new JLabel(JaxoLanguage.label("JaxoArrowOptionsEditPanel.length"),
                JLabel.TRAILING);
        arplength.add(jarlength);

        modelArLength =
            new SpinnerNumberModel(
                Float.valueOf(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWLENGTH)),
                Float.valueOf(0.f), null, Float.valueOf(1.f));

        this.arsplength = new JaxoFixedJSpinner(modelArLength);
        arsplength.setName("splen");
        arsplength.addChangeListener(new ChangeListener() {
                public void stateChanged(final ChangeEvent e) {
                    if (aradjusting) {
                        return;
                    }
                    if (arlockcb.isSelected()) {
                        aradjusting = true;
                        try {
                            final float len =
                                ((Number) arsplength.getValue()).floatValue();
                            arspwidth.setValue(Double.valueOf(len / arlwRatio));
                        } finally {
                            aradjusting = false;
                        }
                    }
                }
            });
        arplength.add(arsplength);

        return arplength;
    }

    private JPanel getArrowWidthPanel() {
        final JPanel arpwidth = new JPanel();
        final GridLayout layout = new GridLayout(0, 2);
        arpwidth.setLayout(layout);

        final JLabel arjwidth = new JLabel(JaxoLanguage.label("JaxoArrowOptionsEditPanel.width"),
                JLabel.TRAILING);
        arpwidth.add(arjwidth);

        modelArWidth =
            new SpinnerNumberModel(
                Float.valueOf(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWWIDTH)),
                Float.valueOf(0.f), null, Float.valueOf(1.f));

        this.arspwidth = new JaxoFixedJSpinner(modelArWidth);
        arspwidth.setName("spwid");
        arspwidth.addChangeListener(new ChangeListener() {
                public void stateChanged(final ChangeEvent e) {
                    if (aradjusting) {
                        return;
                    }
                    if (arlockcb.isSelected()) {
                        aradjusting = true;
                        try {
                            final float wid =
                                ((Number) arspwidth.getValue()).floatValue();
                            final float len = arlwRatio * wid;
                            arsplength.setValue(Double.valueOf(len));
                        } finally {
                            aradjusting = false;
                        }
                    }
                }
            });
        arpwidth.add(arspwidth);

        return arpwidth;
    }

    private JPanel getArrowInsetPanel() {
        final JPanel arpinset = new JPanel();
        final GridLayout layout = new GridLayout(0, 2);
        arpinset.setLayout(layout);

        final JLabel arjinset = new JLabel(JaxoLanguage.label("JaxoArrowOptionsEditPanel.inset"),
                JLabel.TRAILING);
        arpinset.add(arjinset);

        modelArInset =
            new SpinnerNumberModel(Float.valueOf(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_ARROWINSET)),
                Float.valueOf(0.f), Float.valueOf(1.f), Float.valueOf(0.05f));

        this.arspinset = new JaxoFixedJSpinner(modelArInset);
        arspinset.setName("spinset");
        arpinset.add(arspinset);

        return arpinset;
    }

    private JPanel getLockArrowPanel() {
        final JPanel arplockar = new JPanel();
        final GridLayout layout = new GridLayout(0, 2);
        arplockar.setLayout(layout);

        arlockcb =
            new JCheckBox(JaxoLanguage.translate("JaxoArrowOptionsEditPanel.lockar"));
        arlockcb.setName("lockar");
        arlockcb.setEnabled(true);
        arlockcb.setSelected(true);
        arlockcb.addItemListener(new ItemListener() {
                public void itemStateChanged(final ItemEvent e) {
                    if (arlockcb.isSelected()) {
                        final float len =
                            ((Number) arsplength.getValue()).floatValue();
                        final float wid = ((Number) arspwidth.getValue()).floatValue();
                        arlwRatio = len / wid;
                    }
                }
            });
        arplockar.add(arlockcb);

        return arplockar;
    }

    private JPanel getSepPanel() {
        final JPanel psep = new JPanel(false);
        modelsep = new SpinnerNumberModel(0.2, 0.2, 100.0, 0.5);

        final JLabel lsep =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.line.separation"),
                JLabel.TRAILING);
        psep.add(lsep);

        final JSpinner spsep = new JaxoFixedJSpinner(modelsep);
        psep.add(spsep);

        final JPanel sepPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.line.separation.title");
        sepPanel.add(psep);

        return sepPanel;
    }

    private JPanel getDefVertexPanel() {
        modelvert = new SpinnerNumberModel(0, 0, 50, 1);

        final JPanel vert = new JPanel(false);
        vert.add(new JLabel(JaxoLanguage.label("JaxoPrefsPanel.vertex.size"),
                JLabel.TRAILING));
        vert.add(new JaxoFixedJSpinner(modelvert));

        final JPanel vertexSizePanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.vertex.size.title");
        vertexSizePanel.add(vert);

        return vertexSizePanel;
    }

    private JPanel getAmpPanel() {
        final JPanel pamp = new JPanel(false);
        modelamp = new SpinnerNumberModel(0, -500, 500, 1);

        final JLabel lamp =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.line.amplitude"),
                JLabel.TRAILING);
        pamp.add(lamp);

        final JSpinner spamp = new JaxoFixedJSpinner(modelamp);
        pamp.add(spamp);

        final JPanel ampPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.line.amplitude.title");
        ampPanel.add(pamp);

        return ampPanel;
    }

    private JPanel getColorTPanel() {
        textColorButton = new JaxoColorButton();

        textColorButton.setChooser(colorChooser);
        textColorButton.setChooserMode(
            JaxoColor.JAXO_COLORS_NO_GRAYSCALES_MODE);

        final JPanel colorTPanel = JaxoDialogs.newTitledFlowLayoutPanel("Text_color");

        colorTPanel.add(textColorButton);

        return colorTPanel;
    }

    private JPanel getTextFinalFontPanel() {
        final JPanel textFamilyPanel = new JPanel(false);
        final JLabel textFamilyLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.font.family"),
                JLabel.TRAILING);
        chooseTextFamily = new JComboBox(SYSTEM_FONTS.toArray());
        textFamilyPanel.add(textFamilyLabel);
        textFamilyPanel.add(chooseTextFamily);


        final JPanel textSizePanel = new JPanel(false);
        final JLabel textSizeLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.font.size"),
                JLabel.TRAILING);
        chooseTextSize =
            new JaxoFixedJSpinner(new SpinnerNumberModel(1, 1, 300, 1));
        textSizePanel.add(textSizeLabel);
        textSizePanel.add(new JaxoSpinnerComboBox(chooseTextSize,
                JaxoPSText.getFontSizeDefaults()));


        final JPanel textStylePanel = new JPanel(false);
        final JLabel textStyleLabel =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.font.style"),
                JLabel.TRAILING);
        chooseTextStyle =
            new JComboBox(JaxoPSText.getFontStyles().toArray());
        chooseTextStyle.setRenderer(new JaxoFontStyleRenderer());
        textStylePanel.add(textStyleLabel);
        textStylePanel.add(chooseTextStyle);

        final JPanel textFinalFontPanel =
            JaxoDialogs.newTitledBorderLayoutPanel("JaxoPrefsPanel.font.title");

        textFinalFontPanel.add(BorderLayout.LINE_START, textFamilyPanel);
        textFinalFontPanel.add(BorderLayout.CENTER, textSizePanel);
        textFinalFontPanel.add(BorderLayout.LINE_END, textStylePanel);

        return textFinalFontPanel;
    }

    private JPanel getFinalRotSPanel() {
        final JPanel result =
            JaxoDialogs.newTitledLayoutPanel("Rotation", new GridBagLayout());

        modelTextRotation = new JaxoSpinnerRotationModel();

        final JLabel psLabel =
            new JLabel(JaxoLanguage.label(
                    "JaxoPrefsPanel.font.postScript.rotationAngle"),
                JLabel.TRAILING);

        final GridBagConstraints c = new GridBagConstraints();

        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 5, 2, 0);
        result.add(psLabel, c);

        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(5, 0, 2, 5);
        result.add(new JaxoSpinnerComboBox(modelTextRotation.newSpinner(),
                JaxoOptionsPanel.getRotationAngleDefaults()), c);

        modelTeXRotation = new JaxoSpinnerRotationModel();

        final JLabel texLabel =
            new JLabel(JaxoLanguage.label(
                    "JaxoPrefsPanel.font.TeX.rotationAngle"), JLabel.TRAILING);

        c.gridx = 0;
        c.gridy = 1;
        c.insets = new Insets(2, 5, 5, 0);
        result.add(texLabel, c);

        c.gridx = 1;
        c.gridy = 1;
        c.insets = new Insets(2, 0, 5, 5);
        result.add(new JaxoSpinnerComboBox(modelTeXRotation.newSpinner(),
                JaxoOptionsPanel.getRotationAngleDefaults()), c);

        return result;
    }

    private JPanel getAlignmentPanel() {
        final String[] possible =
        {
            JaxoLanguage.translate("Left-Top"),
            JaxoLanguage.translate("Left-Center"),
            JaxoLanguage.translate("Left-Bottom"),
            JaxoLanguage.translate("Center-Top"),
            JaxoLanguage.translate("Center-Center"),
            JaxoLanguage.translate("Center-Bottom"),
            JaxoLanguage.translate("Right-Top"),
            JaxoLanguage.translate("Right-Center"),
            JaxoLanguage.translate("Right-Bottom")
        };
        chooseTeXAlignment = new JComboBox(possible);

        final JPanel alignmentPanel =
            JaxoDialogs.newTitledFlowLayoutPanel("TeX_alignment");

        alignmentPanel.add(chooseTeXAlignment);

        return alignmentPanel;
    }

    private JPanel getFsPanel() {
        final String[] allowed =
        {
            "tiny", "scriptsize", "footnotesize", "small", "normalsize",
            "large", "Large", "LARGE", "huge", "Huge"
        };

        chooseTeXSize = new JComboBox(allowed);

        final JPanel fsPanel = JaxoDialogs.newTitledFlowLayoutPanel("TeX_font_size");

        fsPanel.add(chooseTeXSize);

        return fsPanel;
    }

    private JPanel getBGridCont() {
        final JPanel gridPanel = new JPanel(false);
        gridPanel.add(getGridOnOffPanel());
        gridPanel.add(getGridSizePanel());
        gridPanel.add(getSnapOnOffPanel());

        final JPanel gridPanel1 = new JPanel(false);

        gridPanel1.add(getGridTypePanel());
        gridPanel1.add(getGridStylePanel());
        gridPanel1.add(getGridColorPanel());
        gridPanel1.add(getCanvasBackgroundPanel());

        final JPanel bGrid = JaxoDialogs.newPageBoxLayoutPanel();

        bGrid.add(gridPanel);
        bGrid.add(gridPanel1);

        return bGrid;
    }

    private JPanel getBObjectCont() {
        final JPanel objectPanel = new JPanel(false);
        objectPanel.add(getColorPanel());
        objectPanel.add(getLineWidthPanel());
        objectPanel.add(getSepPanel());

        final JPanel objectPanel1 = new JPanel(false);
        objectPanel1.add(getArrowPositionPanel());
        objectPanel1.add(getArrowOptionsPanel());

        final JPanel objectPanel2 = new JPanel(false);
        objectPanel2.add(getDefVertexPanel());
        objectPanel2.add(getAmpPanel());

        final JPanel bObject = JaxoDialogs.newPageBoxLayoutPanel();

        bObject.add(objectPanel);
        bObject.add(objectPanel1);
        bObject.add(objectPanel2);

        return bObject;
    }

    private JPanel getBTextCont() {
        final JPanel textPanel = new JPanel(false);
        textPanel.add(getColorTPanel());
        textPanel.add(getTextFinalFontPanel());

        final JPanel textPanel1 = new JPanel();
        textPanel1.add(getFinalRotSPanel());
        textPanel1.add(getAlignmentPanel());
        textPanel1.add(getFsPanel());

        final JPanel bText = JaxoDialogs.newPageBoxLayoutPanel();

        bText.add(textPanel);
        bText.add(textPanel1);

        return bText;
    }

    private JPanel getBMiscCont() {
        final JPanel miscPanel = new JPanel(true);
        miscPanel.add(getDefPanel());

        final JPanel miscPanel1 = new JPanel(false);
        miscPanel1.add(getDepthPanel());

        final JPanel miscPanel2 = new JPanel(false);
        miscPanel2.add(getColorSpacePanel());

        final JPanel bMisc = JaxoDialogs.newPageBoxLayoutPanel();

        bMisc.add(miscPanel);
        bMisc.add(miscPanel1);
        bMisc.add(miscPanel2);

        return bMisc;
    }

    private JPanel getDefPanel() {
        final int nofDefaults = JaxoConstants.defaultModes().length;
        final String[] defaults = new String[nofDefaults];

        for (int jj = 0; jj < nofDefaults; jj++) {
            defaults[jj] =
                JaxoLanguage.translate(JaxoConstants.defaultActionKeys()[jj]);
        }

        chooseDefaultMode = new JComboBox(defaults);

        final JPanel defPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.defaultAction.title");

        defPanel.setPreferredSize(new Dimension(200, 65));
        defPanel.add(chooseDefaultMode);

        return defPanel;
    }

    private JPanel getDepthPanel() {
        modelundo = new SpinnerNumberModel(2, 2, 10000, 10);
        //Test what undo depth is effectively allowed
        final JLabel undo =
            new JLabel(JaxoLanguage.label("JaxoPrefsPanel.undoDepth"),
                JLabel.TRAILING);

        final JSpinner spundo = new JaxoFixedJSpinner(modelundo);

        final JPanel depthPanel =
            JaxoDialogs.newTitledFlowLayoutPanel(
                "JaxoPrefsPanel.undoDepth.title");

        depthPanel.add(undo);
        depthPanel.add(spundo);

        depthPanel.setPreferredSize(new Dimension(300, 65));

        return depthPanel;
    }
}
