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

import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.PropertyChangeEvent;

import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleComponent;
import com.sun.star.accessibility.XAccessibleExtendedComponent;
import com.sun.star.accessibility.XAccessibleText;
import com.sun.star.accessibility.XAccessibleStateSet;
import com.sun.star.accessibility.AccessibleStateType;

class CanvasShape
{
    public final Color maHighlightColor = Color.red;
    public final Color maSelectionColor = Color.green;
    public final Color maFocusColor = Color.blue;

    //    public AccessibleObject (XAccessibleContext xContext, TreePath aPath)
    public CanvasShape (AccTreeNode aNode)
    {
        maNode = aNode;
        mxContext = aNode.getContext();
        msName = "name unknown";
        msDescription = "description unknown";
        maShape = new Rectangle2D.Double (-10,-10,10,10);
        maPosition = new Point (-10,-10);
        maSize = new Dimension (10,10);
        maFgColor = java.awt.Color.black;
        maBgColor = Color.blue;
        mnRole = -1;
        mbHighlighted = false;
        mbSelected = false;
        mbFocused = false;
        mxComponent = aNode.getComponent();

        update ();
    }



    /** Update the data obtained from the xAccessible.
    */
    public void update ()
    {
        if (mxContext != null)
        {
            msName = mxContext.getAccessibleName();
            msDescription = mxContext.getAccessibleDescription();
            mnRole = mxContext.getAccessibleRole();

            // Extract the selected and focused flag.
            XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet ();
            if (xStateSet != null)
            {
                mbSelected = xStateSet.contains (AccessibleStateType.SELECTED);
                mbFocused = xStateSet.contains (AccessibleStateType.FOCUSED);
            }
        }
         
        updateGeometry ();
        if (mxComponent != null)
        {
            // Note: alpha values in office 0..255 have to be mapped to
            //       255..0 in Java
            Color aCol = new Color (mxComponent.getForeground(), true);
            maFgColor = new Color (aCol.getRed (),
                                   aCol.getGreen (),
                                   aCol.getBlue (),
                                   0xff - aCol.getAlpha ());
            aCol = new Color (mxComponent.getBackground(), true);
            maBgColor = new Color (aCol.getRed (),
                                   aCol.getGreen (),
                                   aCol.getBlue (),
                                   0xff - aCol.getAlpha ());
        }
    }

    public void updateGeometry ()
    {
        if (mxComponent != null)
        {
            com.sun.star.awt.Point aLocationOnScreen = mxComponent.getLocationOnScreen();
            com.sun.star.awt.Size aSizeOnScreen = mxComponent.getSize();
            maPosition = new Point (
                aLocationOnScreen.X,
                aLocationOnScreen.Y);
            maSize = new Dimension (
                aSizeOnScreen.Width,
                aSizeOnScreen.Height);
        }
    }


    /** Paint the object into the specified canvas.  It is transformed
        according to the specified offset and scale.
    */
    public void paint (Graphics2D g, 
        double nXOffset, double nYOffset, double nScaleFactor,
        boolean bShowDescription, boolean bShowName, boolean bShowText)
    {
        try{
            // Transform the object's position and size according to the
            // specified offset and scale.
            Point aLocation = new Point();
            maShape = new Rectangle2D.Double (
                maPosition.x * nScaleFactor + nXOffset,
                maPosition.y * nScaleFactor + nYOffset,
                maSize.width * nScaleFactor,
                maSize.height * nScaleFactor);
            
            // Fill the object's bounding box with its background color if it
            // has no children.
            if (mxContext.getAccessibleChildCount() == 0)
            {
                g.setColor (maBgColor);
                g.fill (maShape);
            }

            // Remove alpha channel from color before drawing the frame.
            Color color = maFgColor;
            if (maFgColor.getAlpha()<128)
                color = new Color (maFgColor.getRed(), maFgColor.getGreen(), maFgColor.getBlue());
            g.setColor (color);
            g.draw (maShape);
            
            if (mbFocused)
            {
                g.setColor (maFocusColor);
                for (int x=0; x<=2; x++)
                    for (int y=0; y<=2; y++)
                        g.fill (
                            new Rectangle2D.Double (
                                maShape.x + x/2.0 * maShape.width-3,
                                maShape.y + y/2.0 * maShape.height-3,
                                6,
                                6));
            }
            if (mbSelected)
            {
                g.setColor (maSelectionColor);
                for (int x=0; x<=2; x++)
                    for (int y=0; y<=2; y++)
                        g.draw (
                            new Rectangle2D.Double (
                                maShape.x + x/2.0 * maShape.width-2,
                                maShape.y + y/2.0 * maShape.height-2,
                                4,
                                4));
            }

            // Write the object's text OR name and description.
            g.setColor (maFgColor);
            if (bShowName)
                paintName (g);
            if (bShowDescription)
                paintDescription (g);
            if (bShowText)
                paintText (g);
        }
        catch (Exception e)
        { // don't care
        }
    }

