/*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core.output;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;

import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

/**
 * Support class for popup menu in OutputView.
 * Taken from org.netbeans.core.windows.frames.
 *
 * @author Tran Duc Trung
 */

class TabHandlePopupListener implements AWTEventListener
{
    private static int installCount = 0;
    private static TabHandlePopupListener INSTANCE = null;

    private TabHandlePopupListener() {}

    static synchronized void install() {
        installCount++;
        if (installCount == 1) {
            if (INSTANCE == null) {
                INSTANCE = new TabHandlePopupListener();
                Toolkit.getDefaultToolkit().addAWTEventListener(
                    INSTANCE, AWTEvent.MOUSE_EVENT_MASK);
            }
        }
    }
    
    static synchronized void uninstall() {
        installCount--;
        if (installCount == 0 && INSTANCE != null) {
            Toolkit.getDefaultToolkit().removeAWTEventListener(INSTANCE);
            INSTANCE = null;
        }
    }

    public void eventDispatched (AWTEvent ev) {
        MouseEvent e = (MouseEvent) ev;

        // XXX(-ttran) In the perfect world I would write
        //
        //    if (!e.isPopupTrigger())
        //        return;
        //
        // Unfortunately some times (Windows L&F) popup trigger is bound to
        // mouse-released event which leads to this sequence of events
        //
        //   - the user right clicks on the tab handle intending to invoke the
        //     popup
        //   - if the tab is not selected, it is selected, the whole layout of
        //     tab handles changed, the mouse pointer now is on a different tab
        //     handle
        //   - the user releases the mouse button
        //   - we reacts to this event and run the action on the new tab which
        //     has the handle under the mouse pointer
        //
        // For this reason I have to show the popup on mouse-pressed event not
        // mouse-released no matter what is the convention on the OS
        // 
        // See bug #22442.
        if (e.getID() != MouseEvent.MOUSE_PRESSED
            || ! org.openide.awt.MouseUtils.isRightMouseButton(e)
            ) {
            return;
        }
        
        Component c = (Component) e.getSource();
        while (c != null && !(c instanceof JTabbedPane))
            c = c.getParent();
        if (c == null)
            return;
        final JTabbedPane tab = (JTabbedPane) c;

        while ((c != null) && !(c instanceof OutputView)) {
            c = c.getParent();
        }
        if (c == null)
            return;
        final OutputView container = (OutputView) c;
        //Component selected in container
        final Component prevSelected = container.getSelectedComponent();
        
        final Point p = SwingUtilities.convertPoint((Component) e.getSource(), e.getPoint(), tab);
        
        final int clickTab = JdkBug4620540Hack.findTabForCoordinate(tab, p.x, p.y);
        if (clickTab < 0)
            return;
        
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                //Component in selected tab in given JTabbedPane
                Component selectedInTab = tab.getComponentAt(clickTab);
                //Check if component in clicked tab is selected in container if not
                //select it.
                if (prevSelected != selectedInTab) {
                    container.requestVisible(selectedInTab);
                }
                
                Component selected = tab.getSelectedComponent();
                
                container.showPopupMenu(container.createPopupMenu(), p, tab);
            }
        });
    }
}
