/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Takashi ITOH - initial API and implementation
 *******************************************************************************/
package org.eclipse.actf.visualization.gui.ui.views;

import java.util.Stack;

import org.eclipse.actf.accservice.swtbridge.AccessibleObject;
import org.eclipse.actf.accservice.swtbridge.IA2;
import org.eclipse.actf.accservice.swtbridge.MSAA;
import org.eclipse.actf.accservice.swtbridge.ia2.Accessible2;
import org.eclipse.actf.util.win32.HighlightComposite;
import org.eclipse.actf.util.win32.OverlayLabel;
import org.eclipse.actf.visualization.gui.GuiImages;
import org.eclipse.actf.visualization.gui.GuiPlugin;
import org.eclipse.actf.visualization.gui.Messages;
import org.eclipse.actf.visualization.gui.flash.FlashUtil;
import org.eclipse.actf.visualization.gui.preferences.GuiPreferenceConstants;
import org.eclipse.actf.visualization.gui.preferences.GuiPreferenceManager;
import org.eclipse.actf.visualization.gui.ui.actions.HideHtmlAction;
import org.eclipse.actf.visualization.gui.ui.actions.RefreshRootAction;
import org.eclipse.actf.visualization.gui.ui.actions.ShowOffscreenAction;
import org.eclipse.actf.visualization.gui.util.AccessiblePropertyUtil;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ArmEvent;
import org.eclipse.swt.events.ArmListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;


public class MSAAOutlineView extends ViewPart implements IMSAAOutlineView {
    public static final String ID = MSAAOutlineView.class.getName();
    
    private TreeViewer viewer;

    private Action expandAction;
    private Action expandAllAction;

    private Action collapseAllAction;

    private RefreshRootAction refreshAction;

    private HideHtmlAction hideHtmlAction;
    
    private ShowOffscreenAction showOffscreenAction;

    private Action runCheckerAction;

    private Action showLabelsAction;

    private boolean suppressLabelAdjust = false;
    
    private boolean ignoreSelection = false;
    
    private boolean hideHtml = false;

