/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text;

import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Set;
import javax.swing.SwingUtilities;
import javax.swing.event.*;

/**
 * Component decorator that implements the view interface.  The
 * entire element is used to represent the component.  This acts
 * as a gateway from the display-only View implementations to
 * interactive lightweight components (ie it allows components
 * to be embedded into the View hierarchy).
 * <p>
 * The component is placed relative to the text baseline
 * according to the value returned by
 * <code>Component.getAlignmentY</code>.  For Swing components
 * this value can be conveniently set using the method
 * <code>JComponent.setAlignmentY</code>.  For example, setting
 * a value of <code>0.75</code> will cause 75 percent of the
 * component to be above the baseline, and 25 percent of the
 * component to be below the baseline.
 * <p>
 * This class is implemented to do the extra work necessary to
 * work properly in the presence of multiple threads (i.e. from
 * asynchronous notification of model changes for example) by
 * ensuring that all component access is done on the event thread.
 * <p>
 * The component used is determined by the return value of the
 * createComponent method.  The default implementation of this
 * method is to return the component held as an attribute of
 * the element (by calling StyleConstants.getComponent).  A
 * limitation of this behavior is that the component cannot
 * be used by more than one text component (i.e. with a shared
 * model).  Subclasses can remove this constraint by implementing
 * the createComponent to actually create a component based upon
 * some kind of specification contained in the attributes.  The
 * ObjectView class in the html package is an example of a
 * ComponentView implementation that supports multiple component
 * views of a shared model.
 *
 * @author Timothy Prinzing
 */
public class ComponentView extends View  {

    /**
     * Creates a new ComponentView object.
     *
     * @param elem the element to decorate
     */
    public ComponentView(Element elem) {
        super(elem);
    }

    /**
     * Create the component that is associated with
     * this view.  This will be called when it has
     * been determined that a new component is needed.
     * This would result from a call to setParent or
     * as a result of being notified that attributes
     * have changed.
     */
    protected Component createComponent() {
        AttributeSet attr = getElement().getAttributes();
        Component comp = StyleConstants.getComponent(attr);
        return comp;
    }

    /**
     * Fetch the component associated with the view.
     */
    public final Component getComponent() {
        return createdC;
    }

    // --- View methods ---------------------------------------------

    /**
     * The real paint behavior occurs naturally from the association
     * that the component has with its parent container (the same
     * container hosting this view).  This is implemented to do nothing.
     *
     * @param g the graphics context
     * @param a the shape
     * @see View#paint
     */
    public void paint(Graphics g, Shape a) {
        if (c != null) {
            Rectangle alloc = (a instanceof Rectangle) ?
                (Rectangle) a : a.getBounds();
            c.setBounds(alloc.x, alloc.y, alloc.width, alloc.height);
        }
    }

    /**
     * Determines the preferred span for this view along an
     * axis.  This is implemented to return the value
     * returned by Component.getPreferredSize along the
     * axis of interest.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return   the span the view would like to be rendered into >= 0.
     *           Typically the view is told to render into the span
     *           that is returned, although there is no guarantee.
     *           The parent may choose to resize or break the view.
     * @exception IllegalArgumentException for an invalid axis
     */
    public float getPreferredSpan(int axis) {
        if ((axis != X_AXIS) && (axis != Y_AXIS)) {
            throw new IllegalArgumentException("Invalid axis: " + axis);
        }
        if (c != null) {
            Dimension size = c.getPreferredSize();
            if (axis == View.X_AXIS) {
                return size.width;
            } else {
                return size.height;
            }
        }
        return 0;
    }

    /**
     * Determines the minimum span for this view along an
     * axis.  This is implemented to return the value
     * returned by Component.getMinimumSize along the
     * axis of interest.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return   the span the view would like to be rendered into >= 0.
     *           Typically the view is told to render into the span
     *           that is returned, although there is no guarantee.
     *           The parent may choose to resize or break the view.
     * @exception IllegalArgumentException for an invalid axis
     */
    public float getMinimumSpan(int axis) {
        if ((axis != X_AXIS) && (axis != Y_AXIS)) {
            throw new IllegalArgumentException("Invalid axis: " + axis);
        }
        if (c != null) {
            Dimension size = c.getMinimumSize();
            if (axis == View.X_AXIS) {
                return size.width;
            } else {
                return size.height;
            }
        }
        return 0;
    }

