/*
 * AbstractPopupButton.java  $Revision: 1.3 $  $Date: 2007/10/03 04:39:40 $
 *
 * Copyright (C) 2007 Meldcraft Corporation
 *
 * This file is part of Scaffold.
 * 
 * Scaffold is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Scaffold is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Scaffold.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.meldcraft.gui.swing;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import com.meldcraft.gui.swing.SwingUtil;

/**
 * @version $Revision: 1.3 $ $Date: 2007/10/03 04:39:40 $
 * @author Rob Richards
 */
abstract public class AbstractPopupButton extends JButton
    implements ActionListener
{
// Static variables
// Member variables
    private Box             mPanel;
    private Popup           mPopup;
    private MouseListener   mMouseListener;

// Constructors and initialization
    public AbstractPopupButton()
    {
        setMargin(new Insets(0,0,0,0));
        setText("");
        addActionListener(this);

        mPanel = Box.createVerticalBox();
        mPanel.setBorder(BorderFactory.createCompoundBorder(
                            BorderFactory.createRaisedBevelBorder(),
                            BorderFactory.createEmptyBorder(5,10,5,10)));

        mMouseListener = new MouseAdapter() {
            public void mousePressed(MouseEvent e)
            {
                if (mPopup != null)
                {
                    hidePopup();
                }
            }
        };

        mPanel.addMouseListener(mMouseListener);
        addMouseListener(mMouseListener);
    }

// Interface implemenations
    public void actionPerformed(ActionEvent e)
    {
        // show scrunch popup menu
        if (mPopup != null)
        {
            hidePopup();
        }
        else
        {
            mPanel.removeAll();
            Component[] comps = getPopupComponents();
            if (comps != null)
            {
                for (int i=0 ; i < comps.length ; i++)
                {
                    mPanel.add(comps[i]);
                }
            }

            Point pt = getLocationOnScreen();
            int x = pt.x + getWidth()-1;
            int y = pt.y + getHeight()/2;

            Dimension sdim = SwingUtil.getScreenSize((Window)SwingUtilities.getAncestorOfClass(Window.class, this));
            Dimension pdim = mPanel.getPreferredSize();
            boolean xfine = true;
            if (x + pdim.width > sdim.width)
            {
                xfine = false;
                x = sdim.width - pdim.width;
                y = pt.y + getHeight();
            }

            if (y + pdim.height > sdim.height)
            {
                if (xfine)
                {
                    y = sdim.height - pdim.height;
                }
                else
                {
                    y = pt.y - pdim.height;
                }
            }

            mPopup = PopupFactory.getSharedInstance().getPopup(this, mPanel,
                                                               x, y);
            Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, mPanel);
            if (window != null)
            {
                window.setFocusableWindowState(true);
                window.addWindowFocusListener(new WindowFocusListener() {
                    public void windowGainedFocus(WindowEvent e)
                    {
                        // do nothing
                    }
                    public void windowLostFocus(WindowEvent e)
                    {
                        if (mPopup != null)
                        {
                            hidePopup(true);
                        }
                    }
                });
            }

            mPopup.show();
        }
    }

// Public methods
// Protected methods
    abstract protected Component[] getPopupComponents();

    protected void hidePopup()
    {
        hidePopup(false);
    }

// Private methods
    private void hidePopup(boolean removeComps)
    {
        mPopup.hide();
        mPopup = null;

        if (removeComps)
        {
            mPanel.removeAll();
        }
    }

// Inner classes
}
