/*******************************************************************************
 * 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.flash.ui.views;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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.dialogs.MessageDialog;
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.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;


import org.eclipse.actf.accservice.swtbridge.AccessibleObject;
import org.eclipse.actf.model.flash.FlashAdjust;
import org.eclipse.actf.model.flash.FlashDetect;
import org.eclipse.actf.model.flash.FlashNode;
import org.eclipse.actf.model.flash.FlashPlayer;
import org.eclipse.actf.visualization.flash.FlashImages;
import org.eclipse.actf.visualization.flash.Messages;
import org.eclipse.actf.visualization.gui.GuiImages;
import org.eclipse.actf.visualization.gui.GuiPlugin;
import org.eclipse.actf.visualization.gui.flash.FlashFinder;
import org.eclipse.actf.visualization.gui.flash.FlashUtil;
import org.eclipse.actf.visualization.gui.ui.actions.RefreshRootAction;
import org.eclipse.actf.visualization.gui.ui.views.IFlashDOMView;
import org.eclipse.actf.visualization.gui.ui.views.MSAAViewRegistory;


public class FlashDOMView extends ViewPart implements IFlashDOMView {
    public static final String ID = FlashDOMView.class.getName();
    
	private TreeViewer viewer;
	private Action expandAction;
	private Action expandAllAction;
	private Action collapseAllAction;
	private RefreshRootAction refreshAction;
	private Action informativeTreeAction;
    private Action visualTreeAction;
    private Action debugTreeAction;
    private Action scanWindowlessAction;
    private Color colorFound = Display.getCurrent().getSystemColor(SWT.COLOR_CYAN);

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

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new FlashTreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new FlashDOMContentProvider());
		viewer.setLabelProvider(new FlashDOMLabelProvider());
		viewer.addSelectionChangedListener(new ISelectionChangedListener(){
		    public void selectionChanged(SelectionChangedEvent event) {
		        ISelection selection = event.getSelection();
		        if (selection instanceof IStructuredSelection) {
		        	Object selectedItem = ((IStructuredSelection) selection).getFirstElement();
		        	if( selectedItem instanceof FlashNode ) {
		        		((FlashNode)selectedItem).setMarker();
		        	}
                    else if( !(selectedItem instanceof FlashPlayer) ) {
                        return;
                    }
		        	MSAAViewRegistory.showProperties(selectedItem);
		        }
		    }
		});
		makeActions();
		hookContextMenu();
		contributeToActionBars();
        MSAAViewRegistory.findView(MSAAViewRegistory.MSAAOutlineView_ID);
		refresh();
	}

    public void adjustID() {
        Object[] results = FlashUtil.getFlashElements(MSAAViewRegistory.rootObject);
        for( int i=0; i<results.length; i++ ) {
            FlashAdjust flashAdjust = new FlashAdjust(results[i]);
            flashAdjust.adjust("adesigner_flash_object"+i); //$NON-NLS-1$
            flashAdjust.dispose();
        }
    }
    
    public void refresh() {
        AccessibleObject rootObject = MSAAViewRegistory.getRootObject();
        if( null != rootObject ) {
            adjustID();
            viewer.setInput(FlashUtil.getFlashElements(rootObject));
            FlashDetect.showDialog();
        }
    }
    
    public void findRectangle(Rectangle flashRect, Object objUnknown) {
        viewer.setInput(new Object[]{objUnknown});
        String strMessage = Messages.getString("flash.error_no_element"); //$NON-NLS-1$
        RectangleFinder finder = new RectangleFinder(flashRect);
        try {
            finder.find(viewer.getTree().getItems());
        }
        catch( Error e ) {
        	e.printStackTrace();
        }
        if( finder.foundCount > 0 ) {
        	strMessage = MessageFormat.format(Messages.getString("flash.element_found"), new Object[]{new Integer(finder.foundCount)}); //$NON-NLS-1$
        }
        MessageDialog.openInformation(
                viewer.getControl().getShell(),
                Messages.getString("flash.flash_dom"), //$NON-NLS-1$
                strMessage);
    }
    
    public void addWindowlessElement(final Object objUnknown) {
        if( !scanWindowlessAction.isChecked() ) {
            Display.getCurrent().asyncExec(new Runnable(){
                public void run() {
                    Object currentInput = viewer.getInput();
                    if( currentInput instanceof Object[] ) {
                        List list = Arrays.asList((Object[])currentInput);
                        if( !list.contains(objUnknown) ) {
                            ArrayList newList = new ArrayList(list);
                            newList.add(objUnknown);
                            viewer.setInput(newList.toArray());
                        }
                    }
                }
            });
        }
    }

    private class RectangleFinder {
        private static final int MARGIN = 10;
        public int foundCount = 0;
        private int errorCount = 0;
        private int flashLeft, flashTop, flashRight, flashBottom;
        public RectangleFinder(Rectangle flashRect) {
            flashLeft = flashRect.x;
            flashTop = flashRect.y;
            flashRight = flashRect.x+flashRect.width;
            flashBottom = flashRect.y+flashRect.height;
        }
        
        public void find(TreeItem[] items) {
            for( int i=0; i<items.length; i++ ) {
                TreeItem item = items[i];
                try {
                    FlashNode flashNode = (FlashNode)item.getData();
                    if( flashNode.getLevel()>=40 ) {
            			throw new Error(MessageFormat.format(Messages.getString("flash.error_target_length"),new Object[]{new Integer(flashNode.getLevel())})+"\n"+flashNode.getTarget()); //$NON-NLS-1$ //$NON-NLS-2$
                    }
                    String strX = flashNode.getString("x"); //$NON-NLS-1$
                    if( null == strX ) continue;
                    int x = Float.valueOf(strX).intValue(); //$NON-NLS-1$
                    if( x>=flashRight+MARGIN ) {
                        continue;
                    }
                    int y = Float.valueOf(flashNode.getString("y")).intValue(); //$NON-NLS-1$
                    if( y>=flashBottom+MARGIN ) {
                        continue;
                    }
                    int w = Float.valueOf(flashNode.getString("w")).intValue(); //$NON-NLS-1$
                    if( x+w<=flashLeft-MARGIN ) {
                        continue;
                    }
                    int h = Float.valueOf(flashNode.getString("h")).intValue(); //$NON-NLS-1$
                    if( y+h<=flashTop-MARGIN ) {
                        continue;
                    }
                    if( isMatch(x,y,w,h) ) {
                        item.setBackground(colorFound);
                        foundCount++;
                        viewer.reveal(flashNode);
                    }
                    if( Boolean.TRUE.equals(flashNode.getObject("isOpaqueObject")) ) { //$NON-NLS-1$
//                    	System.out.println("Skip Opaque Object "+flashNode.getTarget()); //$NON-NLS-1$
                    	continue;
                    }
                    find(((FlashTreeViewer)viewer).getChildItems(item));
                }
                catch( Exception e ) {
                	e.printStackTrace();
                }
                catch( FindError e ) {
                	throw e;
                }
                catch( Error e) {
                	System.err.println(e.getMessage());
                	if( ++errorCount >= 20 ) {
                		throw new FindError("Error count reached "+errorCount); //$NON-NLS-1$
                	}
                }
            }
        }
        
        private class FindError extends Error {
            private static final long serialVersionUID = -7707451728015676479L;

            public FindError(String message) {
				super(message);
			}
        };
        
        private boolean isMatch(int x, int y, int w, int h) {
            return flashLeft-MARGIN<=x && x<flashLeft+MARGIN && 
                   flashTop-MARGIN<=y && y<flashTop+MARGIN && 
                   flashRight-MARGIN<=x+w && x+w<=flashRight+MARGIN && 
                   flashBottom-MARGIN<=y+h && y+h<=flashBottom+MARGIN;
        }
    }
    
	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				FlashDOMView.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(informativeTreeAction);
		manager.add(visualTreeAction);
        manager.add(scanWindowlessAction);
        manager.add(debugTreeAction);
        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	private void fillContextMenu(IMenuManager manager) {
        Object selected = getSelectedItem();
        if (null != selected) {
            manager.add(expandAction);
        }
		manager.add(new Separator());
		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);
	}

	private void makeActions() {
		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) {
					System.err.println(e.getMessage());
				}
			}
		};
		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();

		informativeTreeAction = new Action(Messages.getString("flash.filter_noninformative"),Action.AS_CHECK_BOX) { //$NON-NLS-1$
			public void run() {
				FlashDOMContentProvider provider = (FlashDOMContentProvider)viewer.getContentProvider();
				provider.informativeTree = informativeTreeAction.isChecked();
                MSAAViewRegistory.refreshRootObject();
			}
		};

        visualTreeAction = new Action(Messages.getString("flash.show_visual"),Action.AS_CHECK_BOX) { //$NON-NLS-1$
            public void run() {
                FlashDOMContentProvider provider = (FlashDOMContentProvider)viewer.getContentProvider();
                provider.visualTree = visualTreeAction.isChecked();
                MSAAViewRegistory.refreshRootObject();
            }
        };
        
        debugTreeAction = new Action(Messages.getString("flash.debugMode"),Action.AS_CHECK_BOX) { //$NON-NLS-1$
            public void run() {
                FlashFinder.debugMode = debugTreeAction.isChecked();
                MSAAViewRegistory.refreshRootObject();
            }
        };

        scanWindowlessAction = new Action(Messages.getString("flash.scanWindowless"),Action.AS_CHECK_BOX) { //$NON-NLS-1$
            public void run() {
                FlashFinder.scanAll = scanWindowlessAction.isChecked();
                MSAAViewRegistory.refreshRootObject();
            }
        };
        
	}

    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 FlashDOMContentProvider implements ITreeContentProvider {

		public boolean visualTree = false;
		public boolean informativeTree = false;

		public Object[] getChildren(Object parentElement) {
			if( parentElement instanceof FlashNode ) {
				return ((FlashNode)parentElement).getChildren(visualTree,informativeTree/*,debugMode*/);
			}
	        return new Object[0];
		}

		public Object getParent(Object element) {
			if( element instanceof FlashNode ) {
				return ((FlashNode)element).getParent();
			}
			return null;
		}

		public boolean hasChildren(Object element) {
			if( element instanceof FlashNode ) {
				return ((FlashNode)element).hasChild(visualTree);
			}
			return false;
		}

		public Object[] getElements(Object inputElement) {
            List elements = new ArrayList();
            if( inputElement instanceof Object[] ){
                Object[] objects = (Object[])inputElement;
                for( int i=0; i<objects.length; i++ ) {
                    if( objects[i] instanceof AccessibleObject ) {
                        AccessibleObject accObject= (AccessibleObject)objects[i];
                        FlashPlayer player = FlashPlayer.getPlayerFromObject(accObject);
                        if( null != player ) {
                            FlashNode rootNode = player.getRootNode();
                            if( null != rootNode ) {
                                if( FlashUtil.isInvisibleFlash(accObject) ) {
                                    player.isVisible = false;
                                }
                                elements.add(rootNode);
                            }
                            else {
                                elements.add(player);
                            }
                        }
                    }
                }
            }
            return elements.toArray();
		}
		

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
		
	}
	
    private static String getNodeImage(Object element) {
        String iconType = null;
        if( element instanceof FlashNode ) {
            FlashNode flashNode = ((FlashNode)element);
            String type = flashNode.getType();
            if( "movieclip".equals(type) ) { //$NON-NLS-1$
                iconType = type;
                int accRole = flashNode.getAccInfo().getAccRole();
                if( -1 != accRole ) {
                    return GuiImages.roleIcon(accRole);
                }
                else if( flashNode.getAccInfo().hasOnRelease() ) {
                    iconType = FlashImages.TYPE_button;
                }
            }
            else if( "object".equals(type) ) { //$NON-NLS-1$
                iconType = type;
                String className = flashNode.getClassName();
                if( "Button".equals(className) ) { //$NON-NLS-1$
                    iconType = FlashImages.TYPE_button;
                }
                else if( className.startsWith("TextField") ) { //$NON-NLS-1$
                    iconType = FlashImages.TYPE_text;
                }
                else {
                    String objectName = flashNode.getObjectName();
                    if( "_accProps".equals(objectName) ||  //$NON-NLS-1$
                    	"_accImpl".equals(objectName) ) { //$NON-NLS-1$
                        iconType = FlashImages.TYPE_accprops;
                    }
                }
            }
            else if( "function".equals(type) || //$NON-NLS-1$
            		 "string".equals(type) ) { //$NON-NLS-1$
                iconType = type;
            }
            else if( "number".equals(type) ||  //$NON-NLS-1$
                     "null".equals(type) ||  //$NON-NLS-1$
                     "boolean".equals(type) ||  //$NON-NLS-1$
                     "undefined".equals(type) ) { //$NON-NLS-1$
                iconType = FlashImages.TYPE_variable;
            }
            else {
                iconType = FlashImages.TYPE_others;
            }
        }
        else if( element instanceof FlashPlayer ) {
            iconType = FlashImages.TYPE_flash;
        }
        return null!=iconType ? FlashImages.flashIcon(iconType) : null;
    }
    
    private static String getNodeText(Object element) {
        if( element instanceof FlashNode ) {
            FlashNode flashNode = (FlashNode)element;
            StringBuffer sb = new StringBuffer();
            String text = flashNode.getText();
            if( null !=text ) {
                sb.append(text);
            }
            String title = flashNode.getTitle();
            if( null != title ) {
                if( sb.length()>0 ) {
                    sb.append(" "); //$NON-NLS-1$
                }
                sb.append(title);
            }
            String value = flashNode.getValue();
            if( null != value ) {
                if( sb.length()>0 ) {
                    sb.append(" "); //$NON-NLS-1$
                }
                sb.append(value);
            }
            if( sb.length()==0 ) {
                sb.append(Messages.getString("msaa.NAMELESS")); //$NON-NLS-1$
            }
            String objectName = flashNode.getObjectName();
            if( sb.length()>0 ) {
                sb.append(" "); //$NON-NLS-1$
            }
            sb.append(objectName);
            String type = flashNode.getType();
            if( null != type ) {
                sb.append("("); //$NON-NLS-1$
                sb.append(type);
                sb.append(")"); //$NON-NLS-1$
            }
            return sb.toString();
        }
        else if( element instanceof FlashPlayer ) {
            return ((FlashPlayer)element).getErrorText(); 
        }
        if( null==element ) return "null"; //$NON-NLS-1$
        return element.toString();
    }

    public String getNodeError(Object element) {
        if( element instanceof FlashNode ) {
            FlashNode flashNode = (FlashNode)element;
            if( !flashNode.getPlayer().isVisible ) {
                return FlashImages.OVER_BLACK;
            }
            if( flashNode.isUIComponent() ) {
                if( -1 == flashNode.getAccInfo().getAccRole() ) {
                    return FlashImages.OVER_RED;
                }
            }
            boolean shouldWarn = "movieclip".equals(flashNode.getType()) || //$NON-NLS-1$
                                 "Button".equals(flashNode.getClassName()); //$NON-NLS-1$
            if( shouldWarn && flashNode.getAccInfo().isSilent() ) {
                return FlashImages.OVER_BLACK;
            }
            if( null != flashNode.getText() ) {
                return FlashImages.OVER_GREEN;
            }
            if( shouldWarn && null == flashNode.getAccInfo().getAccName() ) {
                return FlashImages.OVER_RED;
            }
            if( "Button".equals(flashNode.getClassName()) ) { //$NON-NLS-1$
                return FlashImages.OVER_YELLOW;
            }
            String objectName = flashNode.getObjectName();
            if( "onRelease".equals(objectName) ) { //$NON-NLS-1$
                return FlashImages.OVER_YELLOW;
            }
            if( "_accProps".equals(objectName) || //$NON-NLS-1$
                "_accImpl".equals(objectName) ) { //$NON-NLS-1$
                return FlashImages.OVER_GREEN;
            }
        }
        else if (element instanceof FlashPlayer) {
            return FlashImages.OVER_BLACK;
        }
        return null;
    }
    
    private class FlashDOMLabelProvider extends LabelProvider implements IColorProvider {

		
		public FlashDOMLabelProvider() {
			super();
		}

		public Image getImage(Object element) {
            String nodeImage = getNodeImage(element);
            String nodeError = getNodeError(element);
            if( null != nodeImage ) {
                if( null != nodeError ) {
                    return FlashImages.getImage(nodeImage,nodeError, new Point(16,16));                }
                return FlashImages.getImage(nodeImage);
            }
            else if( null != nodeError) {
                return FlashImages.getImage(nodeError);
            }
			return null;
		}

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

		public Color getBackground(Object element) {
			return null;
		}

		public Color getForeground(Object element) {
			return null;
		}
		
	}

    private class FlashTreeViewer extends TreeViewer {
        
        public FlashTreeViewer(Composite parent, int style) {
            super(new Tree(parent, style));
        }
        
        public TreeItem[] getChildItems(TreeItem item) {
            super.createChildren(item);
            return item.getItems();
        }
    }
}