    public void paint_highlight (Graphics2D g, 
        double nXOffset, double nYOffset, double nScaleFactor)
    {
        if (mbHighlighted)
            g.setColor (maHighlightColor);
        else
            g.setColor (maFgColor);
        g.draw (maShape);
    }




    private void paintName (Graphics2D g)
    {
        g.drawString ("Name: " + msName, 
            (float)maShape.x+5, 
            (float)maShape.y+15); 
    }



    private void paintDescription (Graphics2D g)
    {
        g.drawString ("Description: " + msDescription, 
            (float)maShape.x+5, 
            (float)maShape.y+35); 
    }




    private void paintText (Graphics2D g)
    {
        XAccessibleText xText = null;
        // get XAccessibleText
        xText = maNode.getText();

        // Draw every character in the text string.
        if (xText != null)
        {
            String sText = xText.getText();
            try
            {
                for(int i = 0; i < sText.length(); i++)
                {
                    com.sun.star.awt.Rectangle aRect =
                        xText.getCharacterBounds(i);
                    
                    double x = maShape.x + aRect.X;
                    double y = maShape.y + aRect.Y + aRect.Height;
                    
                    g.drawString(sText.substring(i, i+1), (float)x, (float)y);
                }
            }
            catch (com.sun.star.lang.IndexOutOfBoundsException e)
            {}
        }
    }




    /** Callback for disposing events.
    */
    public void disposing (com.sun.star.lang.EventObject e)
    {
        System.out.println ("Disposing");
    }




    /** Compute whether the specified point lies inside the object's
        bounding box.
    */
    public boolean contains (int x, int y)
    {
        return (maShape.contains (x,y));
    }

    public void highlight ()
    {
        mbHighlighted = true;
    }

    public void unhighlight ()
    {
        mbHighlighted = false;
    }

    public boolean isHighlighted ()
    {
        return mbHighlighted;
    }

    public Rectangle getBBox ()
    {
        return new Rectangle (maPosition, maSize);
    }
    
    public Point getOrigin ()
    {
        return maPosition;
    }

    public TreePath getPath ()
    {
        return new TreePath (maNode.createPath());
    }

    public int getRole ()
    {
        return mnRole;
    }

    public XAccessibleContext getContext ()
    {
        return mxContext;
    }

    public XAccessibleComponent getComponent ()
    {
        return mxComponent;
    }

    public String toString ()
    {
        return ">"+msName+", "+msDescription+" +"+maPosition.x+"+"+maPosition.y
            +"x"+maSize.width+"x"+maSize.height+"<";
    }

    private AccTreeNode
        maNode;
    private XAccessibleContext
        mxContext;
    private XAccessibleComponent
        mxComponent;
    private String
        msDescription,
        msName;
    private Rectangle2D.Double
        maShape;
    private Point
        maPosition;
    private Dimension
        maTransformedSize,
        maSize;
    private Color
        maFgColor,
        maBgColor;
    private boolean
        // Highlighting objects is an internal concept.  Corresponds to selection in the tree view.
        mbHighlighted,
        // Set when the accessible object is selected.
        mbSelected,
        // Set when the accessible object is focused.
        mbFocused;
    private int
        mnRole;
}
