
package uk.co.wingpath.gui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import uk.co.wingpath.event.Event;

public class SimpleDialog
{
    protected WWindow dialog;
    private ButtonPanel buttonPanel;
    private JPanel mainPanel;
    private DialogCloseAction closeAction;
    private WWindow parent;
    private boolean sized = false;
    private int minWidth = 100;
    private int minHeight = 50;

    private static DialogCloseAction hideOnClose = new DialogCloseAction ()
        {
            public void dialogClosing (WWindow dialog)
            {
                dialog.setVisible (false);
            }
        };

    private static DialogCloseAction disposeOnClose = new DialogCloseAction ()
        {
            public void dialogClosing (WWindow dialog)
            {
                dialog.dispose ();
            }
        };

    public static SimpleDialog createNonModal (WWindow parent)
    {
        return new SimpleDialog (parent, WDialog.createNonModal (parent));
    }

    public static SimpleDialog createModal (WWindow parent)
    {
        return new SimpleDialog (parent, WDialog.createModal (parent));
    }

    public static SimpleDialog createFrame (WWindow parent)
    {
        return new SimpleDialog (parent, WFrame.create (parent));
    }

    private SimpleDialog (WWindow parent, final WWindow dialog)
    {
        Event.checkIsEventDispatchThread ();
        this.parent = parent;
        this.dialog = dialog;

        Container contentPane = dialog.getContentPane ();

        mainPanel = new JPanel ();
        mainPanel.setLayout (new BorderLayout ());
        contentPane.add (mainPanel, BorderLayout.CENTER);

        buttonPanel = new ButtonPanel ();
        mainPanel.add (buttonPanel, BorderLayout.SOUTH);

        closeAction = hideOnClose;
        dialog.setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE);
        dialog.addWindowListener (new WindowAdapter ()
            {
                public void windowClosing (WindowEvent e)
                {
                    closeAction.dialogClosing (dialog);
                }
            });

        // Arrange for escape key to hide dialog

        AbstractAction cancelAction = new AbstractAction ()
            {
                public void actionPerformed (ActionEvent e)
                {
                    closeAction.dialogClosing (dialog);
                }
            };
        Gui.addShortCut (dialog.getRootPane (), "ESCAPE_KEY",
            KeyEvent.VK_ESCAPE, 0, cancelAction);

        // Add shortcut for enabling tooltip display

        Gui.addEnableToolTipShortCut (dialog.getRootPane ());
    }

    public void setContent (JComponent content)
    {
        mainPanel.add (content, BorderLayout.CENTER);
    }

    public void setStatusBar (StatusBar statusBar)
    {
        Container contentPane = dialog.getContentPane ();
        contentPane.add (statusBar, BorderLayout.SOUTH);
    }

    public void setButtonPanel (ButtonPanel buttonPanel)
    {
        this.buttonPanel = buttonPanel;
        mainPanel.add (buttonPanel, BorderLayout.SOUTH);
    }

    public void setCloseAction (DialogCloseAction closeAction)
    {
        this.closeAction = closeAction;
    }

    public void setDefaultCloseOperation (int operation)
    {
        switch (operation)
        {
        case WindowConstants.DISPOSE_ON_CLOSE:
            closeAction = disposeOnClose;
            break;

        case WindowConstants.HIDE_ON_CLOSE:
            closeAction = hideOnClose;
            break;

        default:
            throw new IllegalArgumentException ("Illegal close operation");
        }
    }

    public void setMinimumSize (int minWidth, int minHeight)
    {
        if (sized)
            throw new IllegalStateException ("Already sized");
        this.minWidth = minWidth;
        this.minHeight = minHeight;
    }

    private void setSize ()
    {
        dialog.pack ();
        int width = dialog.getWidth ();
        int height = dialog.getHeight ();
        if (width < minWidth)
            width = minWidth;
        if (height < minHeight)
            height = minHeight;
        // Setting the width to the width determined by pack sometimes
        // causes GridBaglayout to assign zero-width to text fields.
        // Hence the addition of 2 below.
        width += 2;
        dialog.setSize (width, height);
    }

    private void setLocation ()
    {
        if (dialog.isLocationByPlatform ())
            return;

        if (parent == null)
        {
            // Put dialog in centre of screen.

            dialog.setLocationRelativeTo (null);
        }
        else
        {
            // Centre dialog over botton-right corner of parent.

            int width = dialog.getWidth ();
            int height = dialog.getHeight ();
            Dimension screenSize =
                Toolkit.getDefaultToolkit ().getScreenSize ();
            Dimension parentSize = parent.getSize ();
            Point parentLocation = parent.getLocationOnScreen ();

            int x = parentLocation.x + parentSize.width - width / 2;
            int y = parentLocation.y + parentSize.height -height / 2;

            if (y + height > screenSize.height)
                y = screenSize.height - height;
            if (x + width > screenSize.width)
                x = screenSize.width - width;
            if (x < 0)
                x = 0;
            if (y < 0)
                y = 0;

            dialog.setLocation (x, y);
        }
    }

    private void setSizeAndLocation ()
    {
        Event.checkIsEventDispatchThread ();
        if (!sized)
        {
            setSize ();
            setLocation ();
            sized = true;
        }
    }

    /**
    * Prepare the dialog for being displayed (but don't make it visible).
    */
    public void prepare ()
    {
        Event.checkIsEventDispatchThread ();
        setSizeAndLocation ();
    }

    public void showDialog ()
    {
        Event.checkIsEventDispatchThread ();
        setSizeAndLocation ();
        dialog.setExtendedState (Frame.NORMAL);
        dialog.setVisible (true);
    }

    public void hideDialog ()
    {
        Event.checkIsEventDispatchThread ();
        closeAction.dialogClosing (dialog);
    }

    public JButton addButton (String label, String toolTip,
        ActionListener listener)
    {
        return buttonPanel.addButton (label, toolTip, listener);
    }

    public JButton addCloseButton ()
    {
        JButton button = buttonPanel.addButton ("Close", null,
            new ActionListener () {
                public void actionPerformed (ActionEvent w)
                {
                    closeAction.dialogClosing (dialog);
                }
            });
        dialog.getRootPane ().setDefaultButton (button);
        return button;
    }

    public JButton addCancelButton ()
    {
        JButton button = buttonPanel.addButton ("Cancel", null,
            new ActionListener () {
                public void actionPerformed (ActionEvent w)
                {
                    closeAction.dialogClosing (dialog);
                }
            });
        return button;
    }

    public JButton addButton (Action action)
    {
        return buttonPanel.addButton (action);
    }

    public void setHelpAction (Action helpAction)
    {
        Gui.addHelpShortCut (dialog.getRootPane (), helpAction);
    }

    public JButton addHelpButton (Action helpAction)
    {
        JButton button = buttonPanel.addButton (helpAction);
        setHelpAction (helpAction);
        return button;
    }

    public void setDefaultButton (JButton button)
    {
        dialog.getRootPane ().setDefaultButton (button);
    }

    public void setTitle (String title)
    {
        dialog.setTitle (title);
    }

    public void setResizable (boolean resizable)
    {
        dialog.setResizable (resizable);
    }

    public void setCursor (Cursor cursor)
    {
        dialog.setCursor (cursor);
    }
}


