/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.compare.structuremergeviewer;

import java.util.Iterator;
import java.util.ResourceBundle;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.*;

import org.eclipse.jface.util.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;

import org.eclipse.compare.internal.*;
import org.eclipse.compare.*;

/**
 * A tree viewer that works on objects implementing
 * the <code>IDiffContainer</code> and <code>IDiffElement</code> interfaces.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed outside
 * this package.
 * </p>
 *
 * @see IDiffContainer
 * @see IDiffElement
 */
public class DiffTreeViewer extends TreeViewer {
	
	static class DiffViewerSorter extends ViewerSorter {
	
		public boolean isSorterProperty(Object element, Object property) {
			return false;
		}
	
		public int category(Object node) {
			if (node instanceof DiffNode) {
				Object o= ((DiffNode) node).getId();
				if (o instanceof DocumentRangeNode)
					return ((DocumentRangeNode) o).getTypeCode();
			}
			return 0;
		}
	}	

	class DiffViewerContentProvider implements ITreeContentProvider {
			
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	
		public boolean isDeleted(Object element) {
			return false;
		}
			
		public void dispose() {
			inputChanged(DiffTreeViewer.this, getInput(), null);
		}
			
		public Object getParent(Object element) {
			if (element instanceof IDiffElement) 
				return ((IDiffElement)element).getParent();
			return null;
		}
		
		public final boolean hasChildren(Object element) {
			if (element instanceof IDiffContainer) 
				return ((IDiffContainer)element).hasChildren();
			return false;
		}
		
		public final Object[] getChildren(Object element) {
			if (element instanceof IDiffContainer)
				return ((IDiffContainer)element).getChildren();
			return new Object[0];
		}
		
		public Object[] getElements(Object element) {
			return getChildren(element);
		}				
	}
	
	/*
	 * Takes care of swapping left and right if fLeftIsLocal
	 * is true.
	 */
	class DiffViewerLabelProvider extends LabelProvider {
		
		public String getText(Object element) {
			
			if (element instanceof IDiffElement)
				return ((IDiffElement)element).getName();
						
			return Utilities.getString(fBundle, "defaultLabel"); //$NON-NLS-1$
		}
	
		public Image getImage(Object element) {
			if (element instanceof IDiffElement) {
				IDiffElement input= (IDiffElement) element;
				
				int kind= input.getKind();
				if (fLeftIsLocal) {
					switch (kind & Differencer.DIRECTION_MASK) {
					case Differencer.LEFT:
						kind= (kind &~ Differencer.LEFT) | Differencer.RIGHT;
						break;
					case Differencer.RIGHT:
						kind= (kind &~ Differencer.RIGHT) | Differencer.LEFT;
						break;
					}
				}
				
				return fCompareConfiguration.getImage(input.getImage(), kind);
			}
			return null;
		}
	}

