/**************************************************************
 *
 * 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 com.sun.star.accessibility.AccessibleTextType;
import com.sun.star.accessibility.TextSegment;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleText;
import com.sun.star.accessibility.XAccessibleEditableText;

import com.sun.star.awt.Rectangle;
import com.sun.star.awt.Point;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.beans.PropertyValue;

import java.util.Vector;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JDialog;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.Icon;
import javax.swing.JTextArea;
import javax.swing.JOptionPane;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.BoxLayout;
import javax.swing.text.JTextComponent;


class AccessibleTextHandler extends NodeHandler
{
    public NodeHandler createHandler (XAccessibleContext xContext)
    {
        XAccessibleText xText = (XAccessibleText) UnoRuntime.queryInterface (
            XAccessibleText.class, xContext);
        if (xText != null)
            return new AccessibleTextHandler (xText);
        else
            return null;
    }

    public AccessibleTextHandler ()
    {
    }

    public AccessibleTextHandler (XAccessibleText xText)
    {
        if (xText != null)
            maChildList.setSize (8);
    }

    public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
    {
        AccessibleTreeNode aChild = null;
        XAccessibleText xText = null;
        if (aParent instanceof AccTreeNode)
            xText = ((AccTreeNode)aParent).getText();

        try
        {
            if( xText != null )
            {
                switch( nIndex )
                {
                    case 0:
                        aChild = new StringNode (xText.getText(), aParent);
                        break;
                    case 1:
                        aChild = new StringNode ("# chars: " + xText.getCharacterCount(), aParent);
                        break;
                    case 2:
                        aChild = new StringNode (characters( xText ), aParent);
                        break;
                    case 3:
                        aChild = new StringNode ("selection: "
                            + "[" + xText.getSelectionStart()
                            + "," + xText.getSelectionEnd()
                            + "] \"" + xText.getSelectedText() + "\"",
                            aParent);
                        break;
                    case 4:
                        aChild = new StringNode ("getCaretPosition: " + xText.getCaretPosition(), aParent);
                        break;
                    case 5:
                    {
                        VectorNode aVec = new VectorNode("portions", aParent);
                        aChild = aVec;
                        aVec.addChild(
                             textAtIndexNode( xText, "Character",
                                              AccessibleTextType.CHARACTER,
                                              aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Word",
                                             AccessibleTextType.WORD,
                                             aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Sentence",
                                             AccessibleTextType.SENTENCE,
                                             aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Paragraph",
                                             AccessibleTextType.PARAGRAPH,
                                             aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Line",
                                             AccessibleTextType.LINE,
                                             aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Attribute",
                                             AccessibleTextType.ATTRIBUTE_RUN,
                                             aParent ) );
                        aVec.addChild(
                            textAtIndexNode( xText, "Glyph",
                                             AccessibleTextType.GLYPH,
                                             aParent ) );
                    }
                    break;
                    case 6:
                        aChild = new StringNode (bounds( xText ), aParent);
                        break;
                    case 7:
                        aChild = getAttributes( xText, aParent );
                        break;
                    default:
                        aChild = new StringNode ("unknown child index " + nIndex, aParent);
                }
            }
        }
        catch (Exception e)
        {
            // Return empty child.
        }

        return aChild;
    }


    private String textAtIndexNodeString(
        int nStart, int nEnd,
        String sWord, String sBefore, String sBehind)
    {
        return "[" + nStart + "," + nEnd + "] "
            + "\"" + sWord + "\"     \t"
            + "(" + sBefore + ","
            + "" + sBehind + ")";
    }

    /** Create a text node that lists all strings of a particular text type
     */
    private AccessibleTreeNode textAtIndexNode(
        XAccessibleText xText,
        String sName,
        short nTextType,
        AccessibleTreeNode aParent)
    {
        VectorNode aNode = new VectorNode (sName, aParent);

        // get word at all positions;
        // for nicer display, compare current word to previous one and
        // make a new node for every interval, not for every word
        int nLength = xText.getCharacterCount();
        if( nLength > 0 )
        {
            try
            {
                // sWord + nStart mark the current word
                // make a node as soon as a new one is found; close the last
                // one at the end
                TextSegment sWord = xText.getTextAtIndex(0, nTextType);
                TextSegment sBefore = xText.getTextBeforeIndex(0, nTextType);
                TextSegment sBehind = xText.getTextBehindIndex(0, nTextType);
                int nStart = 0;
                for(int i = 1; i < nLength; i++)
                {
                    TextSegment sTmp = xText.getTextAtIndex(i, nTextType);
                    TextSegment sTBef = xText.getTextBeforeIndex(i, nTextType);
                    TextSegment sTBeh = xText.getTextBehindIndex(i, nTextType);
                    if( ! ( sTmp.equals( sWord ) && sTBef.equals( sBefore ) &&
                            sTBeh.equals( sBehind ) ) )
                    {
                        aNode.addChild (new StringNode (textAtIndexNodeString(
                            nStart, i,
                            sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
                        sWord = sTmp;
                        sBefore = sTBef;
                        sBehind = sTBeh;
                        nStart = i;
                    }

                    // don't generate more than 50 children.
                    if (aNode.getChildCount() > 50)
                    {
                        sWord.SegmentText = "...";
                        break;
                    }
                }
                aNode.addChild (new StringNode (textAtIndexNodeString(
                    nStart, nLength,
                    sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
            }
            catch( IndexOutOfBoundsException e )
            {
                aNode.addChild (new StringNode (e.toString(), aNode));
            }
            catch (com.sun.star.lang.IllegalArgumentException e)
            {
                aNode.addChild (new StringNode (e.toString(), aNode));
            }
        }

        return aNode;
    }



    /** getCharacter (display as array string) */
    private String characters(XAccessibleText xText)
    {
        // get count (max. 30)
        int nChars = xText.getCharacterCount();
        if( nChars > 30 )
            nChars = 30;

        // build up string
        StringBuffer aChars = new StringBuffer();
        try
        {
            aChars.append( "[" );
            for( int i = 0; i < nChars; i++)
            {
                aChars.append( xText.getCharacter(i) );
                aChars.append( "," );
            }
            if( nChars > 0)
            {
                if( nChars == xText.getCharacterCount() )
                    aChars.deleteCharAt( aChars.length() - 1 );
                else
                    aChars.append( "..." );
            }
            aChars.append( "]" );
        }
        catch( IndexOutOfBoundsException e )
        {
            aChars.append( "   ERROR   " );
        }

        // return result
        return "getCharacters: " + aChars;
    }


    /** iterate over characters, and translate their positions
     * back and forth */
    private String bounds( XAccessibleText xText )
    {
        StringBuffer aBuffer = new StringBuffer( "bounds: " );
        try
        {
            // iterate over characters
            int nCount = xText.getCharacterCount();
            for(int i = 0; i < nCount; i++ )
            {
                // get bounds for this character
                Rectangle aRect = xText.getCharacterBounds( i );

                // get the character by 'clicking' into the middle of
                // the bounds
                Point aMiddle = new Point();
                aMiddle.X = aRect.X + (aRect.Width / 2) - 1;
                aMiddle.Y = aRect.Y + (aRect.Height / 2 ) - 1;
                int nIndex = xText.getIndexAtPoint( aMiddle );

                // get the character, or a '#' for an illegal index
                if( (nIndex >= 0) && (nIndex < xText.getCharacter(i)) )
                    aBuffer.append( xText.getCharacter(nIndex) );
                else
                    aBuffer.append( '#' );
            }
        }
        catch( IndexOutOfBoundsException e )
            { ; } // ignore errors

        return aBuffer.toString();
    }


    private AccessibleTreeNode getAttributes( XAccessibleText xText,
                                  AccessibleTreeNode aParent)
    {
        String[] aAttributeList = new String[] {
            "CharBackColor",
            "CharColor",
            "CharEscapement",
            "CharHeight",
            "CharPosture",
            "CharStrikeout",
            "CharUnderline",
            "CharWeight",
            "ParaAdjust",
            "ParaBottomMargin",
            "ParaFirstLineIndent",
            "ParaLeftMargin",
            "ParaLineSpacing",
            "ParaRightMargin",
            "ParaTabStops"};

        AccessibleTreeNode aRet;

        try
        {
            VectorNode aPortions = new VectorNode ("getAttributes", aParent);

            int nIndex = 0;
            int nLength = xText.getCharacterCount();
            while( nIndex < nLength )
            {
                // get attribute run
                String aPortion = null;
                try
                {
                    aPortion = xText.getTextAtIndex(
                        nIndex, AccessibleTextType.ATTRIBUTE_RUN).SegmentText;
                }
                catch(com.sun.star.lang.IllegalArgumentException e)
                {
                    aPortion = new String ("");
                }

                // get attributes and make node with attribute children
                PropertyValue[] aValues = xText.getCharacterAttributes(nIndex, aAttributeList);
                VectorNode aAttrs = new VectorNode (aPortion, aPortions);
                for( int i = 0; i < aValues.length; i++ )
                {
                    new StringNode( aValues[i].Name + ": " + aValues[i].Value,
                                    aAttrs );
                }

                // get next portion, but advance at least one
                nIndex += (aPortion.length() > 0) ? aPortion.length() : 1;
            }

            aRet = aPortions;
        }
        catch( IndexOutOfBoundsException e )
        {
            aRet = new StringNode( "Exception caught:" + e, aParent );
        }

        return aRet;
    }


    static String[] aTextActions =
        new String[] { "select...", "copy..." };
    static String[] aEditableTextActions =
        new String[] { "select...", "copy...",
                       "cut...", "paste...", "edit...", "format..." };

    public String[] getActions (AccessibleTreeNode aNode)
    {
        XAccessibleEditableText xEText = null;
        if (aNode instanceof AccTreeNode)
            xEText = ((AccTreeNode)aNode).getEditText ();

        return (xEText == null) ? aTextActions : aEditableTextActions;
    }

    public void performAction (AccessibleTreeNode aNode, int nIndex)
    {
        if ( ! (aNode instanceof AccTreeNode))
            return;

        AccTreeNode aATNode = (AccTreeNode)aNode;
        TextActionDialog aDialog = null;

        // create proper dialog
        switch( nIndex )
        {
            case 0:
                aDialog = new TextActionDialog( aATNode,
                                                "Select range:",
                                                "select" )
                    {
                        boolean action(
                            JTextComponent aText, AccTreeNode aNode )
                            throws IndexOutOfBoundsException
                        {
                            return aNode.getText().setSelection(
                                getSelectionStart(),
                                getSelectionEnd() );
                        }
                    };
                break;
            case 1:
                aDialog = new TextActionDialog( aATNode,
                                                "Select range and copy:",
                                                "copy" )
                    {
                        boolean action(
                            JTextComponent aText, AccTreeNode aNode )
                            throws IndexOutOfBoundsException
                        {
                            return aNode.getText().copyText(
                                getSelectionStart(),
                                getSelectionEnd() );
                        }
                    };
                break;
            case 2:
                aDialog = new TextActionDialog( aATNode,
                                                "Select range and cut:",
                                                "cut" )
                    {
                        boolean action(
                            JTextComponent aText, AccTreeNode aNode )
                            throws IndexOutOfBoundsException
                        {
                            return aNode.getEditText().cutText(
                                getSelectionStart(),
                                getSelectionEnd() );
                        }
                    };
                break;
            case 3:
                aDialog = new TextActionDialog( aATNode,
                                                "Place Caret and paste:",
                                                "paste" )
                    {
                        boolean action(
                            JTextComponent aText, AccTreeNode aNode )
                            throws IndexOutOfBoundsException
                        {
                            return aNode.getEditText().pasteText(
                                aText.getCaretPosition() );
                        }
                    };
                break;
            case 4:
                aDialog = new TextEditDialog( aATNode, "Edit text:",
                                              "edit" );
                break;
            case 5:
                aDialog = new TextAttributeDialog( aATNode );
                break;
        }

        if( aDialog != null )
            aDialog.show();
    }

}

/**
 * Display a dialog with a text field and a pair of cancel/do-it buttons
 */
class TextActionDialog extends JDialog
    implements ActionListener
{
    AccTreeNode aNode;
    JTextArea aText;
    String sName;
    JCheckBox aIndexToggle;

    public TextActionDialog( AccTreeNode aNd,
                             String sExplanation,
                             String sButtonText )
    {
        super( AccessibilityWorkBench.Instance() );

        aNode = aNd;
        sName = sButtonText;
        init( sExplanation, aNode.getText().getText(), sButtonText );
//        setSize( getPreferredSize() );
        setSize( 350, 225 );
    }

    /** build dialog */
    protected void init( String sExplanation,
                         String sText,
                         String sButtonText )
    {
        setTitle( sName );

        // vertical stacking of the elements
        Container aContent = getContentPane();
        //        aContent.setLayout( new BorderLayout() );

        // label with explanation
        if( sExplanation.length() > 0 )
            aContent.add( new JLabel( sExplanation ), BorderLayout.NORTH );

        // the text field
        aText = new JTextArea();
        aText.setText( sText );
        aText.setColumns( Math.min( Math.max( 40, sText.length() ), 20 ) );
        aText.setRows( sText.length() / 40 + 1 );
        aText.setLineWrap( true );
        aText.setEditable( false );
        aContent.add( aText, BorderLayout.CENTER );

        JPanel aButtons = new JPanel();
        aButtons.setLayout( new FlowLayout() );
        aIndexToggle = new JCheckBox( "reverse selection" );
        aButtons.add( aIndexToggle );
        JButton aActionButton = new JButton( sButtonText );
        aActionButton.setActionCommand( "Action" );
        aActionButton.addActionListener( this );
        aButtons.add( aActionButton );
        JButton aCancelButton = new JButton( "cancel" );
        aCancelButton.setActionCommand( "Cancel" );
        aCancelButton.addActionListener( this );
        aButtons.add( aCancelButton );

        // add Panel with buttons
        aContent.add( aButtons, BorderLayout.SOUTH );
    }

    void cancel()
    {
        hide();
        dispose();
    }

    void action()
    {
        String sError = null;
        try
        {
            boolean bSuccess = action( aText, aNode );
            if( !bSuccess )
                sError = "Can't execute";
        }
        catch( IndexOutOfBoundsException e )
        {
            sError = "Index out of bounds";
        }

        if( sError != null )
            JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(),
                                           sError, sName,
                                           JOptionPane.ERROR_MESSAGE);

        cancel();
    }

    public void actionPerformed(ActionEvent e)
    {
        String sCommand = e.getActionCommand();

        if( "Cancel".equals( sCommand ) )
            cancel();
        else if( "Action".equals( sCommand ) )
            action();
    }


    int getSelectionStart()     { return getSelection(true); }
    int getSelectionEnd()       { return getSelection(false); }
    int getSelection(boolean bStart)
    {
        return ( bStart ^ aIndexToggle.isSelected() )
            ? aText.getSelectionStart() : aText.getSelectionEnd();
    }



    /** override this for dialog-specific action */
    boolean action( JTextComponent aText, AccTreeNode aNode )
        throws IndexOutOfBoundsException
    {
        return false;
    }
}


class TextEditDialog extends TextActionDialog
{
    public TextEditDialog( AccTreeNode aNode,
                           String sExplanation,
                           String sButtonText )
    {
        super( aNode, sExplanation, sButtonText );
    }

    protected void init( String sExplanation,
                         String sText,
                         String sButtonText )
    {
        super.init( sExplanation, sText, sButtonText );
        aText.setEditable( true );
    }


    /** edit the text */
    boolean action( JTextComponent aText, AccTreeNode aNode )
    {
        // is this text editable? if not, fudge you and return
        XAccessibleEditableText xEdit = aNode.getEditText();
        return ( xEdit == null ) ? false :
            updateText( xEdit, aText.getText() );
    }


    /** update the text */
    boolean updateText( XAccessibleEditableText xEdit, String sNew )
    {
        String sOld = xEdit.getText();

        // false alarm? Early out if no change was done!
        if( sOld.equals( sNew ) )
            return false;

        // get the minimum length of both strings
        int nMinLength = sOld.length();
        if( sNew.length() < nMinLength )
            nMinLength = sNew.length();

        // count equal characters from front and end
        int nFront = 0;
        while( (nFront < nMinLength) &&
               (sNew.charAt(nFront) == sOld.charAt(nFront)) )
            nFront++;
        int nBack = 0;
        while( (nBack < nMinLength) &&
               ( sNew.charAt(sNew.length()-nBack-1) ==
                 sOld.charAt(sOld.length()-nBack-1)    ) )
            nBack++;
        if( nFront + nBack > nMinLength )
            nBack = nMinLength - nFront;

        // so... the first nFront and the last nBack characters
        // are the same. Change the others!
        String sDel = sOld.substring( nFront, sOld.length() - nBack );
        String sIns = sNew.substring( nFront, sNew.length() - nBack );

        System.out.println("edit text: " +
                           sOld.substring(0, nFront) +
                           " [ " + sDel + " -> " + sIns + " ] " +
                           sOld.substring(sOld.length() - nBack) );

        boolean bRet = false;
        try
        {
            // edit the text, and use
            // (set|insert|delete|replace)Text as needed
            if( nFront+nBack == 0 )
                bRet = xEdit.setText( sIns );
            else if( sDel.length() == 0 )
                bRet = xEdit.insertText( sIns, nFront );
            else if( sIns.length() == 0 )
                bRet = xEdit.deleteText( nFront, sOld.length()-nBack );
            else
                bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns);
        }
        catch( IndexOutOfBoundsException e )
        {
            bRet = false;
        }

        return bRet;
    }
}


class TextAttributeDialog extends TextActionDialog
{
    public TextAttributeDialog(
        AccTreeNode aNode )
    {
        super( aNode, "Choose attributes, select text, and press 'Set':",
               "set" );
    }

    private JCheckBox aBold, aUnderline, aItalics;
    private Color aForeground, aBackground;

    protected void init( String sExplanation,
                         String sText,
                         String sButtonText )
    {
        super.init( sExplanation, sText, sButtonText );

        aForeground = Color.black;
        aBackground = Color.white;

        JPanel aAttr = new JPanel();
        aAttr.setLayout( new BoxLayout( aAttr, BoxLayout.Y_AXIS ) );

        aBold = new JCheckBox( "bold" );
        aUnderline = new JCheckBox( "underline" );
        aItalics = new JCheckBox( "italics" );

        JButton aForeButton = new JButton("Foreground", new ColorIcon(true));
        aForeButton.addActionListener( new ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                    aForeground = JColorChooser.showDialog(
                        TextAttributeDialog.this,
                        "Select Foreground Color",
                        aForeground);
                }
            } );

        JButton aBackButton = new JButton("Background", new ColorIcon(false));
        aBackButton.addActionListener( new ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                    aBackground = JColorChooser.showDialog(
                        TextAttributeDialog.this,
                        "Select Background Color",
                        aBackground);
                }
            } );

        aAttr.add( aBold );
        aAttr.add( aUnderline );
        aAttr.add( aItalics );
        aAttr.add( aForeButton );
        aAttr.add( aBackButton );

        getContentPane().add( aAttr, BorderLayout.WEST );
    }


    class ColorIcon implements Icon
    {
        boolean bForeground;
        static final int nHeight = 16;
        static final int nWidth = 16;

        public ColorIcon(boolean bWhich) { bForeground = bWhich; }
        public int getIconHeight()  { return nHeight; }
        public int getIconWidth() { return nWidth; }
        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor( getColor() );
            g.fillRect( x, y, nHeight, nWidth );
            g.setColor( c.getForeground() );
            g.drawRect( x, y, nHeight, nWidth );
        }
        Color getColor()
        {
            return bForeground ? aForeground : aBackground;
        }
    }



    /** edit the text */
    boolean action( JTextComponent aText, AccTreeNode aNode )
        throws IndexOutOfBoundsException
    {
        // is this text editable? if not, fudge you and return
        XAccessibleEditableText xEdit = aNode.getEditText();
        boolean bSuccess = false;
        if( xEdit != null )
        {
            PropertyValue[] aSequence = new PropertyValue[6];
            aSequence[0] = new PropertyValue();
            aSequence[0].Name = "CharWeight";
            aSequence[0].Value = new Integer( aBold.isSelected() ? 150 : 100 );
            aSequence[1] = new PropertyValue();
            aSequence[1].Name = "CharUnderline";
            aSequence[1].Value = new Integer( aUnderline.isSelected() ? 1 : 0 );
            aSequence[2] = new PropertyValue();
            aSequence[2].Name = "CharBackColor";
            aSequence[2].Value = new Integer( aBackground.getRGB() );
            aSequence[3] = new PropertyValue();
            aSequence[3].Name = "CharColor";
            aSequence[3].Value = new Integer( aForeground.getRGB() );
            aSequence[4] = new PropertyValue();
            aSequence[4].Name = "CharPosture";
            aSequence[4].Value = new Integer( aItalics.isSelected() ? 1 : 0 );
            aSequence[5] = new PropertyValue();
            aSequence[5].Name = "CharBackTransparent";
            aSequence[5].Value = new Boolean( false );

            bSuccess = xEdit.setAttributes( getSelectionStart(),
                                            getSelectionEnd(),
                                            aSequence );
        }
        return bSuccess;
    }

}