    /**
     * Determines the maximum span for this view along an
     * axis.  This is implemented to return the value
     * returned by Component.getMaximumSize along the
     * axis of interest.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return   the span the view would like to be rendered into >= 0.
     *           Typically the view is told to render into the span
     *           that is returned, although there is no guarantee.
     *           The parent may choose to resize or break the view.
     * @exception IllegalArgumentException for an invalid axis
     */
    public float getMaximumSpan(int axis) {
        if ((axis != X_AXIS) && (axis != Y_AXIS)) {
            throw new IllegalArgumentException("Invalid axis: " + axis);
        }
        if (c != null) {
            Dimension size = c.getMaximumSize();
            if (axis == View.X_AXIS) {
                return size.width;
            } else {
                return size.height;
            }
        }
        return 0;
    }

    /**
     * Determines the desired alignment for this view along an
     * axis.  This is implemented to give the alignment of the
     * embedded component.
     *
     * @param axis may be either View.X_AXIS or View.Y_AXIS
     * @return the desired alignment.  This should be a value
     *   between 0.0 and 1.0 where 0 indicates alignment at the
     *   origin and 1.0 indicates alignment to the full span
     *   away from the origin.  An alignment of 0.5 would be the
     *   center of the view.
     */
    public float getAlignment(int axis) {
        if (c != null) {
            switch (axis) {
            case View.X_AXIS:
                return c.getAlignmentX();
            case View.Y_AXIS:
                return c.getAlignmentY();
            }
        }
        return super.getAlignment(axis);
    }

    /**
     * Sets the parent for a child view.
     * The parent calls this on the child to tell it who its
     * parent is, giving the view access to things like
     * the hosting Container.  The superclass behavior is
     * executed, followed by a call to createComponent if
     * the parent view parameter is non-null and a component
     * has not yet been created. The embedded components parent
     * is then set to the value returned by <code>getContainer</code>.
     * If the parent view parameter is null, this view is being
     * cleaned up, thus the component is removed from its parent.
     * <p>
     * The changing of the component hierarchy will
     * touch the component lock, which is the one thing
     * that is not safe from the View hierarchy.  Therefore,
     * this functionality is executed immediately if on the
     * event thread, or is queued on the event queue if
     * called from another thread (notification of change
     * from an asynchronous update).
     *
     * @param p the parent
     */
    public void setParent(View p) {
        super.setParent(p);
        if (SwingUtilities.isEventDispatchThread()) {
            setComponentParent();
        } else {
            Runnable callSetComponentParent = new Runnable() {
                public void run() {
                    Document doc = getDocument();
                    try {
                        if (doc instanceof AbstractDocument) {
                            ((AbstractDocument)doc).readLock();
                        }
                        setComponentParent();
                        Container host = getContainer();
                        if (host != null) {
                            preferenceChanged(null, true, true);
                            host.repaint();
                        }
                    } finally {
                        if (doc instanceof AbstractDocument) {
                            ((AbstractDocument)doc).readUnlock();
                        }
                    }
                }
            };
            SwingUtilities.invokeLater(callSetComponentParent);
        }
    }

    /**
     * Set the parent of the embedded component
     * with assurance that it is thread-safe.
     */
    void setComponentParent() {
        View p = getParent();
        if (p != null) {
            Container parent = getContainer();
            if (parent != null) {
                if (c == null) {
                    // try to build a component
                    Component comp = createComponent();
                    if (comp != null) {
                        createdC = comp;
                        c = new Invalidator(comp);
                    }
                }
                if (c != null) {
                    if (c.getParent() == null) {
                        // components associated with the View tree are added
                        // to the hosting container with the View as a constraint.
                        parent.add(c, this);
                        parent.addPropertyChangeListener("enabled", c);
                    }
                }
            }
        } else {
            if (c != null) {
                Container parent = c.getParent();
                if (parent != null) {
                    // remove the component from its hosting container
                    parent.remove(c);
                    parent.removePropertyChangeListener("enabled", c);
                }
            }
        }
    }