	static class FilterSame extends ViewerFilter {
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof IDiffElement)
				return (((IDiffElement)element).getKind() & Differencer.PSEUDO_CONFLICT) == 0;
			return true;
		}
		public boolean isFilterProperty(Object element, Object property) {
			return false;
		}
	}
	
	private ResourceBundle fBundle;
	private CompareConfiguration fCompareConfiguration;
	/* package */ boolean fLeftIsLocal;
	private IPropertyChangeListener fPropertyChangeListener;

	private Action fCopyLeftToRightAction;
	private Action fCopyRightToLeftAction;
	private Action fEmptyMenuAction;
	private Action fExpandAllAction;
		
	/**
	 * Creates a new viewer for the given SWT tree control with the specified configuration.
	 *
	 * @param tree the tree control
	 * @param configuration the configuration for this viewer
	 */
	public DiffTreeViewer(Tree tree, CompareConfiguration configuration) {
		super(tree);
		initialize(configuration);
	}
	
	/**
	 * Creates a new viewer under the given SWT parent and with the specified configuration.
	 *
	 * @param parent the SWT control under which to create the viewer
	 * @param configuration the configuration for this viewer
	 */
	public DiffTreeViewer(Composite parent, CompareConfiguration configuration) {
		super(new Tree(parent, SWT.MULTI));
		initialize(configuration);
	}
	
	private void initialize(CompareConfiguration configuration) {
		
		Control tree= getControl();
		
		INavigatable nav= new INavigatable() {
			public boolean gotoDifference(boolean next) {
				// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
				return internalNavigate(next, true);
			}
		};
		tree.setData(INavigatable.NAVIGATOR_PROPERTY, nav);
		
		// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
		IOpenable openable= new IOpenable() {
			public void openSelected() {
				internalOpen();
			}
		};
		tree.setData(IOpenable.OPENABLE_PROPERTY, openable);
		
		fLeftIsLocal= Utilities.getBoolean(configuration, "LEFT_IS_LOCAL", false); //$NON-NLS-1$

		tree.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());

		Composite parent= tree.getParent();
		
		fBundle= ResourceBundle.getBundle("org.eclipse.compare.structuremergeviewer.DiffTreeViewerResources"); //$NON-NLS-1$
		
		// register for notification with the CompareConfiguration 
		fCompareConfiguration= configuration;
		if (fCompareConfiguration != null) {
			fPropertyChangeListener= new IPropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent event) {
					DiffTreeViewer.this.propertyChange(event);
				}
			};
			fCompareConfiguration.addPropertyChangeListener(fPropertyChangeListener);
		}				
	
		setContentProvider(new DiffViewerContentProvider());
		setLabelProvider(new DiffViewerLabelProvider());
		
		addSelectionChangedListener(
			new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent se) {
					updateActions();
				}
			}
		);
										
		setSorter(new DiffViewerSorter());
		
		ToolBarManager tbm= CompareViewerSwitchingPane.getToolBarManager(parent);
		if (tbm != null) {
			tbm.removeAll();
			
			tbm.add(new Separator("merge")); //$NON-NLS-1$
			tbm.add(new Separator("modes")); //$NON-NLS-1$
			tbm.add(new Separator("navigation")); //$NON-NLS-1$
			
			createToolItems(tbm);
			updateActions();
			
			tbm.update(true);
		}
		
		MenuManager mm= new MenuManager();
		mm.setRemoveAllWhenShown(true);
		mm.addMenuListener(
			new IMenuListener() {
				public void menuAboutToShow(IMenuManager mm2) {
					fillContextMenu(mm2);
					if (mm2.isEmpty()) {
						if (fEmptyMenuAction == null) {
							fEmptyMenuAction=
								new Action(Utilities.getString(fBundle, "emptyMenuItem")) {};	//$NON-NLS-1$
							fEmptyMenuAction.setEnabled(false);
						}
						mm2.add(fEmptyMenuAction);
					}
				}
			}
		);
		tree.setMenu(mm.createContextMenu(tree));
	}
			
	/**
	 * Returns the viewer's name.
	 *
	 * @return the viewer's name
	 */
	public String getTitle() {
		String title= Utilities.getString(fBundle, "title", null); //$NON-NLS-1$
		if (title == null)
			title= Utilities.getString("DiffTreeViewer.title"); //$NON-NLS-1$
		return title;
	}
	
	/**
	 * Returns the resource bundle.
	 *
	 * @return the viewer's resource bundle
	 */
	protected ResourceBundle getBundle() {
		return fBundle;
	}

	/**
	 * Returns the compare configuration of this viewer.
	 *
	 * @return the compare configuration of this viewer
	 */
	public CompareConfiguration getCompareConfiguration() {
		return fCompareConfiguration;
	}
			
	/**
	 * Called on the viewer disposal.
	 * Unregisters from the compare configuration.
	 * Clients may extend if they have to do additional cleanup.
	 */
	protected void handleDispose(DisposeEvent event) {
		
		if (fCompareConfiguration != null) {
			if (fPropertyChangeListener != null)
				fCompareConfiguration.removePropertyChangeListener(fPropertyChangeListener);
			fCompareConfiguration= null;
		}
		fPropertyChangeListener= null;
		
		super.handleDispose(event);
	}
	
	/**
	 * Tracks property changes of the configuration object.
	 * Clients may extend to track their own property changes.
	 */
	protected void propertyChange(PropertyChangeEvent event) {
	}
	
	protected void inputChanged(Object in, Object oldInput) {
		super.inputChanged(in, oldInput);
		
		if (in != oldInput) {
			initialSelection();
			updateActions();
		}
	}
	
	/**
	 * This hook method is called from within <code>inputChanged</code>
	 * after a new input has been set but before any controls are updated.
	 * This default implementation calls <code>navigate(true)</code>
	 * to select and expand the first leaf node.
	 * Clients can override this method and are free to decide whether
	 * they want to call the inherited method.
	 * 
	 * @since 2.0
	 */
	protected void initialSelection() {
		navigate(true);
	}

	/**
	 * Overridden to avoid expanding <code>DiffNode</code>s that shouldn't expand.
	 */
	protected void internalExpandToLevel(Widget node, int level) {
				
		Object data= node.getData();
		
		if (dontExpand(data))
			return;
		
		super.internalExpandToLevel(node, level);
	}
	
	/**
	 * This hook method is called from within <code>internalExpandToLevel</code>
	 * to control whether a given model node should be expanded or not.
	 * This default implementation checks whether the object is a <code>DiffNode</code> and
	 * calls <code>dontExpand()</code> on it.
	 * Clients can override this method and are free to decide whether
	 * they want to call the inherited method.
	 * 
	 * @param o the model object to be expanded
	 * @return <code>false</code> if a node should be expanded, <code>true</code> to prevent expanding
	 * @since 2.0
	 */
	protected boolean dontExpand(Object o) {
		return o instanceof DiffNode && ((DiffNode)o).dontExpand();
	}
	
	//---- merge action support

	/**
	 * This factory method is called after the viewer's controls have been created.
	 * It installs four actions in the given <code>ToolBarManager</code>. Two actions
	 * allow for copying one side of a <code>DiffNode</code> to the other side.
	 * Two other actions are for navigating from one node to the next (previous).
	 * <p>
	 * Clients can override this method and are free to decide whether they want to call
	 * the inherited method.
	 *
	 * @param toolbarManager the toolbar manager for which to add the actions
	 */
	protected void createToolItems(ToolBarManager toolbarManager) {
		
//		fCopyLeftToRightAction= new Action() {
//			public void run() {
//				copySelected(true);
//			}
//		};
//		Utilities.initAction(fCopyLeftToRightAction, fBundle, "action.TakeLeft.");
//		toolbarManager.appendToGroup("merge", fCopyLeftToRightAction);

//		fCopyRightToLeftAction= new Action() {
//			public void run() {
//				copySelected(false);
//			}
//		};
//		Utilities.initAction(fCopyRightToLeftAction, fBundle, "action.TakeRight.");
//		toolbarManager.appendToGroup("merge", fCopyRightToLeftAction);
		
//		fNextAction= new Action() {
//			public void run() {
//				navigate(true);
//			}
//		};
//		Utilities.initAction(fNextAction, fBundle, "action.NextDiff."); //$NON-NLS-1$
//		toolbarManager.appendToGroup("navigation", fNextAction); //$NON-NLS-1$

//		fPreviousAction= new Action() {
//			public void run() {
//				navigate(false);
//			}
//		};
//		Utilities.initAction(fPreviousAction, fBundle, "action.PrevDiff."); //$NON-NLS-1$
//		toolbarManager.appendToGroup("navigation", fPreviousAction); //$NON-NLS-1$
	}
	
	/**
	 * This method is called to add actions to the viewer's context menu.
	 * It installs actions for expanding tree nodes, copying one side of a <code>DiffNode</code> to the other side.
	 * Clients can override this method and are free to decide whether they want to call
	 * the inherited method.
	 *
	 * @param manager the menu manager for which to add the actions
	 */
	protected void fillContextMenu(IMenuManager manager) {
		if (fExpandAllAction == null) {
			fExpandAllAction= new Action() {
				public void run() {
					expandSelection();
				}
			};
			Utilities.initAction(fExpandAllAction, fBundle, "action.ExpandAll."); //$NON-NLS-1$
		}
		
		boolean enable= false;
		ISelection selection= getSelection();
		if (selection instanceof IStructuredSelection) {
			Iterator elements= ((IStructuredSelection)selection).iterator();
			while (elements.hasNext()) {
				Object element= elements.next();
				if (element instanceof IDiffContainer) {
					if (((IDiffContainer)element).hasChildren()) {
						enable= true;
						break;
					}
				}
			}
		}
		fExpandAllAction.setEnabled(enable);

		manager.add(fExpandAllAction);
		
		if (fCopyLeftToRightAction != null)
			manager.add(fCopyLeftToRightAction);
		if (fCopyRightToLeftAction != null)
			manager.add(fCopyRightToLeftAction);
	}

	/**
	 * Expands to infinity all items in the selection.
	 * 
	 * @since 2.0
	 */
	protected void expandSelection() {
		ISelection selection= getSelection();
		if (selection instanceof IStructuredSelection) {
			Iterator elements= ((IStructuredSelection)selection).iterator();
			while (elements.hasNext()) {
				Object next= elements.next();
				expandToLevel(next, ALL_LEVELS);
			}
		}
	}

	/**
	 * Copies one side of all <code>DiffNode</code>s in the current selection to the other side.
	 * Called from the (internal) actions for copying the sides of a <code>DiffNode</code>.
	 * Clients may override. 
	 * 
	 * @param leftToRight if <code>true</code> the left side is copied to the right side.
	 * If <code>false</code> the right side is copied to the left side
	 */
	protected void copySelected(boolean leftToRight) {
		ISelection selection= getSelection();
		if (selection instanceof IStructuredSelection) {
			Iterator e= ((IStructuredSelection) selection).iterator();
			while (e.hasNext()) {
				Object element= e.next();
				if (element instanceof ICompareInput)
					copyOne((ICompareInput) element, leftToRight);
			}
		}
	}
	
	/**
	 * Called to copy one side of the given node to the other.
	 * This default implementation delegates the call to <code>ICompareInput.copy(...)</code>.
	 * Clients may override. 
	 * 
	 * @param leftToRight if <code>true</code> the left side is copied to the right side.
	 * If <code>false</code> the right side is copied to the left side
	 */
	protected void copyOne(ICompareInput node, boolean leftToRight) {
		
		node.copy(leftToRight);
		
		// update node's image
		update(new Object[] { node }, null);
	}
	
	/**
	 * Selects the next (or previous) node of the current selection.
	 * If there is no current selection the first (last) node in the tree is selected.
	 * Wraps around at end or beginning.
	 * Clients may override. 
	 *
	 * @param next if <code>true</code> the next node is selected, otherwise the previous node
	 */
	protected void navigate(boolean next) {	
		// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
		internalNavigate(next, false);
	}
	
	//---- private
	
	/**
	 * Selects the next (or previous) node of the current selection.
	 * If there is no current selection the first (last) node in the tree is selected.
	 * Wraps around at end or beginning.
	 * Clients may override. 
	 *
	 * @param next if <code>true</code> the next node is selected, otherwise the previous node
	 * @return <code>true</code> if at end (or beginning)
	 */
	private boolean internalNavigate(boolean next, boolean fireOpen) {
		
		Control c= getControl();
		if (!(c instanceof Tree))
			return false;
			
		Tree tree= (Tree) c;
		TreeItem item= null;
		TreeItem children[]= tree.getSelection();
		if (children != null && children.length > 0)
			item= children[0];
		if (item == null) {
			children= tree.getItems();
			if (children != null && children.length > 0) {
				item= children[0];
				if (item != null && item.getItemCount() <= 0) {
					internalSetSelection(item, fireOpen);				// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
					return false;
				}
			}
		}
			
		while (true) {
			item= findNextPrev(item, next);
			if (item == null)
				break;
			if (item.getItemCount() <= 0)
				break;
		}
		
		if (item != null) {
			internalSetSelection(item, fireOpen);	// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
			return false;
		}
		return true;
	}

	private TreeItem findNextPrev(TreeItem item, boolean next) {
		
		if (item == null)
			return null;
		
		TreeItem children[]= null;

		if (!next) {
		
			TreeItem parent= item.getParentItem();
			if (parent != null)
				children= parent.getItems();
			else
				children= item.getParent().getItems();
			
			if (children != null && children.length > 0) {
				// goto previous child
				int index= 0;
				for (; index < children.length; index++)
					if (children[index] == item)
						break;
				
				if (index > 0) {
					
					item= children[index-1];
					
					while (true) {
						createChildren(item);
						int n= item.getItemCount();
						if (n <= 0)
							break;
							
						item.setExpanded(true);
						item= item.getItems()[n-1];
					}

					// previous
					return item;
				}
			}
			
			// go up
			return parent;
					
		} else {
			item.setExpanded(true);
			createChildren(item);
			
			if (item.getItemCount() > 0) {
				// has children: go down
				children= item.getItems();
				return children[0];
			}
			
			while (item != null) {
				children= null;
				TreeItem parent= item.getParentItem();
				if (parent != null)
					children= parent.getItems();
				else
					children= item.getParent().getItems();
				
				if (children != null && children.length > 0) {
					// goto next child
					int index= 0;
					for (; index < children.length; index++)
						if (children[index] == item)
							break;
					
					if (index < children.length-1) {
						// next
						return children[index+1];
					}
				}
				
				// go up
				item= parent;
			}
		}
				
		return item;
	}
	
	private void internalSetSelection(TreeItem ti, boolean fireOpen) {
		if (ti != null) {
			Object data= ti.getData();
			if (data != null) {
				// Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
				ISelection selection= new StructuredSelection(data);
				setSelection(selection, true);
				ISelection currentSelection= getSelection();
				if (fireOpen && currentSelection != null && selection.equals(currentSelection)) {
					fireOpen(new OpenEvent(this, selection));
				}
			}
		}
	}
			
	private final boolean isEditable(Object element, boolean left) {
		if (element instanceof ICompareInput) {
			ICompareInput diff= (ICompareInput) element;
			Object side= left ? diff.getLeft() : diff.getRight();
			if (side == null && diff instanceof IDiffElement) {
				IDiffContainer container= ((IDiffElement)diff).getParent();
				if (container instanceof ICompareInput) {
					ICompareInput parent= (ICompareInput) container;
					side= left ? parent.getLeft() : parent.getRight();
				}
			}
			if (side instanceof IEditableContent)
				return ((IEditableContent) side).isEditable();
		}
		return false;
	}
		
	private void updateActions() {
		int leftToRight= 0;
		int rightToLeft= 0;
		ISelection selection= getSelection();
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection ss= (IStructuredSelection) selection;
			Iterator e= ss.iterator();
			while (e.hasNext()) {
				Object element= e.next();
				if (element instanceof ICompareInput) {
					if (isEditable(element, false))
						leftToRight++;
					if (isEditable(element, true))
						rightToLeft++;
					if (leftToRight > 0 && rightToLeft > 0)
						break;
				}
			}
			if (fExpandAllAction != null)
				fExpandAllAction.setEnabled(selection.isEmpty());
		}
		if (fCopyLeftToRightAction != null)
			fCopyLeftToRightAction.setEnabled(leftToRight > 0);
		if (fCopyRightToLeftAction != null)
			fCopyRightToLeftAction.setEnabled(rightToLeft > 0);
	}
	
	/*
	 * Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
	 */ 
	private void internalOpen()  {
		ISelection selection= getSelection();
		if (selection != null && !selection.isEmpty()) {
			fireOpen(new OpenEvent(this, selection));
		}
	}
}