    /**
     * The constructor.
     */
    public MSAAOutlineView() {
    }

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer.setContentProvider(MSAATreeContentProvider.getDefault());
        viewer.setLabelProvider(new MSAATreeLabelProvider());
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection selection = event.getSelection();
                if (selection instanceof IStructuredSelection) {
                    Object selectedObject = ((IStructuredSelection) selection).getFirstElement();
                    if( null != selectedObject ) {
                        if( !ignoreSelection ) {
                            MSAAViewRegistory.outlineSelected(selectedObject);
                        }
                        if (!suppressLabelAdjust && showLabelsAction.isChecked()) {
                            showOverlayLabels();
                        }
                    }
                    else {
                        HighlightComposite.show(false);
                    }
                }
            }

        });
        viewer.addTreeListener(new ITreeViewerListener() {
            public void treeCollapsed(TreeExpansionEvent event) {
                refreshLabels();
            }

            public void treeExpanded(TreeExpansionEvent event) {
                refreshLabels();
            }
        });
        makeActions();
        hookContextMenu();
        contributeToActionBars();
        MSAAViewRegistory.refreshRootObject();
        MSAAViewRegistory.showView(MSAAViewRegistory.MSAAEventView_ID, false);    }

    private void refreshLabels() {
        if (showLabelsAction.isChecked()) {
            viewer.getControl().getDisplay().asyncExec(new Runnable() {
                public void run() {
                    showOverlayLabels();
                }
            });
        }
    }

    public void refresh() {
    	hideHtml = MSAATreeContentProvider.getDefault().hideHtml; 
        OverlayLabel.removeAll();
        AccessibleObject rootObject = MSAAViewRegistory.getRootObject();
        if( null != rootObject ) {
            ignoreSelection = true;
            try {
                viewer.setInput(rootObject);
                AccessibleObject selection = MSAAViewRegistory.adjustSelection(rootObject);
                if( null != selection ) {
                    viewer.setSelection(new StructuredSelection(selection));
                    if( selection.getChildCount() < 100 ) {
                        viewer.setExpandedState(selection,true);
                    }
                }
            }
            finally {
                ignoreSelection = false;
            }
        }
    }

    public void setSelection(Object element) {
        ISelection selection = StructuredSelection.EMPTY;
        if( element instanceof AccessibleObject ) {
            Stack<AccessibleObject> stack = new Stack<AccessibleObject>();
            for( AccessibleObject accParent = (AccessibleObject)element; 
                 null != (accParent = accParent.getCachedParent()) && !viewer.getExpandedState(accParent);
                 stack.push(accParent) ) {
				;
			}
            while( !stack.isEmpty() ) {
                viewer.setExpandedState(stack.pop(),true);
            }
            selection = new StructuredSelection(element);
        }
        viewer.setSelection(selection,true);
	}

	private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                MSAAOutlineView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalPullDown(IMenuManager manager) {
        manager.add(showOffscreenAction);
		manager.add(new Separator());
    	manager.add(hideHtmlAction);
        manager.addMenuListener(new IMenuListener(){
            public void menuAboutToShow(IMenuManager manager) {
                showOffscreenAction.adjust();
                hideHtmlAction.adjust();
            }
        });
        manager.add(new Separator());
        manager.add(showLabelsAction);
    }

    private void fillContextMenu(IMenuManager manager) {
        Object selected = getSelectedItem();
        if (null != selected) {
            manager.add(expandAction);
        }
        manager.add(new Separator());
        manager.add(runCheckerAction);
        manager.add(refreshAction);
        // Other plug-ins can contribute there actions here
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(expandAllAction);
        manager.add(collapseAllAction);
        manager.add(refreshAction);
        manager.add(runCheckerAction);
        manager.add(showLabelsAction);
    }

    private void makeActions() {
        final Shell shell = this.getViewSite().getShell();
        
        expandAction = new Action(Messages.getString("msaa.expand")) { //$NON-NLS-1$
            public void run() {
                try {
                    Object selected = getSelectedItem();
                    if (null != selected) {
                        viewer.expandToLevel(selected, AbstractTreeViewer.ALL_LEVELS);
                    }
                } catch (Error e) {
                    e.printStackTrace();
                }
            }
        };

        expandAllAction = new Action(Messages.getString("msaa.expand_all")) { //$NON-NLS-1$
            public void run() {
                try {
                    viewer.expandAll();
                } catch (Error e) {
                    e.printStackTrace();
                }
            }
        };
        expandAllAction.setToolTipText(Messages.getString("msaa.expand_all")); //$NON-NLS-1$
        expandAllAction.setImageDescriptor(GuiPlugin.IMAGE_EXPAND_ALL);

        collapseAllAction = new Action(Messages.getString("msaa.collapse_all")) { //$NON-NLS-1$
            public void run() {
                try {
                    viewer.collapseAll();
                } catch (Error e) {
                    e.printStackTrace();
                }
            }
        };
        collapseAllAction.setToolTipText(Messages.getString("msaa.collapse_all")); //$NON-NLS-1$
        collapseAllAction.setImageDescriptor(GuiPlugin.IMAGE_COLLAPSE_ALL);

        refreshAction = new RefreshRootAction();

        hideHtmlAction = new HideHtmlAction();

        showOffscreenAction = new ShowOffscreenAction();

        runCheckerAction = new Action(Messages.getString("msaa.checker")) { //$NON-NLS-1$
            public void run() {
                IMSAAProblemsView problemsView = (IMSAAProblemsView) MSAAViewRegistory.showView(
                        MSAAViewRegistory.MSAAProblemsView_ID, true);
                if (null != problemsView) {
                    problemsView.refresh();
                }
            }
        };
        runCheckerAction.setToolTipText(Messages.getString("msaa.checker_tip")); //$NON-NLS-1$
        runCheckerAction.setImageDescriptor(GuiPlugin.IMAGE_CHECKER);

        showLabelsAction = new Action(Messages.getString("msaa.show_tree"), Action.AS_CHECK_BOX) { //$NON-NLS-1$
            public void run() {
                showOverlayLabels();
            }
        };
        showLabelsAction.setToolTipText(Messages.getString("msaa.show_tree")); //$NON-NLS-1$
        showLabelsAction.setImageDescriptor(GuiPlugin.IMAGE_OVERLAY);
        shell.addShellListener(new ShellAdapter(){
            public void shellActivated(ShellEvent e) {
                if( MSAAViewRegistory.MSAAOutlineView_ID.equals(OverlayLabel.getOwnerId()) ) {
                    showOverlayLabels();
                }
            }
            public void shellDeactivated(ShellEvent e) {
                if( MSAAViewRegistory.MSAAOutlineView_ID.equals(OverlayLabel.getOwnerId()) ) {
                    OverlayLabel.removeAll(false);
                }
            }
        });
        showLabelsAction.setEnabled(GuiPreferenceManager.getPreferenceBoolean(GuiPreferenceConstants.UseOverlayWindow));
        final IPreferenceStore store = GuiPreferenceManager.getPreferenceStore();
        store.addPropertyChangeListener(new IPropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if( GuiPreferenceConstants.UseOverlayWindow.equals(event.getProperty())) {
                    showLabelsAction.setEnabled(GuiPreferenceManager.getPreferenceBoolean(GuiPreferenceConstants.UseOverlayWindow));
                }
            }
        });
    }

    private void showOverlayLabels() {
        OverlayLabel.removeAll();
        if (showLabelsAction.isChecked()) {
            new LabelOverlay().showLabels(viewer.getTree().getSelection());
            OverlayLabel.setOwnerId(MSAAViewRegistory.MSAAOutlineView_ID);
        }
    }
    
    private class LabelOverlay {
        int index = 0;

        TreeItem currentItem = null;

        public void showLabels(TreeItem[] items) {
            if (items.length == 1) {
                currentItem = items[0];
                TreeItem parent = currentItem.getParentItem();
                if (null != parent) {
                    items = parent.getItems();
                }
            }
            renderLabels(items);
        }

        public void renderLabels(TreeItem[] items) {
            for (int i = 0; i < items.length; i++) {
                Object treeObject = items[i].getData();
                if (treeObject instanceof AccessibleObject) {
                    Rectangle location = ((AccessibleObject) treeObject).getAccLocation();
                    if (null != location) {
                        OverlayLabel label = OverlayLabel.create(treeObject);
                        if (null != label) {
                            if (items[i].equals(currentItem)) {
                                label.setForeground(label.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
                                label.setBackground(label.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
                            }
                            MSAATreeLabelProvider labelProvider = (MSAATreeLabelProvider) viewer.getLabelProvider();
                            label.setImage(labelProvider.getImage(treeObject));
                            label.setText("" + index); //$NON-NLS-1$
                            String text = "[" + index + "] " + labelProvider.getText(treeObject); //$NON-NLS-1$ //$NON-NLS-2$
                            String[][] properties = AccessiblePropertyUtil.getPropertyStrings(treeObject);
                            label.setTooltop(text, properties);
                            label.pack();
                            label.setLocation(location.x, location.y);
                            index++;
                            label.addMouseListener(new MouseAdapter() {
                                public void mouseDown(MouseEvent e) {
                                    if (e.widget instanceof OverlayLabel) {
                                        OverlayLabel[] labels = OverlayLabel.getLabelsAtPosition(e.display
                                                .getCursorLocation());
                                        if (labels.length > 0) {
                                            showSelectionMenu(labels, (OverlayLabel) e.widget);
                                        } else {
                                            suppressLabelAdjust = true;
                                            viewer.setSelection(new StructuredSelection(
                                                    ((OverlayLabel) e.widget).associatedObject));
                                            suppressLabelAdjust = false;
                                        }
                                    }
                                }
                            });
                            label.addMouseTrackListener(new MouseTrackAdapter() {
                                public void mouseEnter(MouseEvent e) {
                                    if (e.widget instanceof OverlayLabel) {
                                        AccessibleObject object = (AccessibleObject) ((OverlayLabel) e.widget).associatedObject;
                                        if (null != object) {
                                            HighlightComposite.flashRectangle(object.getAccLocation());
                                        }
                                    }
                                }

                                public void mouseExit(MouseEvent e) {
                                    HighlightComposite.show(false);
                                }
                            });
                        }
                    }
                }
                if (items[i].getExpanded()) {
                    renderLabels(items[i].getItems());
                }
            }
        }
    }

    private void showSelectionMenu(OverlayLabel[] labels, OverlayLabel parent) {
        final Menu popupMenu = parent.createPopupMenu();
        MenuItem[] menuItems = new MenuItem[labels.length];
        for (int i = 0; i < labels.length; i++) {
            menuItems[i] = new MenuItem(popupMenu, SWT.PUSH);
            menuItems[i].setText(labels[i].getMenuText());
            menuItems[i].setImage(labels[i].getImage());
            menuItems[i].setData(labels[i].associatedObject);
            menuItems[i].addArmListener(new ArmListener() {
                public void widgetArmed(ArmEvent e) {
                    Object data = ((MenuItem) e.getSource()).getData();
                    if (data instanceof AccessibleObject) {
                        HighlightComposite.flashRectangle(((AccessibleObject) data).getAccLocation());
                    }
                }
            });
            menuItems[i].addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent e) {
                    Object data = ((MenuItem) e.getSource()).getData();
                    suppressLabelAdjust = true;
                    viewer.setSelection(new StructuredSelection(data));
                    suppressLabelAdjust = false;
                }
            });
        }
        popupMenu.setVisible(true);
    }

    private Object getSelectedItem() {
        IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
        if (selection.size() == 1) {
            return selection.getFirstElement();
        }
        return null;
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    private class MSAATreeLabelProvider extends LabelProvider implements IColorProvider {

    	private Color colorInvisible = Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
    	
        public Image getImage(Object element) {
            String imageKey = null;// Images.ELEMENT;
            if (element instanceof AccessibleObject) {
                imageKey = GuiImages.roleIcon(((AccessibleObject) element).getAccRole());
                if( null == imageKey ) {
                    Accessible2 ac2 = ((AccessibleObject) element).getAccessible2();
                    if( null != ac2 ) {
                        imageKey = GuiImages.roleIcon("IA2_ROLE_UNKNOWN"); //$NON-NLS-1$
                    }
                }
            }
            if( null == imageKey ) {
                imageKey = GuiImages.roleIcon("ROLE_UNKNOWN"); //$NON-NLS-1$
            }
            return GuiImages.getImage(imageKey);
        }

        public String getText(Object element) {
        	return getTreeText(element);
        }

		public Color getBackground(Object element) {
            if (!hideHtml && element instanceof AccessibleObject) {
                return FlashUtil.getFlashBackground((AccessibleObject)element);
            }
			return null;
		}

		public Color getForeground(Object element) {
            if (element instanceof AccessibleObject) {
                int accState = ((AccessibleObject)element).getAccState();
                if ( 0 != (accState & MSAA.STATE_INVISIBLE)) {
                	return colorInvisible;
                }
            }
			return null;
		}

    }

    public static String getTreeText(Object element) {
        if (element instanceof AccessibleObject) {
        	AccessibleObject accObject = (AccessibleObject)element;
            try {
                String accText = accObject.getAccName();
                if (null == accText || 0 == accText.length()) {
                    switch( accObject.getAccRole() ) {
	                case IA2.IA2_ROLE_PARAGRAPH:
	                case IA2.IA2_ROLE_HEADING:
		                	accText = accObject.getAccValue();
		                	break;
                    }
                }
                if (null == accText || 0 == accText.length()) {
                    accText = Messages.getString("msaa.NAMELESS"); //$NON-NLS-1$
                	String roleText = accObject.getRoleText();
                    if ( null != roleText ) {
                    	accText += " ("+roleText+")"; //$NON-NLS-1$ //$NON-NLS-2$
                    }
                }
                return accText;
            } catch (Exception e) {
                return e.getMessage();
            }
        }
        return element.toString();
    }
}
