/**
 *  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.GridLayout;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.gui.JaxoDrawingArea;
import net.sf.jaxodraw.util.JaxoDictionary;

/**
 * Dialog to move all objects of a graph.
 *
 * @since 2.0
 */
public class JaxoMoveGraph  {
    private final JaxoDictionary language =
            new JaxoDictionary(JaxoMoveGraph.class);

    private final JSpinner spinnerX = new JSpinner(new SpinnerNumberModel());
    private final JSpinner spinnerY = new JSpinner(new SpinnerNumberModel());

    private final JDialog dialog;

    private boolean hasChanged;

    private int lastX, lastY;
    private boolean adjusting;

    /**
     * Constructor.
     *
     * @param parent component for the dialog.
     * @param c canvas whose graph should be moved.
     */
    public JaxoMoveGraph(final Component parent, final JaxoDrawingArea c) {

        final ChangeListener l = new ChangeListener() {
            public void stateChanged(final ChangeEvent e) {
                if (adjusting) {
                    return;
                }

                int dx = ((Number) spinnerX.getValue()).intValue();
                int dy = ((Number) spinnerY.getValue()).intValue();

                dx -= lastX;
                dy -= lastY;
                lastX += dx;
                lastY += dy;

                c.moveGraph(dx, dy);
            }
        };

        spinnerX.addChangeListener(l);
        spinnerY.addChangeListener(l);


        final JButton ok = new JButton(language.value("/OK"));
        final JButton cancel = new JButton(language.value("/Cancel"));

        dialog = JaxoDialogs.newDialog(parent,
            JaxoDialogs.translatedWindowTitle(language.value("title")), true);
        dialog.setResizable(false);

        ok.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                l.stateChanged(null);
                hasChanged = true;
                dialog.setVisible(false);
            }
        });

        cancel.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                final int dx = ((Number) spinnerX.getValue()).intValue();
                final int dy = ((Number) spinnerY.getValue()).intValue();

                hasChanged = false;

                c.moveGraph(-dx, -dy);

                dialog.setVisible(false);
            }
        });

        final JPanel p = new JPanel(new GridLayout(0, 2), false);
        p.add(new JLabel(language.label("dx"), JLabel.TRAILING));
        p.add(spinnerX);
        p.add(new JLabel(language.label("dy"), JLabel.TRAILING));
        p.add(spinnerY);
        dialog.getContentPane().add(p);
        final JPanel buttons = new JPanel(false);
        buttons.add(ok);
        buttons.add(cancel);
        dialog.getContentPane().add(buttons, BorderLayout.SOUTH);
        dialog.pack();
        dialog.setLocationRelativeTo(parent);
    }


    /** Show dialog, blocking. */
    public void show() {
        hasChanged = false;
        adjusting = true;
        lastX = 0;
        lastY = 0;
        spinnerX.setValue(Integer.valueOf(0));
        spinnerY.setValue(Integer.valueOf(0));
        adjusting = false;
        dialog.setVisible(true);
    }


    /**
     * Checks if the the graph was actually moved.
     *
     * @return True if the graph was actually moved.
     */
    public final boolean hasChanged() {
        return hasChanged;
    }
}
