/**************************************************************
 * 
 * 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 javax.swing.*;
import java.awt.Dimension;
import java.awt.*;
import java.awt.geom.*;

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

import com.sun.star.awt.Point;
import com.sun.star.awt.Size;
import com.sun.star.uno.UnoRuntime;


/** Display the currently focused accessible object graphically.
*/
public class GraphicalDisplay
    extends JPanel
    implements IAccessibleObjectDisplay
{
    /** Create a new graphical widget the displays some of the geometrical
        information availbable from accessible objects.
    */
    public GraphicalDisplay ()
    {
        setPreferredSize (new Dimension (300,200));
    }


    /** Paint some or all of the area of this widget with the outlines of
        the currently focues object and its ancestors.
     */
    public synchronized void paintComponent (Graphics g)
    {
        super.paintComponent (g);

        setupTransformation ();

        // Draw the screen representation to give a hint of the location of the
        // accessible object on the screen.
        Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
        // Fill the screen rectangle.
        g.setColor (new Color (250,240,230));
        g.fillRect (
            (int)(mnHOffset+0.5),
            (int)(mnVOffset+0.5),
            (int)(mnScale*aScreenSize.getWidth()),
            (int)(mnScale*aScreenSize.getHeight()));
        // Draw a frame around the screen rectangle to increase its visibility.
        g.setColor (Color.BLACK);
        g.drawRect (
            (int)(mnHOffset+0.5),
            (int)(mnVOffset+0.5),
            (int)(mnScale*aScreenSize.getWidth()),
            (int)(mnScale*aScreenSize.getHeight()));

        // Now do the actual display of the accessible object.
        drawAccessibleObject (g, mxContext, Color.GREEN);
    }
    public synchronized void paintChildren (Graphics g)
    {
    }
    public synchronized void paintBorder (Graphics g)
    {
    }




    /** Draw a simple representation of the given accessible object in the
        specified color.
    */
    public void drawAccessibleObject (Graphics g, XAccessibleContext xContext, Color aColor)
    {
        if (xContext != null)
        {
            // First draw our parent.
            XAccessible xParent = xContext.getAccessibleParent();
            if (xParent != null)
                drawAccessibleObject (g, xParent.getAccessibleContext(), Color.GRAY);
            
            // When the context supports the XAccessibleComponent interface
            // then draw its outline.
            XAccessibleComponent xComponent = 
                (XAccessibleComponent)UnoRuntime.queryInterface(
                    XAccessibleComponent.class, xContext);
            if (xComponent != null)
            {
                // Get size and location on screen and transform them to fit
                // everything inside this widget.
                Point aLocation = xComponent.getLocationOnScreen();
                Size aSize = xComponent.getSize();
                g.setColor (aColor);
                g.drawRect (
                    (int)(mnHOffset + mnScale*aLocation.X+0.5),
                    (int)(mnVOffset + mnScale*aLocation.Y+0.5),
                    (int)(mnScale*aSize.Width),
                    (int)(mnScale*aSize.Height));
            }
        }
    }


    public synchronized void setAccessibleObject (XAccessibleContext xContext)
    {
        mxContext = xContext;
        repaint ();
    }

    public synchronized void updateAccessibleObject (XAccessibleContext xContext)
    {
        repaint ();
    }


    /** Set up the transformation so that the graphical display can show a
        centered representation of the whole screen.
    */
    private void setupTransformation ()
    {
        Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension aWidgetSize = getSize();
        if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
        {
            // 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;

            // 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;
        }
        else
        {
            // In case of a degenerate (not yet initialized?) screen size
            // use some meaningless default values.
            mnScale = 1;
            mnHOffset = 0;
            mnVOffset = 0;
        }
    }


    private XAccessibleContext mxContext;
    private double mnScale;
    private double mnHOffset;
    private double mnVOffset;
}
