/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.swing;

import java.awt.Dimension;
import java.awt.EventQueue;
// import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.ToolTipManager;

import org.apache.batik.bridge.UserAgent;
import org.apache.batik.css.engine.CSSEngine;
import org.apache.batik.dom.events.NodeEventTarget;
import org.apache.batik.swing.gvt.AbstractImageZoomInteractor;
import org.apache.batik.swing.gvt.AbstractPanInteractor;
import org.apache.batik.swing.gvt.AbstractResetTransformInteractor;
import org.apache.batik.swing.gvt.AbstractRotateInteractor;
import org.apache.batik.swing.gvt.AbstractZoomInteractor;
import org.apache.batik.swing.gvt.Interactor;
// import org.apache.batik.swing.gvt.Overlay;
import org.apache.batik.swing.svg.JSVGComponent;
import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
import org.apache.batik.swing.svg.SVGUserAgent;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.util.XMLConstants;
// import org.apache.batik.util.gui.DOMViewer;
// import org.apache.batik.util.gui.DOMViewerController;
// import org.apache.batik.util.gui.ElementOverlayManager;
import org.apache.batik.util.gui.JErrorPane;

// import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.svg.SVGDocument;

/**
 * This class represents a general-purpose swing SVG component. The
 * <code>JSVGCanvas</code> does not provided additional functionalities compared to
 * the <code>JSVGComponent</code> but simply provides an API conformed to the
 * JavaBean specification. The only major change between the
 * <code>JSVGComponent</code> and this component is that interactors and text
 * selection are activated by default.
 *
 * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
 * @version $Id$
 */
public class JSVGCanvas extends JSVGComponent {

    /**
     * The key for the Action to scroll right.
     */
    public static final String SCROLL_RIGHT_ACTION = "ScrollRight";

    /**
     * The key for the Action to scroll left.
     */
    public static final String SCROLL_LEFT_ACTION = "ScrollLeft";

    /**
     * The key for the Action to scroll up.
     */
    public static final String SCROLL_UP_ACTION = "ScrollUp";

    /**
     * The key for the Action to scroll down.
     */
    public static final String SCROLL_DOWN_ACTION = "ScrollDown";

    /**
     * The key for the Action to quickly scroll right.
     */
    public static final String FAST_SCROLL_RIGHT_ACTION = "FastScrollRight";

    /**
     * The key for the Action to quickly scroll left.
     */
    public static final String FAST_SCROLL_LEFT_ACTION = "FastScrollLeft";

    /**
     * The key for the Action to quickly scroll up.
     */
    public static final String FAST_SCROLL_UP_ACTION = "FastScrollUp";

    /**
     * The key for the Action to quickly scroll down.
     */
    public static final String FAST_SCROLL_DOWN_ACTION = "FastScrollDown";

    /**
     * The key for the Action to zoom in.
     */
    public static final String ZOOM_IN_ACTION = "ZoomIn";

    /**
     * The key for the Action to zoom out.
     */
    public static final String ZOOM_OUT_ACTION = "ZoomOut";

    /**
     * The key for the Action to reset the transform.
     */
    public static final String RESET_TRANSFORM_ACTION = "ResetTransform";

    /**
     * This flag bit indicates whether or not the zoom interactor is
     * enabled. True means the zoom interactor is functional.
     */
    private boolean isZoomInteractorEnabled = true;

    /**
     * This flag bit indicates whether or not the image zoom interactor is
     * enabled. True means the image zoom interactor is functional.
     */
    private boolean isImageZoomInteractorEnabled = true;

    /**
     * This flag bit indicates whether or not the pan interactor is
     * enabled. True means the pan interactor is functional.
     */
    private boolean isPanInteractorEnabled = true;

    /**
     * This flag bit indicates whether or not the rotate interactor is
     * enabled. True means the rotate interactor is functional.
     */
    private boolean isRotateInteractorEnabled = true;

    /**
     * This flag bit indicates whether or not the reset transform interactor is
     * enabled. True means the reset transform interactor is functional.
     */
    private boolean isResetTransformInteractorEnabled = true;

    /**
     * The <code>PropertyChangeSupport</code> used to fire
     * <code>PropertyChangeEvent</code>.
     */
    protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    /**
     * The URI of the current document being displayed.
     */
    protected String uri;

    /**
     * Keeps track of the last known mouse position over the canvas.
     * This is used for displaying tooltips at the right location.
     */
    protected LocationListener locationListener = new LocationListener();

    /**
     * Mapping of elements to listeners so they can be removed,
     * if the tooltip is removed.
     */
    protected Map toolTipMap = null;
    protected EventListener toolTipListener = new ToolTipModifier();
    protected EventTarget   lastTarget = null;
    protected Map toolTipDocs = null;
    /**
     * This is used as the value in the toolTipDocs WeakHashMap.
     * This way we can tell if a document has already been added.
     */
    protected static final Object MAP_TOKEN = new Object();
    /**
     * The time of the last tool tip event.
     */
    protected long lastToolTipEventTimeStamp;

