/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 *
 * Copyright (C)
 * <a href="http://www.inab.org">Spanish National Institute of Bioinformatics (INB)</a>
 * <a href="http://www.bsc.es">Barcelona Supercomputing Center (BSC)</a>
 * <a href="http://inb.bsc.es">Computational Node 6</a>
 */

package org.inb.biomoby.client.gui.auxiliary;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;
import org.inb.biomoby.client.gui.AbstractMobyComponent;

/**
 * @author Dmitry Repchevsky
 */

public abstract class AbstractDescriptionMobyComponent extends AbstractMobyComponent
        implements MouseListener, MouseMotionListener
{
    private JComponent popup;
    
    public AbstractDescriptionMobyComponent()
    {
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    
    protected abstract JComponent getPopup();
    
    protected void showPopup(int x, int y)
    {
        JLayeredPane lp = getRootPane().getLayeredPane();
        
        if (popup == null)
        {
            popup = this.getPopup();
            
            if (popup == null)
            { // there is no popup for the component
                return;
            }

            lp.add(popup, JLayeredPane.POPUP_LAYER);
        }
        
        Point p = SwingUtilities.convertPoint(this, x, y, lp);
        
        int w = popup.getPreferredSize().width;
        int h = popup.getPreferredSize().height;

        if (p.y - h > 0 ||
            p.y > lp.getHeight() - p.y)
        {
            if (p.y < h)
            { // doesn't fit - make height smaller
                h = p.y;
            }
            p.y -= h;
        }
        else
        {
            h = lp.getHeight() - p.y;
        }

        //if (p.x + w > lp.getWidth() && p.x - w > 0)
        if (p.x - w > 0 ||
            p.x > lp.getWidth() - p.x)
        {
            if (p.x < w)
            { // doesn't fit - make width smaller
                w = p.x;
            }
            p.x -= w;
        }
        else
        {
            w = lp.getWidth() - p.x;
        }

        popup.setBounds(p.x, p.y, w, h);
    }
    
    protected void hidePopup()
    {
        if (popup != null)
        {
            getRootPane().getLayeredPane().remove(popup);
            getRootPane().repaint();
            popup = null;
        }
    }

    @Override public void mouseClicked(MouseEvent e) {}
    @Override public void mousePressed(MouseEvent e) {}
    @Override public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e)
    {
        showPopup(e.getX(), e.getY());
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
        hidePopup();
    }

    @Override
    public void mouseMoved(MouseEvent e)
    {
        showPopup(e.getX(), e.getY());
    }
    
    @Override public void mouseDragged(MouseEvent e) {}
    
}
