/*
 * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.swing;


import javax.swing.event.*;
import java.awt.event.*;

import java.awt.Component;
import java.awt.Container;
import java.awt.Window;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

import java.io.Serializable;


/**
 * @author Dave Moore
 */

class AncestorNotifier implements ComponentListener, PropertyChangeListener, Serializable
{
    Component firstInvisibleAncestor;
    EventListenerList listenerList = new EventListenerList();
    JComponent root;

    AncestorNotifier(JComponent root) {
        this.root = root;
        addListeners(root, true);
    }

    void addAncestorListener(AncestorListener l) {
        listenerList.add(AncestorListener.class, l);
    }

    void removeAncestorListener(AncestorListener l) {
        listenerList.remove(AncestorListener.class, l);
    }

    AncestorListener[] getAncestorListeners() {
        return (AncestorListener[])listenerList.getListeners(AncestorListener.class);
    }

    /**
     * Notify all listeners that have registered interest for
     * notification on this event type.  The event instance
     * is lazily created using the parameters passed into
     * the fire method.
     * @see EventListenerList
     */
    protected void fireAncestorAdded(JComponent source, int id, Container ancestor, Container ancestorParent) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==AncestorListener.class) {
                // Lazily create the event:
                AncestorEvent ancestorEvent =
                    new AncestorEvent(source, id, ancestor, ancestorParent);
                ((AncestorListener)listeners[i+1]).ancestorAdded(ancestorEvent);
            }
        }
    }

    /**
     * Notify all listeners that have registered interest for
     * notification on this event type.  The event instance
     * is lazily created using the parameters passed into
     * the fire method.
     * @see EventListenerList
     */
    protected void fireAncestorRemoved(JComponent source, int id, Container ancestor, Container ancestorParent) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==AncestorListener.class) {
                // Lazily create the event:
                AncestorEvent ancestorEvent =
                    new AncestorEvent(source, id, ancestor, ancestorParent);
                ((AncestorListener)listeners[i+1]).ancestorRemoved(ancestorEvent);
            }
        }
    }
    /**
     * Notify all listeners that have registered interest for
     * notification on this event type.  The event instance
     * is lazily created using the parameters passed into
     * the fire method.
     * @see EventListenerList
     */
    protected void fireAncestorMoved(JComponent source, int id, Container ancestor, Container ancestorParent) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==AncestorListener.class) {
                // Lazily create the event:
                AncestorEvent ancestorEvent =
                    new AncestorEvent(source, id, ancestor, ancestorParent);
                ((AncestorListener)listeners[i+1]).ancestorMoved(ancestorEvent);
            }
        }
    }

    void removeAllListeners() {
        removeListeners(root);
    }

    void addListeners(Component ancestor, boolean addToFirst) {
        Component a;

        firstInvisibleAncestor = null;
        for (a = ancestor;
             firstInvisibleAncestor == null;
             a = a.getParent()) {
            if (addToFirst || a != ancestor) {
                a.addComponentListener(this);

                if (a instanceof JComponent) {
                    JComponent jAncestor = (JComponent)a;

                    jAncestor.addPropertyChangeListener(this);
                }
            }
            if (!a.isVisible() || a.getParent() == null || a instanceof Window) {
                firstInvisibleAncestor = a;
            }
        }
        if (firstInvisibleAncestor instanceof Window &&
            firstInvisibleAncestor.isVisible()) {
            firstInvisibleAncestor = null;
        }
    }

    void removeListeners(Component ancestor) {
        Component a;
        for (a = ancestor; a != null; a = a.getParent()) {
            a.removeComponentListener(this);
            if (a instanceof JComponent) {
                JComponent jAncestor = (JComponent)a;
                jAncestor.removePropertyChangeListener(this);
            }
            if (a == firstInvisibleAncestor || a instanceof Window) {
                break;
            }
        }
    }

    public void componentResized(ComponentEvent e) {}

    public void componentMoved(ComponentEvent e) {
        Component source = e.getComponent();

        fireAncestorMoved(root, AncestorEvent.ANCESTOR_MOVED,
                          (Container)source, source.getParent());
    }

    public void componentShown(ComponentEvent e) {
        Component ancestor = e.getComponent();

        if (ancestor == firstInvisibleAncestor) {
            addListeners(ancestor, false);
            if (firstInvisibleAncestor == null) {
                fireAncestorAdded(root, AncestorEvent.ANCESTOR_ADDED,
                                  (Container)ancestor, ancestor.getParent());
            }
        }
    }

    public void componentHidden(ComponentEvent e) {
        Component ancestor = e.getComponent();
        boolean needsNotify = firstInvisibleAncestor == null;

        if ( !(ancestor instanceof Window) ) {
            removeListeners(ancestor.getParent());
        }
        firstInvisibleAncestor = ancestor;
        if (needsNotify) {
            fireAncestorRemoved(root, AncestorEvent.ANCESTOR_REMOVED,
                                (Container)ancestor, ancestor.getParent());
        }
    }

    public void propertyChange(PropertyChangeEvent evt) {
        String s = evt.getPropertyName();

        if (s!=null && (s.equals("parent") || s.equals("ancestor"))) {
            JComponent component = (JComponent)evt.getSource();

            if (evt.getNewValue() != null) {
                if (component == firstInvisibleAncestor) {
                    addListeners(component, false);
                    if (firstInvisibleAncestor == null) {
                        fireAncestorAdded(root, AncestorEvent.ANCESTOR_ADDED,
                                          component, component.getParent());
                    }
                }
            } else {
                boolean needsNotify = firstInvisibleAncestor == null;
                Container oldParent = (Container)evt.getOldValue();

                removeListeners(oldParent);
                firstInvisibleAncestor = component;
                if (needsNotify) {
                    fireAncestorRemoved(root, AncestorEvent.ANCESTOR_REMOVED,
                                        component, oldParent);
                }
            }
        }
    }
}