    /**
     * The target for which the last tool tip event was fired.
     */
    protected EventTarget lastToolTipEventTarget;



    /**
     * Creates a new JSVGCanvas.
     */
    public JSVGCanvas() {
        this(null, true, true);
        addMouseMotionListener(locationListener);
    }

    /**
     * Creates a new JSVGCanvas.
     *
     * @param ua a SVGUserAgent instance or null.
     * @param eventsEnabled Whether the GVT tree should be reactive to mouse
     *                      and key events.
     * @param selectableText Whether the text should be selectable.
     */
    public JSVGCanvas(SVGUserAgent ua,
                      boolean eventsEnabled,
                      boolean selectableText) {

        super(ua, eventsEnabled, selectableText);

        setPreferredSize(new Dimension(200, 200));
        setMinimumSize(new Dimension(100, 100));

        List intl = getInteractors();
        intl.add(zoomInteractor);
        intl.add(imageZoomInteractor);
        intl.add(panInteractor);
        intl.add(rotateInteractor);
        intl.add(resetTransformInteractor);

        installActions();

        if (eventsEnabled) {
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent evt) {
                    requestFocus();
                }
            });

            installKeyboardActions();
        }
        addMouseMotionListener(locationListener);
    }

    /**
     * Builds the ActionMap of this canvas with a set of predefined
     * <code>Action</code>s.
     */
    protected void installActions() {
        ActionMap actionMap = getActionMap();

        actionMap.put(SCROLL_RIGHT_ACTION, new ScrollRightAction(10));
        actionMap.put(SCROLL_LEFT_ACTION, new ScrollLeftAction(10));
        actionMap.put(SCROLL_UP_ACTION, new ScrollUpAction(10));
        actionMap.put(SCROLL_DOWN_ACTION, new ScrollDownAction(10));

        actionMap.put(FAST_SCROLL_RIGHT_ACTION, new ScrollRightAction(30));
        actionMap.put(FAST_SCROLL_LEFT_ACTION, new ScrollLeftAction(30));
        actionMap.put(FAST_SCROLL_UP_ACTION, new ScrollUpAction(30));
        actionMap.put(FAST_SCROLL_DOWN_ACTION, new ScrollDownAction(30));

        actionMap.put(ZOOM_IN_ACTION, new ZoomInAction());
        actionMap.put(ZOOM_OUT_ACTION, new ZoomOutAction());

        actionMap.put(RESET_TRANSFORM_ACTION, new ResetTransformAction());
    }

    public void setDisableInteractions(boolean b) {
        super.setDisableInteractions(b);
        ActionMap actionMap = getActionMap();

        actionMap.get(SCROLL_RIGHT_ACTION)     .setEnabled(!b);
        actionMap.get(SCROLL_LEFT_ACTION)      .setEnabled(!b);
        actionMap.get(SCROLL_UP_ACTION)        .setEnabled(!b);
        actionMap.get(SCROLL_DOWN_ACTION)      .setEnabled(!b);

        actionMap.get(FAST_SCROLL_RIGHT_ACTION).setEnabled(!b);
        actionMap.get(FAST_SCROLL_LEFT_ACTION) .setEnabled(!b);
        actionMap.get(FAST_SCROLL_UP_ACTION)   .setEnabled(!b);
        actionMap.get(FAST_SCROLL_DOWN_ACTION) .setEnabled(!b);

        actionMap.get(ZOOM_IN_ACTION)          .setEnabled(!b);
        actionMap.get(ZOOM_OUT_ACTION)         .setEnabled(!b);
        actionMap.get(RESET_TRANSFORM_ACTION)  .setEnabled(!b);
    }


        /**
     * Builds the InputMap of this canvas with a set of predefined
     * <code>Action</code>s.
     */
    protected void installKeyboardActions() {

        InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED);
        KeyStroke key;

        key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
        inputMap.put(key, SCROLL_RIGHT_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
        inputMap.put(key, SCROLL_LEFT_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
        inputMap.put(key, SCROLL_UP_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
        inputMap.put(key, SCROLL_DOWN_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.SHIFT_DOWN_MASK);
        inputMap.put(key, FAST_SCROLL_RIGHT_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.SHIFT_DOWN_MASK);
        inputMap.put(key, FAST_SCROLL_LEFT_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.SHIFT_DOWN_MASK);
        inputMap.put(key, FAST_SCROLL_UP_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.SHIFT_DOWN_MASK);
        inputMap.put(key, FAST_SCROLL_DOWN_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_DOWN_MASK);
        inputMap.put(key, ZOOM_IN_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK);
        inputMap.put(key, ZOOM_OUT_ACTION);

        key = KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK);
        inputMap.put(key, RESET_TRANSFORM_ACTION);
    }

    /**
     * Adds the specified <code>PropertyChangeListener</code>.
     *
     * @param pcl the property change listener to add
     */
    public void addPropertyChangeListener(PropertyChangeListener pcl) {
        pcs.addPropertyChangeListener(pcl);
    }

    /**
     * Removes the specified <code>PropertyChangeListener</code>.
     *
     * @param pcl the property change listener to remove
     */
    public void removePropertyChangeListener(PropertyChangeListener pcl) {
        pcs.removePropertyChangeListener(pcl);
    }

    /**
     * Adds the specified <code>PropertyChangeListener</code> for the specified
     * property.
     *
     * @param propertyName the name of the property to listen on
     * @param pcl the property change listener to add
     */
    public void addPropertyChangeListener(String propertyName,
                                          PropertyChangeListener pcl) {
        pcs.addPropertyChangeListener(propertyName, pcl);
    }

    /**
     * Removes the specified <code>PropertyChangeListener</code> for the specified
     * property.
     *
     * @param propertyName the name of the property that was listened on
     * @param pcl the property change listener to remove
     */
    public void removePropertyChangeListener(String propertyName,
                                             PropertyChangeListener pcl) {
        pcs.removePropertyChangeListener(propertyName, pcl);
    }

    /**
     * Determines whether the zoom interactor is enabled or not.
     */
    public void setEnableZoomInteractor(boolean b) {
        if (isZoomInteractorEnabled != b) {
            boolean oldValue = isZoomInteractorEnabled;
            isZoomInteractorEnabled = b;
            if (isZoomInteractorEnabled) {
                getInteractors().add(zoomInteractor);
            } else {
                getInteractors().remove(zoomInteractor);
            }
            pcs.firePropertyChange("enableZoomInteractor", oldValue, b);
        }
    }

    /**
     * Returns true if the zoom interactor is enabled, false otherwise.
     */
    public boolean getEnableZoomInteractor() {
        return isZoomInteractorEnabled;
    }

    /**
     * Determines whether the image zoom interactor is enabled or not.
     */
    public void setEnableImageZoomInteractor(boolean b) {
        if (isImageZoomInteractorEnabled != b) {
            boolean oldValue = isImageZoomInteractorEnabled;
            isImageZoomInteractorEnabled = b;
            if (isImageZoomInteractorEnabled) {
                getInteractors().add(imageZoomInteractor);
            } else {
                getInteractors().remove(imageZoomInteractor);
            }
            pcs.firePropertyChange("enableImageZoomInteractor", oldValue, b);
        }
    }

    /**
     * Returns true if the image zoom interactor is enabled, false otherwise.
     */
    public boolean getEnableImageZoomInteractor() {
        return isImageZoomInteractorEnabled;
    }

    /**
     * Determines whether the pan interactor is enabled or not.
     */
    public void setEnablePanInteractor(boolean b) {
        if (isPanInteractorEnabled != b) {
            boolean oldValue = isPanInteractorEnabled;
            isPanInteractorEnabled = b;
            if (isPanInteractorEnabled) {
                getInteractors().add(panInteractor);
            } else {
                getInteractors().remove(panInteractor);
            }
            pcs.firePropertyChange("enablePanInteractor", oldValue, b);
        }
    }

    /**
     * Returns true if the pan interactor is enabled, false otherwise.
     */
    public boolean getEnablePanInteractor() {
        return isPanInteractorEnabled;
    }

    /**
     * Determines whether the rotate interactor is enabled or not.
     */
    public void setEnableRotateInteractor(boolean b) {
        if (isRotateInteractorEnabled != b) {
            boolean oldValue = isRotateInteractorEnabled;
            isRotateInteractorEnabled = b;
            if (isRotateInteractorEnabled) {
                getInteractors().add(rotateInteractor);
            } else {
                getInteractors().remove(rotateInteractor);
            }
            pcs.firePropertyChange("enableRotateInteractor", oldValue, b);
        }
    }

    /**
     * Returns true if the rotate interactor is enabled, false otherwise.
     */
    public boolean getEnableRotateInteractor() {
        return isRotateInteractorEnabled;
    }

    /**
     * Determines whether the reset transform interactor is enabled or not.
     */
    public void setEnableResetTransformInteractor(boolean b) {
        if (isResetTransformInteractorEnabled != b) {
            boolean oldValue = isResetTransformInteractorEnabled;
            isResetTransformInteractorEnabled = b;
            if (isResetTransformInteractorEnabled) {
                getInteractors().add(resetTransformInteractor);
            } else {
                getInteractors().remove(resetTransformInteractor);
            }
            pcs.firePropertyChange("enableResetTransformInteractor",
                                   oldValue,
                                   b);
        }
    }

    /**
     * Returns true if the reset transform interactor is enabled, false
     * otherwise.
     */
    public boolean getEnableResetTransformInteractor() {
        return isResetTransformInteractorEnabled;
    }

    /**
     * Returns the URI of the current document.
     */
    public String getURI() {
        return uri;
    }

    /**
     * Sets the URI to the specified uri. If the input 'newURI'
     * string is null, then the canvas will display an empty
     * document.
     *
     * @param newURI the new uri of the document to display
     */
    public void setURI(String newURI) {
        String oldValue = uri;
        this.uri = newURI;
        if (uri != null) {
            loadSVGDocument(uri);
        } else {
            setSVGDocument(null);
        }

        pcs.firePropertyChange("URI", oldValue, uri);
    }

    /**
     * Creates a UserAgent.
     */
    protected UserAgent createUserAgent() {
        return new CanvasUserAgent();
    }

    /**
     * Creates an instance of Listener.
     */
    protected Listener createListener() {
        return new CanvasSVGListener();
    }

    /**
     * To hide the listener methods. This class just reset the tooltip.
     */
    protected class CanvasSVGListener extends SVGListener {

        /**
         * Called when the loading of a document was started.
         */
        public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
            super.documentLoadingStarted(e);
            JSVGCanvas.this.setToolTipText(null);
        }

    }

    protected void installSVGDocument(SVGDocument doc) {
        if (toolTipDocs != null) {
            for (Object o : toolTipDocs.keySet()) {
                SVGDocument ttdoc;
                ttdoc = (SVGDocument) o;
                if (ttdoc == null) continue;

                NodeEventTarget root;
                root = (NodeEventTarget) ttdoc.getRootElement();
                if (root == null) continue;
                root.removeEventListenerNS
                        (XMLConstants.XML_EVENTS_NAMESPACE_URI,
                                SVGConstants.SVG_EVENT_MOUSEOVER,
                                toolTipListener, false);
                root.removeEventListenerNS
                        (XMLConstants.XML_EVENTS_NAMESPACE_URI,
                                SVGConstants.SVG_EVENT_MOUSEOUT,
                                toolTipListener, false);
            }
            toolTipDocs = null;
        }
        lastTarget = null;

        if (toolTipMap != null) {
            toolTipMap.clear();
        }

        super.installSVGDocument(doc);
    }

