/**************************************************************
 * 
 * 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 ("Notifiy 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;
}