    /**
     * Provides a mapping from the coordinate space of the model to
     * that of the view.
     *
     * @param pos the position to convert >= 0
     * @param a the allocated region to render into
     * @return the bounding box of the given position is returned
     * @exception BadLocationException  if the given position does not
     *   represent a valid location in the associated document
     * @see View#modelToView
     */
    public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
        int p0 = getStartOffset();
        int p1 = getEndOffset();
        if ((pos >= p0) && (pos <= p1)) {
            Rectangle r = a.getBounds();
            if (pos == p1) {
                r.x += r.width;
            }
            r.width = 0;
            return r;
        }
        throw new BadLocationException(pos + " not in range " + p0 + "," + p1, pos);
    }

    /**
     * Provides a mapping from the view coordinate space to the logical
     * coordinate space of the model.
     *
     * @param x the X coordinate >= 0
     * @param y the Y coordinate >= 0
     * @param a the allocated region to render into
     * @return the location within the model that best represents
     *    the given point in the view
     * @see View#viewToModel
     */
    public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
        Rectangle alloc = (Rectangle) a;
        if (x < alloc.x + (alloc.width / 2)) {
            bias[0] = Position.Bias.Forward;
            return getStartOffset();
        }
        bias[0] = Position.Bias.Backward;
        return getEndOffset();
    }

    // --- member variables ------------------------------------------------

    private Component createdC;
    private Invalidator c;

    /**
     * This class feeds the invalidate back to the
     * hosting View.  This is needed to get the View
     * hierarchy to consider giving the component
     * a different size (i.e. layout may have been
     * cached between the associated view and the
     * container hosting this component).
     */
    class Invalidator extends Container implements PropertyChangeListener {

        // NOTE: When we remove this class we are going to have to some
        // how enforce setting of the focus traversal keys on the children
        // so that they don't inherit them from the JEditorPane. We need
        // to do this as JEditorPane has abnormal bindings (it is a focus cycle
        // root) and the children typically don't want these bindings as well.

        Invalidator(Component child) {
            setLayout(null);
            add(child);
            cacheChildSizes();
        }

        /**
         * The components invalid layout needs
         * to be propagated through the view hierarchy
         * so the views (which position the component)
         * can have their layout recomputed.
         */
        public void invalidate() {
            super.invalidate();
            if (getParent() != null) {
                preferenceChanged(null, true, true);
            }
        }

        public void doLayout() {
            cacheChildSizes();
        }

        public void setBounds(int x, int y, int w, int h) {
            super.setBounds(x, y, w, h);
            if (getComponentCount() > 0) {
                getComponent(0).setSize(w, h);
            }
            cacheChildSizes();
        }

        public void validateIfNecessary() {
            if (!isValid()) {
                validate();
             }
        }

        private void cacheChildSizes() {
            if (getComponentCount() > 0) {
                Component child = getComponent(0);
                min = child.getMinimumSize();
                pref = child.getPreferredSize();
                max = child.getMaximumSize();
                yalign = child.getAlignmentY();
                xalign = child.getAlignmentX();
            } else {
                min = pref = max = new Dimension(0, 0);
            }
        }

        /**
         * Shows or hides this component depending on the value of parameter
         * <code>b</code>.
         * @param b If <code>true</code>, shows this component;
         * otherwise, hides this component.
         * @see #isVisible
         * @since JDK1.1
         */
        public void setVisible(boolean b) {
            super.setVisible(b);
            if (getComponentCount() > 0) {
                getComponent(0).setVisible(b);
            }
        }

        /**
         * Overridden to fix 4759054. Must return true so that content
         * is painted when inside a CellRendererPane which is normally
         * invisible.
         */
        public boolean isShowing() {
            return true;
        }

        public Dimension getMinimumSize() {
            validateIfNecessary();
            return min;
        }

        public Dimension getPreferredSize() {
            validateIfNecessary();
            return pref;
        }

        public Dimension getMaximumSize() {
            validateIfNecessary();
            return max;
        }

        public float getAlignmentX() {
            validateIfNecessary();
            return xalign;
        }

        public float getAlignmentY() {
            validateIfNecessary();
            return yalign;
        }

        public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
            return KeyboardFocusManager.getCurrentKeyboardFocusManager().
                    getDefaultFocusTraversalKeys(id);
        }

        public void propertyChange(PropertyChangeEvent ev) {
            Boolean enable = (Boolean) ev.getNewValue();
            if (getComponentCount() > 0) {
                getComponent(0).setEnabled(enable);
            }
        }

        Dimension min;
        Dimension pref;
        Dimension max;
        float yalign;
        float xalign;

    }

}
