/**************************************************************
 *
 * 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.awt.XWindow;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.PropertyChangeEvent;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.container.XEnumeration;
import com.sun.star.document.XEventListener;
import com.sun.star.drawing.XDrawPage;
import com.sun.star.drawing.XDrawView;
import com.sun.star.frame.XController;
import com.sun.star.frame.XFrame;
import com.sun.star.frame.XFrameActionListener;
import com.sun.star.frame.FrameActionEvent;
import com.sun.star.frame.FrameAction;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XTerminateListener;
import com.sun.star.uno.UnoRuntime;

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.XAccessibleRelationSet;
import com.sun.star.accessibility.XAccessibleStateSet;

import com.sun.star.awt.XExtendedToolkit;

import java.util.Vector;
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.io.*;

import ov.ObjectViewContainer;

/** This class manages the GUI of the work bench.
    @see AccessibilityTreeModel
        for the implementation of the tree view on the left side which also
        manages the registration of accessibility listeners.
    @see Canvas
        for the graphical view of the accessible objects.
*/
public class AccessibilityWorkBench
    extends JFrame
    implements ActionListener, XTerminateListener, TreeSelectionListener

{
    public static final String msVersion = "v1.7.2";
    public String msOptionsFileName = ".AWBrc";

    public static void main (String args[])
    {
        int nPortNumber = 5678;

        for (int i=0; i<args.length; i++)
        {
            if (args[i].equals ("-h") || args[i].equals ("--help") || args[i].equals ("-?"))
            {
                System.out.println ("usage: AccessibilityWorkBench <option>*");
                System.out.println ("options:");
                System.out.println ("   -p <port-number>   Port on which to connect to StarOffice.");
                System.out.println ("                      Defaults to 5678.");
                System.exit (0);
            }
            else if (args[i].equals ("-p"))
            {
                nPortNumber = Integer.parseInt (args[++i]);
            }
        }

        saWorkBench = new AccessibilityWorkBench (nPortNumber);
    }




    /** Return the one instance of the AccessibilityWorkBench
        @return
            Returns null when the AccessibilityWorkBench could not be
            created successfully.
    */
    public static AccessibilityWorkBench Instance ()
    {
        return saWorkBench;
    }



    /** Create an accessibility work bench that listens at the specified
        port to Office applications.
    */
    private AccessibilityWorkBench (int nPortNumber)
    {
        mbInitialized = false;

        Layout ();

        MessageArea.println (System.getProperty ("os.name") + " / "
            + System.getProperty ("os.arch") + " / "
            + System.getProperty ("os.version"));
        MessageArea.println ("Using port " + nPortNumber);
        office = new SimpleOffice (nPortNumber);
        info = new InformationWriter ();

        maAccessibilityTree.getComponent().addTreeSelectionListener (this);

        addWindowListener (new WindowAdapter ()
            { public void windowClosing (WindowEvent e)
                  { System.exit(0); }
            });

        initialize ();
    }




    /** Create and arrange the widgets of the GUI.
    */
    public void Layout  ()
    {
        setSize (new Dimension (8000,600));

        JScrollPane aScrollPane;
        GridBagConstraints constraints;

        // Create new layout.
        GridBagLayout aLayout = new GridBagLayout ();
        getContentPane().setLayout (aLayout);

        //  Accessible Tree.
        maAccessibilityTree = new AccessibilityTree ();
        //        maAccessibilityTree.getComponent().setMinimumSize (new Dimension (250,300));
        JScrollPane aTreeScrollPane = new JScrollPane(
            maAccessibilityTree.getComponent(),
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        aTreeScrollPane.setPreferredSize (new Dimension (400,300));

        // Object view shows details about the currently selected accessible
        // object.
        maObjectViewContainer = new ObjectViewContainer ();
        //        maObjectViewContainer.setPreferredSize (new Dimension (300,100));
        JScrollPane aObjectViewContainerScrollPane = new JScrollPane(
            maObjectViewContainer,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        aObjectViewContainerScrollPane.setPreferredSize (new Dimension (400,300));

        // Split pane for tree view and object view.
        JSplitPane aLeftViewSplitPane = new JSplitPane (
            JSplitPane.VERTICAL_SPLIT,
            aTreeScrollPane,
            aObjectViewContainerScrollPane
            );
        aLeftViewSplitPane.setDividerLocation (300);

        //  Canvas.
        maCanvas = new Canvas ();
        maCanvas.setTree (maAccessibilityTree.getComponent());
        maAccessibilityTree.SetCanvas (maCanvas);
        JScrollPane aScrolledCanvas = new JScrollPane(maCanvas,
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        aScrolledCanvas.getViewport().setBackground (Color.RED);
        aScrolledCanvas.setPreferredSize (new Dimension(600,400));

        // Split pane for tree view and canvas.
        JSplitPane aViewSplitPane = new JSplitPane (
            JSplitPane.HORIZONTAL_SPLIT,
            aLeftViewSplitPane,
            aScrolledCanvas
            );
        aViewSplitPane.setOneTouchExpandable(true);
        aViewSplitPane.setDividerLocation (400);

        //  Text output area.
        maMessageArea = MessageArea.Instance ();
        //        maMessageArea.setPreferredSize (new Dimension (300,50));

        // Split pane for the two views and the message area.
        JSplitPane aSplitPane = new JSplitPane (JSplitPane.VERTICAL_SPLIT,
            aViewSplitPane, maMessageArea);
        aSplitPane.setOneTouchExpandable(true);
        addGridElement (aViewSplitPane, 0,0, 2,1, 3,3,
            GridBagConstraints.CENTER, GridBagConstraints.BOTH);

        // Button bar.
        maButtonBar = new JPanel();
        GridBagLayout aButtonLayout = new GridBagLayout ();
        maButtonBar.setLayout (new FlowLayout());
        addGridElement (maButtonBar, 0,3, 2,1, 1,0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);

        //  Buttons.
        aConnectButton = createButton ("Connect", "connect");
        aUpdateButton = createButton ("Update", "update");
        aShapesButton = createButton ("Expand Shapes", "shapes");
        aExpandButton = createButton ("Expand All", "expand");
        aQuitButton = createButton ("Quit", "quit");
        UpdateButtonStates ();

        Options.Instance().Load (msOptionsFileName);

        setJMenuBar (CreateMenuBar ());

        setTitle("Accessibility Workbench " + msVersion);

        pack ();
        setVisible (true);
        validate ();
        repaint();
    }




    /** Shortcut method for adding an object to a GridBagLayout.
    */
    void addGridElement (JComponent object,
        int x, int y, int width, int height, int weightx, int weighty,
        int anchor, int fill)
    {
        GridBagConstraints constraints = new GridBagConstraints ();
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = width;
        constraints.gridheight = height;
        constraints.weightx = weightx;
        constraints.weighty = weighty;
        constraints.anchor = anchor;
        constraints.fill = fill;
        getContentPane().add (object, constraints);
    }




    /** Create a new button and place at the right most position into the
        button bar.
    */
    public JButton createButton (String title, String command)
    {
        JButton aButton = new JButton (title);
        aButton.setEnabled (false);
        aButton.setActionCommand (command);
        aButton.addActionListener (this);

        maButtonBar.add (aButton);
        return aButton;
    }




    /** Create a menu bar for the application.
        @return
            Returns the new menu bar.  The returned reference is also
            remembered in the data member <member>maMenuBar</member>.
    */
    JMenuBar CreateMenuBar ()
    {
        // Menu bar.
        maMenuBar = new JMenuBar ();

        // File menu.
        JMenu aFileMenu = new JMenu ("File");
        maMenuBar.add (aFileMenu);
        JMenuItem aItem;
        aItem = new JMenuItem ("Quit");
        aFileMenu.add (aItem);
        aItem.addActionListener (this);

        // View menu.
        JMenu aViewMenu = new JMenu ("View");
        maMenuBar.add (aViewMenu);
        ButtonGroup aGroup = new ButtonGroup ();
        JRadioButtonMenuItem aRadioButton = new JRadioButtonMenuItem ("Whole Screen");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);
        aRadioButton = new JRadioButtonMenuItem ("200%");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);
        aRadioButton = new JRadioButtonMenuItem ("100%");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);
        aRadioButton = new JRadioButtonMenuItem ("50%");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);
        aRadioButton = new JRadioButtonMenuItem ("25%");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);
        aRadioButton = new JRadioButtonMenuItem ("10%");
        aGroup.add (aRadioButton);
        aViewMenu.add (aRadioButton);
        aRadioButton.addActionListener (this);

        // Options menu.
        JMenu aOptionsMenu = new JMenu ("Options");
        maMenuBar.add (aOptionsMenu);
        JCheckBoxMenuItem aCBItem;
        aCBItem = new JCheckBoxMenuItem ("Show Descriptions", maCanvas.getShowDescriptions());
        aOptionsMenu.add (aCBItem);
        aCBItem.addActionListener (this);

        aCBItem = new JCheckBoxMenuItem ("Show Names", maCanvas.getShowNames());
        aOptionsMenu.add (aCBItem);
        aCBItem.addActionListener (this);

        aCBItem = new JCheckBoxMenuItem ("Show Text", maCanvas.getShowText());
        aOptionsMenu.add (aCBItem);
        aCBItem.addActionListener (this);

        aCBItem = new JCheckBoxMenuItem ("Antialiased Rendering", maCanvas.getAntialiasing());
        aOptionsMenu.add (aCBItem);
        aCBItem.addActionListener (this);

        // Help menu.
        JMenu aHelpMenu = new JMenu ("Help");
        maMenuBar.add (aHelpMenu);

        aItem = new JMenuItem ("Help");
        aHelpMenu.add (aItem);
        aItem.addActionListener (this);

        aItem = new JMenuItem ("News");
        aHelpMenu.add (aItem);
        aItem.addActionListener (this);

        aItem = new JMenuItem ("About");
        aHelpMenu.add (aItem);
        aItem.addActionListener (this);

        return maMenuBar;
    }




    /** Initialize the AWB.  This includes clearing the canvas, add
        listeners, creation of a new tree model for the tree list box and
        the update of the button states.

        This method may be called any number of times.  Note that all
        actions will be carried out every time.  The main purpose of a
        second call is that of a re-initialization after a reconnect.
    */
    protected void initialize ()
    {
        maCanvas.clear();

        AccessibilityTreeModel aModel = null;
        aModel = new AccessibilityTreeModel (createTreeModelRoot());

        aModel.setCanvas (maCanvas);
        maAccessibilityTree.getComponent().setModel (aModel);

        if (office != null)
        {
            // Add terminate listener.
            if (office.getDesktop() != null)
                office.getDesktop().addTerminateListener (this);

            XExtendedToolkit xToolkit = office.getExtendedToolkit();
            // Remove old top window listener.
            if (maTopWindowListener != null)
                xToolkit.removeTopWindowListener (maQueuedTopWindowListener);
            // Add top window listener.
            if (xToolkit != null)
            {
                MessageArea.println ("registering at extended toolkit");
                maTopWindowListener = new TopWindowListener (aModel, office);
                maQueuedTopWindowListener = new QueuedTopWindowListener (maTopWindowListener);
                xToolkit.addTopWindowListener (maQueuedTopWindowListener);
                maTopWindowListener.Initialize ();
            }
            else
                maTopWindowListener = null;
        }

        mbInitialized = true;
        UpdateButtonStates ();
    }




    /** Update the states of the buttons according to the internal state of
        the AWB.
    */
    protected void UpdateButtonStates ()
    {
        aConnectButton.setEnabled (mbInitialized);
        aQuitButton.setEnabled (mbInitialized);
        aUpdateButton.setEnabled (mbInitialized);
        aExpandButton.setEnabled (mbInitialized);
        aShapesButton.setEnabled (mbInitialized);
    }



    /** Callback for GUI actions from the buttons.
    */
    public void actionPerformed (java.awt.event.ActionEvent e)
    {
        if (e.getActionCommand().equals("connect"))
        {
            office.connect();
            initialize ();
        }
        else if (e.getActionCommand().equals("quit"))
        {
            AccessibilityTreeModel aModel = (AccessibilityTreeModel)maAccessibilityTree.getComponent().getModel();
            aModel.clear();
            System.exit (0);
        }
        else if (e.getActionCommand().equals("update"))
        {
            initialize ();
        }
        else if (e.getActionCommand().equals("shapes"))
        {
            Cursor aCursor = getCursor();
            setCursor (new Cursor (Cursor.WAIT_CURSOR));
            maAccessibilityTree.expandShapes();
            setCursor (aCursor);
        }
        else if (e.getActionCommand().equals("expand"))
        {
            Cursor aCursor = getCursor();
            setCursor (new Cursor (Cursor.WAIT_CURSOR));
            maAccessibilityTree.expandAll();
            setCursor (aCursor);
        }
        else if (e.getActionCommand().equals ("Quit"))
        {
            System.out.println ("exiting");
            System.exit (0);
        }
        else if (e.getActionCommand().equals ("Show Descriptions"))
        {
            maCanvas.setShowDescriptions ( ! maCanvas.getShowDescriptions());
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("Show Names"))
        {
            maCanvas.setShowNames ( ! maCanvas.getShowNames());
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("Antialiased Rendering"))
        {
            maCanvas.setAntialiasing ( ! maCanvas.getAntialiasing());
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("Help"))
        {
            HelpWindow.Instance().loadFile ("help.html");
        }
        else if (e.getActionCommand().equals ("News"))
        {
            try{
                HelpWindow.Instance().loadFile ("news.html");
            } catch (Exception ex) {}
        }
        else if (e.getActionCommand().equals ("About"))
        {
            HelpWindow.Instance().loadFile ("about.html");
        }
        else if (e.getActionCommand().equals ("Whole Screen"))
        {
            maCanvas.setZoomMode (Canvas.WHOLE_SCREEN);
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("200%"))
        {
            maCanvas.setZoomMode (200);
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("100%"))
        {
            maCanvas.setZoomMode (100);
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("50%"))
        {
            maCanvas.setZoomMode (50);
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("25%"))
        {
            maCanvas.setZoomMode (25);
            Options.Instance().Save (msOptionsFileName);
        }
        else if (e.getActionCommand().equals ("10%"))
        {
            maCanvas.setZoomMode (10);
            Options.Instance().Save (msOptionsFileName);
        }
        else
        {
            System.err.println("unknown command " + e.getActionCommand());
        }
    }




    /** Create an AccessibilityTreeModel root which contains the documents
        (top windows) that are present at the moment.
    */
    private AccessibleTreeNode createTreeModelRoot()
    {
        // create root node
        VectorNode aRoot = new VectorNode ("Accessibility Tree", null);
        if (maTopWindowListener != null)
            maTopWindowListener.Initialize ();
        return aRoot;
    }


    // TreeSelectionListener
    public void valueChanged (TreeSelectionEvent aEvent)
    {
        TreePath aPath = aEvent.getPath();
        Object aObject = aPath.getLastPathComponent();
        if (aObject instanceof AccTreeNode)
        {
            AccTreeNode aNode = (AccTreeNode) aObject;
            XAccessibleContext xContext = aNode.getContext();
            maObjectViewContainer.SetObject (xContext);
        }
    }




    // XEventListener
    public void disposing( com.sun.star.lang.EventObject aSourceObj )
    {
		XFrame xFrame = (XFrame)UnoRuntime.queryInterface(XFrame.class, aSourceObj.Source);

		if( xFrame != null )
			System.out.println("frame disposed");
		else
			System.out.println("controller disposed");
    }




	// XTerminateListener
	public void queryTermination (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
	{
		System.out.println ("Terminate Event : " + aEvent);
	}




	// XTerminateListener
	public void notifyTermination (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
	{
		System.out.println ("Notify Termination Event : " + aEvent);
	}



    /// The Singleton Workbench object.
    private static AccessibilityWorkBench
        saWorkBench = null;

    protected SimpleOffice
        office;
    protected InformationWriter
        info;

    private XModel
        mxModel;
    private JPanel
        maMainPanel,
        maButtonBar;
    private Canvas
        maCanvas;
    private AccessibilityTree
        maAccessibilityTree;
    private ObjectViewContainer
        maObjectViewContainer;
    private JScrollPane
        maScrollPane;
    private MessageArea
        maMessageArea;
    private JButton
        aConnectButton,
        aQuitButton,
        aUpdateButton,
        aExpandButton,
        aShapesButton;
    private JMenuBar
        maMenuBar;
    private String
        msMessage;
    private boolean
        mbInitialized;
    private TopWindowListener
        maTopWindowListener;
    private QueuedTopWindowListener
        maQueuedTopWindowListener;
}