//     // DOMViewerController
// 
//     /**
//      * DOMViewerController implementation.
//      */
//     protected class CanvasDOMViewerController implements DOMViewerController {
// 
//         public boolean canEdit() {
//             return getUpdateManager() != null;
//         }
// 
//         public ElementOverlayManager createSelectionManager() {
//             if (canEdit()) {
//                 return new ElementOverlayManager(JSVGCanvas.this);
//             }
//             return null;
//         }
// 
//         public Document getDocument() {
//             return svgDocument;
//         }
// 
//         public void performUpdate(Runnable r) {
//             if (canEdit()) {
//                 getUpdateManager().getUpdateRunnableQueue().invokeLater(r);
//             } else {
//                 r.run();
//             }
//         }
// 
//         public void removeSelectionOverlay(Overlay selectionOverlay) {
//             getOverlays().remove(selectionOverlay);
//         }
// 
//         public void selectNode(Node node) {
//             DOMViewer domViewer = new DOMViewer(this);
//             Rectangle fr = getBounds();
//             Dimension td = domViewer.getSize();
//             domViewer.setLocation(fr.x + (fr.width - td.width) / 2,
//                                   fr.y + (fr.height - td.height) / 2);
//             domViewer.setVisible(true);
//             domViewer.selectNode(node);
//         }
//     }

    // ----------------------------------------------------------------------
    // Actions
    // ----------------------------------------------------------------------

    /**
     * A swing action to reset the rendering transform of the canvas.
     */
    public class ResetTransformAction extends AbstractAction {
        public void actionPerformed(ActionEvent evt) {
            fragmentIdentifier = null;
            resetRenderingTransform();
        }
    }

    /**
     * A swing action to append an affine transform to the current
     * rendering transform.  Before the rendering transform is
     * applied the method translates the center of the display to
     * 0,0 so scale and rotate occur around the middle of
     * the display.
     */
    public class AffineAction extends AbstractAction {
        AffineTransform at;
        public AffineAction(AffineTransform at) {
            this.at = at;
        }

        public void actionPerformed(ActionEvent evt) {
            if (gvtRoot == null) {
                return;
            }
            AffineTransform rat = getRenderingTransform();
            if (at != null) {
                Dimension dim = getSize();
                int x = dim.width / 2;
                int y = dim.height / 2;
                AffineTransform t = AffineTransform.getTranslateInstance(x, y);
                t.concatenate(at);
                t.translate(-x, -y);
                t.concatenate(rat);
                setRenderingTransform(t);
            }
        }
    }

    /**
     * A swing action to apply a zoom factor to the canvas.
     * This can be used to zoom in (scale &gt; 1) and out (scale &lt;1).
     */
    public class ZoomAction extends AffineAction {
        public ZoomAction(double scale) {
            super(AffineTransform.getScaleInstance(scale, scale));
        }
        public ZoomAction(double scaleX, double scaleY) {
            super(AffineTransform.getScaleInstance(scaleX, scaleY));
        }
    }

    /**
     * A swing action to zoom in the canvas.
     */
    public class ZoomInAction extends ZoomAction {
        ZoomInAction() { super(2); }
    }

    /**
     * A swing action to zoom out the canvas.
     */
    public class ZoomOutAction extends ZoomAction {
        ZoomOutAction() { super(.5); }
    }

    /**
     * A swing action to Rotate the canvas.
     */
    public class RotateAction extends AffineAction {
        public RotateAction(double theta) {
            super(AffineTransform.getRotateInstance(theta));
        }
    }

    /**
     * A swing action to Pan/scroll the canvas.
     */
    public class ScrollAction extends AffineAction {
        public ScrollAction(double tx, double ty) {
            super(AffineTransform.getTranslateInstance(tx, ty));
        }
    }

    /**
     * A swing action to scroll the canvas to the right,
     * by a fixed amount
     */
    public class ScrollRightAction extends ScrollAction {
        public ScrollRightAction(int inc) {
            super(-inc, 0);
        }
    }

    /**
     * A swing action to scroll the canvas to the left,
     * by a fixed amount
     */
    public class ScrollLeftAction extends ScrollAction {
        public ScrollLeftAction(int inc) {
            super(inc, 0);
        }
    }

    /**
     * A swing action to scroll the canvas up,
     * by a fixed amount
     */
    public class ScrollUpAction extends ScrollAction {
        public ScrollUpAction(int inc) {
            super(0, inc);
        }
    }

    /**
     * A swing action to scroll the canvas down,
     * by a fixed amount
     */
    public class ScrollDownAction extends ScrollAction {
        public ScrollDownAction(int inc) {
            super(0, -inc);
        }
    }

    // ----------------------------------------------------------------------
    // Interactors
    // ----------------------------------------------------------------------

    /**
     * An interactor to perform a zoom.
     * <p>Binding: BUTTON1 + CTRL Key</p>
     */
    protected Interactor zoomInteractor = new AbstractZoomInteractor() {
        public boolean startInteraction(InputEvent ie) {
            int mods = ie.getModifiersEx();
            return
                ie.getID() == MouseEvent.MOUSE_PRESSED &&
                (mods & InputEvent.BUTTON1_DOWN_MASK) != 0 &&
                (mods & InputEvent.CTRL_DOWN_MASK) != 0;
        }
    };

    /**
     * An interactor to perform a realtime zoom.
     * <p>Binding: BUTTON3 + SHIFT Key</p>
     */
    protected Interactor imageZoomInteractor
        = new AbstractImageZoomInteractor() {
        public boolean startInteraction(InputEvent ie) {
            int mods = ie.getModifiersEx();
            return
                ie.getID() == MouseEvent.MOUSE_PRESSED &&
                (mods & InputEvent.BUTTON3_DOWN_MASK) != 0 &&
                (mods & InputEvent.SHIFT_DOWN_MASK) != 0;
        }
    };

    /**
     * An interactor to perform a translation.
     * <p>Binding: BUTTON1 + SHIFT Key</p>
     */
    protected Interactor panInteractor = new AbstractPanInteractor() {
        public boolean startInteraction(InputEvent ie) {
            int mods = ie.getModifiersEx();
            return
                ie.getID() == MouseEvent.MOUSE_PRESSED &&
                (mods & InputEvent.BUTTON1_DOWN_MASK) != 0 &&
                (mods & InputEvent.SHIFT_DOWN_MASK) != 0;
        }
    };

    /**
     * An interactor to perform a rotation.
     * <p>Binding: BUTTON3 + CTRL Key</p>
     */
    protected Interactor rotateInteractor = new AbstractRotateInteractor() {
        public boolean startInteraction(InputEvent ie) {
            int mods = ie.getModifiersEx();
            return
                ie.getID() == MouseEvent.MOUSE_PRESSED &&
                (mods & InputEvent.BUTTON3_DOWN_MASK) != 0 &&
                (mods & InputEvent.CTRL_DOWN_MASK) != 0;
        }
    };

    /**
     * An interactor to reset the rendering transform.
     * <p>Binding: CTRL+SHIFT+BUTTON3</p>
     */
    protected Interactor resetTransformInteractor =
        new AbstractResetTransformInteractor() {
        public boolean startInteraction(InputEvent ie) {
            int mods = ie.getModifiersEx();
            return
                ie.getID() == MouseEvent.MOUSE_CLICKED &&
                (mods & InputEvent.BUTTON3_DOWN_MASK) != 0 &&
                (mods & InputEvent.SHIFT_DOWN_MASK) != 0 &&
                (mods & InputEvent.CTRL_DOWN_MASK) != 0;
        }
    };

    // ----------------------------------------------------------------------
    // User agent implementation
    // ----------------------------------------------------------------------

    /**
     * The <code>CanvasUserAgent</code> only adds tooltips to the behavior of the
     * default <code>BridgeUserAgent</code>. A tooltip will be displayed
     * wheneven the mouse lingers over an element which has a &lt;title&gt; or a
     * &lt;desc&gt; child element.
     */
    protected class CanvasUserAgent extends BridgeUserAgent

        implements XMLConstants {

        final String TOOLTIP_TITLE_ONLY
            = "JSVGCanvas.CanvasUserAgent.ToolTip.titleOnly";
        final String TOOLTIP_DESC_ONLY
            = "JSVGCanvas.CanvasUserAgent.ToolTip.descOnly";
        final String TOOLTIP_TITLE_AND_TEXT
            = "JSVGCanvas.CanvasUserAgent.ToolTip.titleAndDesc";

        /**
         * The handleElement method builds a tool tip from the
         * content of a &lt;title&gt; element, a &lt;desc&gt;
         * element or both. <br>
         * Because these elements can appear in any order, here
         * is the algorithm used to build the tool tip:<br>
         * <ul>
         * <li>If a &lt;title&gt; is passed to <code>handleElement</code>
         *     the method checks if there is a &gt;desc&gt; peer. If
         *     there is one, nothing is done (because the desc will do
         *     it). If there in none, the tool tip is set to the value
         *     of the &lt;title&gt; element content.</li>
         * <li>If a &lt;desc&gt; is passed to <code>handleElement</code>
         *     the method checks if there is a &lt;title&gt; peer. If there
         *     is one, the content of that peer is pre-pended to the
         *     content of the &lt;desc&gt; element.</li>
         * </ul>
         */
        public void handleElement(Element elt, Object data){
            super.handleElement(elt, data);

            // Don't handle tool tips unless we are interactive.
            if (!isInteractive()) return;

            if (!SVGConstants.SVG_NAMESPACE_URI.equals(elt.getNamespaceURI()))
                return;

            // Don't handle tool tips for the root SVG element.
            if (elt.getParentNode() ==
                elt.getOwnerDocument().getDocumentElement()) {
                return;
            }

            Element parent;
            // When node is removed data is old parent node
            // since we can't get it otherwise.
            if (data instanceof Element) parent = (Element)data;
            else                         parent = (Element)elt.getParentNode();

            Element descPeer = null;
            Element titlePeer = null;
            if (elt.getLocalName().equals(SVGConstants.SVG_TITLE_TAG)) {
                if (data == Boolean.TRUE)
                    titlePeer = elt;
                descPeer = getPeerWithTag(parent,
                                           SVGConstants.SVG_NAMESPACE_URI,
                                           SVGConstants.SVG_DESC_TAG);
            } else if (elt.getLocalName().equals(SVGConstants.SVG_DESC_TAG)) {
                if (data == Boolean.TRUE)
                    descPeer = elt;
                titlePeer = getPeerWithTag(parent,
                                           SVGConstants.SVG_NAMESPACE_URI,
                                           SVGConstants.SVG_TITLE_TAG);
            }

            String titleTip = null;
            if (titlePeer != null) {
                titlePeer.normalize();
                if (titlePeer.getFirstChild() != null)
                    titleTip = titlePeer.getFirstChild().getNodeValue();
            }

            String descTip = null;
            if (descPeer != null) {
                descPeer.normalize();
                if (descPeer.getFirstChild() != null)
                    descTip = descPeer.getFirstChild().getNodeValue();
            }

            final String toolTip;
            if ((titleTip != null) && (titleTip.length() != 0)) {
                if ((descTip != null) && (descTip.length() != 0)) {
                    toolTip = Messages.formatMessage
                        (TOOLTIP_TITLE_AND_TEXT,
                         new Object[] { toFormattedHTML(titleTip),
                                        toFormattedHTML(descTip)});
                } else {
                    toolTip = Messages.formatMessage
                        (TOOLTIP_TITLE_ONLY,
                         new Object[]{toFormattedHTML(titleTip)});
                }
            } else {
                if ((descTip != null) && (descTip.length() != 0)) {
                    toolTip = Messages.formatMessage
                        (TOOLTIP_DESC_ONLY,
                         new Object[]{toFormattedHTML(descTip)});
                } else {
                    toolTip = null;
                }
            }

            if (toolTip == null) {
                removeToolTip(parent);
                return;
            }

            if (lastTarget != parent) {
                setToolTip(parent, toolTip);
            } else {
                // Already has focus check if it already has tip text.
                Object o = null;
                if (toolTipMap != null) {
                    o = toolTipMap.get(parent);
                    toolTipMap.put(parent, toolTip);
                }

                if (o != null) {
                    // Update components tooltip text now.
                    EventQueue.invokeLater(new Runnable() {
                            public void run() {
                                setToolTipText(toolTip);
                                MouseEvent e = new MouseEvent
                                    (JSVGCanvas.this,
                                     MouseEvent.MOUSE_MOVED,
                                     System.currentTimeMillis(),
                                     0,
                                     locationListener.getLastX(),
                                     locationListener.getLastY(),
                                     0,
                                     false);
                                ToolTipManager.sharedInstance().mouseMoved(e);
                            }
                        });
                } else {
                    EventQueue.invokeLater(new ToolTipRunnable(toolTip));
                }
            }
        }

        /**
         * Converts line breaks to HTML breaks and encodes special entities.
         * Poor way of replacing '&lt;', '&gt;' and '&amp;' in content.
         */
        public String toFormattedHTML(String str) {
            StringBuffer sb = new StringBuffer(str);
            replace(sb, XML_CHAR_AMP, XML_ENTITY_AMP);  // Must go first!
            replace(sb, XML_CHAR_LT, XML_ENTITY_LT);
            replace(sb, XML_CHAR_GT, XML_ENTITY_GT);
            replace(sb, XML_CHAR_QUOT, XML_ENTITY_QUOT);
            // Dont' quote "'" apostrphe since the display doesn't
            // seem to understand it.
            // replace(sb, XML_CHAR_APOS, XML_ENTITY_APOS);
            replace(sb, '\n', "<br>");
            return sb.toString();
        }

        protected void replace(StringBuffer sb, char c, String r) {
            String v = sb.toString();
            int i = v.length();

            while( (i=v.lastIndexOf(c, i-1)) != -1 ) {
                sb.deleteCharAt(i);
                sb.insert(i, r);
            }
        }

        /**
         * Checks if there is a peer element of a given type.  This returns the
         * first occurence of the given type or null if none is found.
         */
        public Element getPeerWithTag(Element parent,
                                      String nameSpaceURI,
                                      String localName) {

            Element p = parent;
            if (p == null) {
                return null;
            }

            for (Node n=p.getFirstChild(); n!=null; n = n.getNextSibling()) {
                if (!nameSpaceURI.equals(n.getNamespaceURI())){
                    continue;
                }
                if (!localName.equals(n.getLocalName())){
                    continue;
                }
                if (n.getNodeType() == Node.ELEMENT_NODE) {
                    return (Element)n;
                }
            }
            return null;
        }

        /**
         * Returns a boolean defining whether or not there is a peer of
         * <code>elt</code> with the given qualified tag.
         */
        public boolean hasPeerWithTag(Element elt,
                                      String nameSpaceURI,
                                      String localName){

            return !(getPeerWithTag(elt, nameSpaceURI, localName) == null);
        }

        /**
         * Sets the tool tip on the input element.
         */
        public void setToolTip(Element elt, String toolTip){
            if (toolTipMap == null) {
                toolTipMap = new WeakHashMap();
            }
            if (toolTipDocs == null) {
                toolTipDocs = new WeakHashMap();
            }
            SVGDocument doc = (SVGDocument)elt.getOwnerDocument();
            if (toolTipDocs.put(doc, MAP_TOKEN) == null) {
                NodeEventTarget root;
                root = (NodeEventTarget)doc.getRootElement();
                // On mouseover, it sets the tooltip to the given value
                root.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
                                        SVGConstants.SVG_EVENT_MOUSEOVER,
                                        toolTipListener,
                                        false, null);
                // On mouseout, it removes the tooltip
                root.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
                                        SVGConstants.SVG_EVENT_MOUSEOUT,
                                        toolTipListener,
                                        false, null);
            }

            toolTipMap.put(elt, toolTip);

            if (elt == lastTarget)
                EventQueue.invokeLater(new ToolTipRunnable(toolTip));
        }

        public void removeToolTip(Element elt) {
            if (toolTipMap != null)
                toolTipMap.remove(elt);
            if (lastTarget == elt) { // clear ToolTip.
                EventQueue.invokeLater(new ToolTipRunnable(null));
            }
        }

        /**
         * Displays an error message in the User Agent interface.
         */
        public void displayError(String message) {
            if (svgUserAgent != null) {
                super.displayError(message);
            } else {
                JOptionPane pane =
                    new JOptionPane(message, JOptionPane.ERROR_MESSAGE);
                JDialog dialog =
                    pane.createDialog(JSVGCanvas.this, "ERROR");
                dialog.setModal(false);
                dialog.setVisible(true); // Safe to be called from any thread
            }
        }

        /**
         * Displays an error resulting from the specified Exception.
         */
        public void displayError(Exception ex) {
            if (svgUserAgent != null) {
                super.displayError(ex);
            } else {
                JErrorPane pane =
                    new JErrorPane(ex, JOptionPane.ERROR_MESSAGE);
                JDialog dialog = pane.createDialog(JSVGCanvas.this, "ERROR");
                dialog.setModal(false);
                dialog.setVisible(true); // Safe to be called from any thread
            }
        }
    }

    // ----------------------------------------------------------------------
    // Tooltip
    // ----------------------------------------------------------------------

    /**
     * Sets the time and element of the last tool tip event handled.
     */
    public void setLastToolTipEvent(long t, EventTarget et) {
        lastToolTipEventTimeStamp = t;
        lastToolTipEventTarget = et;
    }

    /**
     * Checks if the specified event time and element are the same
     * as the last tool tip event.
     */
    public boolean matchLastToolTipEvent(long t, EventTarget et) {
        return lastToolTipEventTimeStamp == t
            && lastToolTipEventTarget == et;
    }

    /**
     * Helper class. Simply keeps track of the last known mouse
     * position over the canvas.
     */
    protected class LocationListener extends MouseMotionAdapter {

        protected int lastX, lastY;

        public LocationListener () {
            lastX = 0; lastY = 0;
        }

        public void mouseMoved(MouseEvent evt) {
            lastX = evt.getX();
            lastY = evt.getY();
        }

        public int getLastX() {
            return lastX;
        }

        public int getLastY() {
            return lastY;
        }
    }

    /**
     * Sets a specific tooltip on the JSVGCanvas when a given event occurs.
     * This listener is used in the handleElement method to set, remove or
     * modify the JSVGCanvas tooltip on mouseover and on mouseout.<br>
     *
     * Because we are on a single <code>JComponent</code> we trigger an artificial
     * <code>MouseEvent</code> when the toolTip is set to a non-null value, so as
     * to make sure it will show after the <code>ToolTipManager</code>'s default
     * delay.
     */
    protected class ToolTipModifier implements EventListener {
        /**
         * The CanvasUserAgent used to track the last tool tip event.
         */
        protected CanvasUserAgent canvasUserAgent;

        /**
         * Creates a new ToolTipModifier object.
         */
        public ToolTipModifier() {
        }

        public void handleEvent(Event evt){
            // Don't set the tool tip if another ToolTipModifier
            // has already handled this event (as it will have been
            // a higher priority tool tip).
            if (matchLastToolTipEvent(evt.getTimeStamp(), evt.getTarget())) {
                return;
            }
            setLastToolTipEvent(evt.getTimeStamp(), evt.getTarget());
            EventTarget prevLastTarget = lastTarget;
            if (SVGConstants.SVG_EVENT_MOUSEOVER.equals(evt.getType())) {
                lastTarget = evt.getTarget();
            } else if (SVGConstants.SVG_EVENT_MOUSEOUT.equals(evt.getType())) {
                // related target is one it is entering or null.
                org.w3c.dom.events.MouseEvent mouseEvt;
                mouseEvt = ((org.w3c.dom.events.MouseEvent)evt);
                lastTarget = mouseEvt.getRelatedTarget();
            }

            if (toolTipMap != null) {
                Element e = (Element)lastTarget;
                Object o = null;
                while (e != null) {
                    // Search the parents of the current node for ToolTips.
                    o = toolTipMap.get(e);
                    if (o != null) {
                        break;
                    }
                    e = CSSEngine.getParentCSSStylableElement(e);
                }
                final String theToolTip = (String)o;
                if (prevLastTarget != lastTarget)
                    EventQueue.invokeLater(new ToolTipRunnable(theToolTip));
            }
        }
    }

    protected class ToolTipRunnable implements Runnable {
        String theToolTip;
        public ToolTipRunnable(String toolTip) {
            this.theToolTip = toolTip;
        }

        public void run() {
            setToolTipText(theToolTip);

            MouseEvent e;
            if (theToolTip != null) {
                e = new MouseEvent
                    (JSVGCanvas.this,
                     MouseEvent.MOUSE_ENTERED,
                     System.currentTimeMillis(),
                     0,
                     locationListener.getLastX(),
                     locationListener.getLastY(),
                     0,
                     false);
                ToolTipManager.sharedInstance().mouseEntered(e);
                e = new MouseEvent
                    (JSVGCanvas.this,
                     MouseEvent.MOUSE_MOVED,
                     System.currentTimeMillis(),
                     0,
                     locationListener.getLastX(),
                     locationListener.getLastY(),
                     0,
                     false);
                ToolTipManager.sharedInstance().mouseMoved(e);
            } else {
                e = new MouseEvent
                    (JSVGCanvas.this,
                     MouseEvent.MOUSE_MOVED,
                     System.currentTimeMillis(),
                     0,
                     locationListener.getLastX(),
                     locationListener.getLastY(),
                     0,
                     false);
                ToolTipManager.sharedInstance().mouseMoved(e);
            }
        }
    }
}
