/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import java.awt.geom.Rectangle2D;

import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleComponent;

/** This canvas displays accessible objects graphically.  Each accessible
    object with graphical representation is represented by an
    CanvasShape object and has to be added by the
    <member>addAccessible</member> member function.

    <p>The canvas listens to selection events of the associated JTree and
    highlights the first selected node of that tree.</p>
*/
class Canvas 
    extends JPanel
    implements MouseListener, MouseMotionListener, TreeSelectionListener//, Scrollable
{
    // This constant can be passed to SetZoomMode to always show the whole screen.
    public static final int WHOLE_SCREEN = -1;

    public Canvas ()
    {
        super (true);
        maObjects = new java.util.HashMap ();
        maNodes = new Vector ();
        maObjectList = new Vector ();
        maContexts = new Vector ();
        addMouseListener (this);
        addMouseMotionListener (this);
        maBoundingBox = new Rectangle (0,0,100,100);
        maTree = null;
        mnHOffset = 0;
        mnVOffset = 0;
        mnScale = 1;
        setShowText(false);
        setShowDescriptions (true);
        setShowNames (true);
        setAntialiasing (true);
        maLastWidgetSize = new Dimension (0,0);
    }

    /** Tell the canvas which tree view to use to highlight accessible
        objects. 
    */
    public void setTree (JTree aTree)
    {
        if (maTree != null)
            maTree.removeTreeSelectionListener (this);
        maTree = aTree;
        if (maTree != null)
            maTree.addTreeSelectionListener (this);
    }




    public void addNode (AccTreeNode aNode)
    {
        if (maNodes.indexOf (aNode) == -1)
        {
            maNodes.add (aNode);
            
            CanvasShape aObject = (CanvasShape) maObjects.get (aNode);
            if (aObject == null)
            {
                aObject = new CanvasShape (aNode);
                // Update bounding box that includes all objects.
                if (maObjects.size() == 0)
                    maBoundingBox = aObject.getBBox();
                else
                    maBoundingBox = maBoundingBox.union (aObject.getBBox());
                
                maObjects.put (aNode, aObject);
                maObjectList.add (aObject);

            }
            repaint ();
        }
    }

    public void removeNode (AccTreeNode aNode)
    {
        int i = maNodes.indexOf (aNode);
        if( i != -1 )
        {
            Object aObject = maObjects.get(aNode);
            maObjectList.remove (aObject);
            maObjects.remove (aObject);
            maNodes.remove (aNode);
            repaint ();
        }
    }

    public void updateNode (AccTreeNode aNode)
    {
        int i = maNodes.indexOf (aNode);
        if (i != -1)
        {
            CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
            if (aObject != null)
                aObject.update();
        }
    }
    
    public void updateNodeGeometry (AccTreeNode aNode)
    {
        CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
        if (aObject != null)
            aObject.updateGeometry();
    }
    
    public void clear ()
    {
        while (maNodes.size() > 0)
            removeNode ((AccTreeNode)maNodes.elementAt(0));

        maNodes.clear();
        maObjects.clear();
        maObjectList.clear();
    }

    public boolean getShowDescriptions ()
    {
        return Options.GetBoolean ("ShowDescriptions");
    }

    public void setShowDescriptions (boolean bNewValue)
    {
        Options.SetBoolean ("ShowDescriptions", bNewValue);
        repaint ();
    }

    public boolean getShowNames ()
    {
        return Options.GetBoolean ("ShowNames");
    }

    public void setShowNames (boolean bNewValue)
    {
        Options.SetBoolean ("ShowNames", bNewValue);
        repaint ();
    }

    public boolean getAntialiasing ()
    {
        return Options.GetBoolean ("Antialiasing");
    }

    public void setAntialiasing (boolean bNewValue)
    {
        Options.SetBoolean ("Antialiasing", bNewValue);
        repaint ();
    }
    
    public boolean getShowText ()
    {
        return Options.GetBoolean ("ShowText");
    }

    public void setShowText (boolean bNewValue)
    {
        Options.SetBoolean ("ShowText", bNewValue);
        repaint ();
    }

    public void setZoomMode (int nZoomMode)
    {
        Options.SetInteger ("ZoomMode", nZoomMode);
        repaint ();
    }

    public int getZoomMode ()
    {
        return Options.GetInteger ("ZoomMode", WHOLE_SCREEN);
    }


    public void paintComponent (Graphics g)
    {
        synchronized (g)
        {
            super.paintComponent (g);

            Graphics2D g2 = (Graphics2D)g;
            if (getAntialiasing())
                g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_ON);
            else
                g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_OFF);

            setupTransformation ();

            // Draw the screen representation to give a hint of the location of the
            // accessible object on the screen.
            Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
            Rectangle2D.Double aScreen = new Rectangle2D.Double (
                mnHOffset,
                mnVOffset,
                mnScale*aScreenSize.getWidth(),
                mnScale*aScreenSize.getHeight());
            // Fill the screen rectangle and draw a frame arround it to increase its visibility.
            g2.setColor (new Color (250,240,230));
            g2.fill (aScreen);
            g2.setColor (Color.BLACK);
            g2.draw (aScreen);
            
            synchronized (maObjectList)
            {
                int nCount = maObjectList.size();
                boolean bShowDescriptions = getShowDescriptions();
                boolean bShowNames = getShowNames();
                boolean bShowText = getShowText();
                for (int i=0; i<nCount; i++)
                {
                    CanvasShape aCanvasShape = (CanvasShape)maObjectList.elementAt(i);
                    aCanvasShape.paint (
                        g2,
                        mnHOffset, mnVOffset, mnScale,
                        bShowDescriptions, bShowNames, bShowText);
                }
            }
            
            // Paint highlighted frame around active object as the last thing.
            if (maActiveObject != null)
                maActiveObject.paint_highlight (
                    g2,
                    mnHOffset, mnVOffset, mnScale);
        }
    }




    /** Set up the transformation so that the graphical display can show a
        centered representation of the whole screen.
    */
    private void setupTransformation ()
    {
        // Turn off scrollbars when showing the whole screen.  Otherwise show them when needed.
        JViewport aViewport = (JViewport)getParent();
        JScrollPane aScrollPane = (JScrollPane)aViewport.getParent();
        int nZoomMode = getZoomMode();
        if (nZoomMode == WHOLE_SCREEN)
        {
            if (aScrollPane.getHorizontalScrollBarPolicy()
                != JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
                aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            if (aScrollPane.getVerticalScrollBarPolicy()
                != JScrollPane.VERTICAL_SCROLLBAR_NEVER)
                aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        }
        else
        {
            if (aScrollPane.getHorizontalScrollBarPolicy()
                != JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
                aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            if (aScrollPane.getVerticalScrollBarPolicy()
                != JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
                aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        }

        Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension aWidgetSize = aViewport.getSize();
        {
            if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
            {
                if (nZoomMode == WHOLE_SCREEN)
                {
                    // Calculate the scales that would map the screen onto the
                    // widget in both of the coordinate axes and select the
                    // smaller
                    // of the two: it maps the screen onto the widget in both 
                    // axes at the same time.
                    double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth();
                    double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight();
                    if (nHScale < nVScale)
                        mnScale = nHScale;
                    else
                        mnScale = nVScale;
                }
                else
                {
                    mnScale = nZoomMode / 100.0;
                }

                // Calculate offsets that center the scaled screen inside the widget.
                mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0;
                mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0;
                if (mnHOffset < 0)
                    mnHOffset = 0;
                if (mnVOffset < 0)
                    mnVOffset = 0;
            
                setPreferredSize (new Dimension (
                    (int)(2*mnHOffset + mnScale * aScreenSize.getWidth()),
                    (int)(2*mnVOffset + mnScale * aScreenSize.getHeight())));
                revalidate ();
            }
            else
            {
                // In case of a degenerate (not yet initialized?) screen size
                // use some meaningless default values.
                mnScale = 1;
                mnHOffset = 0;
                mnVOffset = 0;
            }
        }
        maLastWidgetSize = aWidgetSize;
    }
    
    

    /**  Call getAccessibleAt to determine accessible object under mouse.
    */
    public void mouseClicked (MouseEvent e)
    {
    }

    public void mousePressed (MouseEvent e)
    {
        CanvasShape aObjectUnderMouse = FindCanvasShapeUnderMouse (e);
        highlightObject (aObjectUnderMouse);
        if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)
        {
            maTree.expandPath (aObjectUnderMouse.getPath());
        }
    }

    public void mouseReleased (MouseEvent e)
    {
    }

    public void mouseEntered (MouseEvent e)
    {
    }

    public void mouseExited (MouseEvent e)
    {
        // Deselect currently active object.
        if (maActiveObject != null)
        {
            maActiveObject.unhighlight ();
            maActiveObject = null;
            repaint ();
        }
    }

    public void mouseDragged (MouseEvent e)
    {
    }

    public void mouseMoved (MouseEvent e)
    {
        if ((e.getModifiers() & InputEvent.SHIFT_MASK) != 0)
            highlightObject (FindCanvasShapeUnderMouse (e));
    }

    protected CanvasShape FindCanvasShapeUnderMouse (MouseEvent e)
    {
        int nObjects = maObjects.size();
        CanvasShape aObjectUnderMouse = null;
        int nCount = maObjectList.size();
        for (int i=nCount-1; i>=0; --i)
        {
            CanvasShape aObject = (CanvasShape)maObjectList.elementAt(i);
            if (aObject != null)
                if (aObject.contains (e.getX(),e.getY()))
                {
                    aObjectUnderMouse = aObject;
                    break;
                }
        }
        return aObjectUnderMouse;
    }

    protected boolean highlightObject (CanvasShape aNewActiveObject)
    {
        if (aNewActiveObject != maActiveObject)
        {
            if (maActiveObject != null)
                maActiveObject.unhighlight();
            
            maActiveObject = aNewActiveObject;
            if (maActiveObject != null)
            {
                if (maTree != null)
                {
                    maTree.scrollPathToVisible (maActiveObject.getPath());
                    maTree.setSelectionPath (maActiveObject.getPath());
                    maTree.repaint ();
                }
                maActiveObject.highlight ();
                repaint ();
            }
            return true;
        }
        else
            return false;
    }
    
    /** Called when the selection of the tree changes.  Highlight the
        corresponding graphical representation of the first selected object.
    */
    public void valueChanged (javax.swing.event.TreeSelectionEvent event)
    {
        TreePath aPath = event.getPath();
        Object aObject = aPath.getLastPathComponent();
        if (aObject instanceof AccTreeNode)
        {
            CanvasShape aCanvasShape = (CanvasShape)maObjects.get ((AccTreeNode)aObject);
            if (highlightObject (aCanvasShape))
                repaint();
        }
    }

    private int 
        mnXAnchor,
        mnYAnchor,
        maResizeFlag;
    private double
        mnHOffset,
        mnVOffset,
        mnScale;
    private CanvasShape 
        maActiveObject;
    private java.util.HashMap
        maObjects;
    private Vector 
        maObjectList,
        maContexts,
        maNodes;
    private Rectangle 
        maBoundingBox;
    private JTree
        maTree;
    // The size of the widget at the last call of setupTransformation()
    private Dimension 
        maLastWidgetSize;
}
