/*******************************************************************************
 * 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.contentmergeviewer;

import java.util.ResourceBundle;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IWorkbenchPartSite;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.util.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelection;

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

/**
 * An abstract compare and merge viewer with two side-by-side content areas
 * and an optional content area for the ancestor. The implementation makes no
 * assumptions about the content type.
 * <p>
 * <code>ContentMergeViewer</code>
 * <ul>
 * <li>implements the overall layout and defines hooks so that subclasses
 *	can easily provide an implementation for a specific content type,
 * <li>implements the UI for making the areas resizable,
 * <li>has an action for controlling whether the ancestor area is visible or not,
 * <li>has actions for copying one side of the input to the other side,
 * <li>tracks the dirty state of the left and right sides and send out notification
 *	on state changes.
 * </ul>
 * A <code>ContentMergeViewer</code> accesses its
 * model by means of a content provider which must implement the
 * <code>IMergeViewerContentProvider</code> interface.
 * </p>
 * <p>
 * Clients may wish to use the standard concrete subclass <code>TextMergeViewer</code>,
 * or define their own subclass.
 * 
 * @see IMergeViewerContentProvider
 * @see TextMergeViewer
 */
public abstract class ContentMergeViewer extends ContentViewer
					implements IPropertyChangeNotifier, ISavable {
	
	class SaveAction extends MergeViewerAction {
				
		SaveAction(boolean left) {
			super(true, false, false);
			Utilities.initAction(this, getResourceBundle(), "action.save."); //$NON-NLS-1$
		}
			
		public void run() {
			saveContent(getInput());
		}
	};
	
	/**
	 * Property names.
	 */
	private static final String ANCESTOR_ENABLED= ComparePreferencePage.INITIALLY_SHOW_ANCESTOR_PANE;	
	
	/* package */ static final int HORIZONTAL= 1;
	/* package */ static final int VERTICAL= 2;
	
	static final double HSPLIT= 0.5;
	static final double VSPLIT= 0.3;
	
	private class ContentMergeViewerLayout extends Layout {
		
		public Point computeSize(Composite c, int w, int h, boolean force) {
			return new Point(100, 100);
		}
		
		public void layout(Composite composite, boolean force) {
			
			// determine some derived sizes
			int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
			Rectangle r= composite.getClientArea();
			
			int centerWidth= getCenterWidth();	
			int width1= (int)((r.width-centerWidth)*fHSplit);
			int width2= r.width-width1-centerWidth;
			
			int height1= 0;
			int height2= 0;
			if (fAncestorEnabled && fShowAncestor) {
				height1= (int)((r.height-(2*headerHeight))*fVSplit);
				height2= r.height-(2*headerHeight)-height1;
			} else {
				height1= 0;
				height2= r.height-headerHeight;
			}		
							
			int y= 0;
			
			if (fAncestorEnabled && fShowAncestor) {
				fAncestorLabel.setBounds(0, y, r.width, headerHeight);
				fAncestorLabel.setVisible(true);
				y+= headerHeight;
				handleResizeAncestor(0, y, r.width, height1);
				y+= height1;
			} else {
				fAncestorLabel.setVisible(false);
				handleResizeAncestor(0, 0, 0, 0);
			}
			
			fLeftLabel.getSize();	// without this resizing would not always work
			
			if (centerWidth > 3) {
				fLeftLabel.setBounds(0, y, width1+1, headerHeight);
				fDirectionLabel.setVisible(true);
				fDirectionLabel.setBounds(width1+1, y, centerWidth-1, headerHeight);
				fRightLabel.setBounds(width1+centerWidth, y, width2, headerHeight);
			} else {
				fLeftLabel.setBounds(0, y, width1, headerHeight);
				fDirectionLabel.setVisible(false);
				fRightLabel.setBounds(width1, y, r.width-width1, headerHeight);
			}
			
			y+= headerHeight;
			
			if (fCenter != null && !fCenter.isDisposed())
				fCenter.setBounds(width1, y, centerWidth, height2);
					
			handleResizeLeftRight(0, y, width1, centerWidth, width2, height2);
		}
	}

	class Resizer extends MouseAdapter implements MouseMoveListener {
				
		Control fControl;
		int fX, fY;
		int fWidth1, fWidth2;
		int fHeight1, fHeight2;
		int fDirection;
		boolean fLiveResize;
		boolean fIsDown;
		
		public Resizer(Control c, int dir) {
			fDirection= dir;
			fControl= c;
			fLiveResize= !(fControl instanceof Sash);
			fControl.addMouseListener(this);
			fControl.addMouseMoveListener(this);
			fControl.addDisposeListener(
				new DisposeListener() {
					public void widgetDisposed(DisposeEvent e) {
						fControl= null;
					}
				}
			);
		}
		
		public void mouseDoubleClick(MouseEvent e) {
			if ((fDirection & HORIZONTAL) != 0)
				fHSplit= HSPLIT;
			if ((fDirection & VERTICAL) != 0)
				fVSplit= VSPLIT;
			fComposite.layout(true);
		}
		
		public void mouseDown(MouseEvent e) {
			Composite parent= fControl.getParent();
			
			Point s= parent.getSize();
			Point as= fAncestorLabel.getSize();
			Point ys= fLeftLabel.getSize();
			Point ms= fRightLabel.getSize();
			
			fWidth1= ys.x;
			fWidth2= ms.x;
			fHeight1= fLeftLabel.getLocation().y-as.y;
			fHeight2= s.y-(fLeftLabel.getLocation().y+ys.y);
			
			fX= e.x;
			fY= e.y;
			fIsDown= true;
		}
		
		public void mouseUp(MouseEvent e) {
			fIsDown= false;
			if (!fLiveResize)
				resize(e);
		}
		
		public void mouseMove(MouseEvent e) {
			if (fIsDown && fLiveResize)
				resize(e);
		}
		
		private void resize(MouseEvent e) {
			int dx= e.x-fX;
			int dy= e.y-fY;
		
			int centerWidth= fCenter.getSize().x;

			if (fWidth1 + dx > centerWidth && fWidth2 - dx > centerWidth) {
				fWidth1+= dx;
				fWidth2-= dx;
				if ((fDirection & HORIZONTAL) != 0)
					fHSplit= (double)fWidth1/(double)(fWidth1+fWidth2);
			}
			if (fHeight1 + dy > centerWidth && fHeight2 - dy > centerWidth) {
				fHeight1+= dy;
				fHeight2-= dy;
				if ((fDirection & VERTICAL) != 0)
					fVSplit= (double)fHeight1/(double)(fHeight1+fHeight2);
			}

			fComposite.layout(true);
			fControl.getDisplay().update();
		}
	};

	/** Style bits for top level composite */
	private int fStyles;
	private ResourceBundle fBundle;
	private CompareConfiguration fCompareConfiguration;
	private IPropertyChangeListener fPropertyChangeListener;
	private ICompareInputChangeListener fCompareInputChangeListener;
	private ListenerList fListenerList;
	boolean fConfirmSave= true;
	
	private double fHSplit= HSPLIT;		// width ratio of left and right panes
	private double fVSplit= VSPLIT;		// height ratio of ancestor and bottom panes
	
	private boolean fAncestorEnabled= true;	// show ancestor in case of conflicts
	/* package */ boolean fShowAncestor= false;	// if current input has conflicts
	private boolean fIsThreeWay= false;
	private ActionContributionItem fAncestorItem;
	
	private Action fCopyLeftToRightAction;	// copy from left to right
	private Action fCopyRightToLeftAction;	// copy from right to left

	MergeViewerAction fLeftSaveAction;
	MergeViewerAction fRightSaveAction;
	
	private IKeyBindingService fKeyBindingService;

	// SWT widgets
	/* package */ Composite fComposite;
	private CLabel fAncestorLabel;
	private CLabel fLeftLabel;
	private CLabel fRightLabel;
	/* package */ CLabel fDirectionLabel;
	/* package */ Control fCenter;
		
	//---- SWT resources to be disposed
	private Image fRightArrow;
	private Image fLeftArrow;
	private Image fBothArrow;
	//---- end
	
	/**
	 * Creates a new content merge viewer and initializes with a resource bundle and a
	 * configuration.
	 *
	 * @param bundle the resource bundle
	 * @param cc the configuration object
	 */
	protected ContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
		fStyles= style;
		fBundle= bundle;
		
		fAncestorEnabled= Utilities.getBoolean(cc, ANCESTOR_ENABLED, fAncestorEnabled);
		fConfirmSave= Utilities.getBoolean(cc, CompareEditor.CONFIRM_SAVE_PROPERTY, fConfirmSave);

		setContentProvider(new MergeViewerContentProvider(cc));
		
		fCompareInputChangeListener= new ICompareInputChangeListener() {
			public void compareInputChanged(ICompareInput input) {
				ContentMergeViewer.this.internalRefresh(input);
			}
		};
		
		fCompareConfiguration= cc;
		if (fCompareConfiguration != null) {
			fPropertyChangeListener= new IPropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent event) {
					ContentMergeViewer.this.propertyChange(event);
				}
			};
			fCompareConfiguration.addPropertyChangeListener(fPropertyChangeListener);
		}
			
		fLeftSaveAction= new SaveAction(true);
		fLeftSaveAction.setEnabled(false);
		fRightSaveAction= new SaveAction(false);
		fRightSaveAction.setEnabled(false);
	}
	
	//---- hooks ---------------------
	
	/**
	 * Returns the viewer's name.
	 *
	 * @return the viewer's name
	 */
	public String getTitle() {
		return Utilities.getString(getResourceBundle(), "title"); //$NON-NLS-1$
	}
	
	/**
	 * Creates the SWT controls for the ancestor, left, and right
	 * content areas of this compare viewer.
	 * Implementations typically hold onto the controls
	 * so that they can be initialized with the input objects in method
	 * <code>updateContent</code>.
	 *
	 * @param composite the container for the three areas
	 */
	abstract protected void createControls(Composite composite);

	/**
	 * Lays out the ancestor area of the compare viewer.
	 * It is called whenever the viewer is resized or when the sashes between
	 * the areas are moved to adjust the size of the areas.
	 *
	 * @param x the horizontal position of the ancestor area within its container
	 * @param y the vertical position of the ancestor area within its container
	 * @param width the width of the ancestor area
	 * @param height the height of the ancestor area
	 */
	abstract protected void handleResizeAncestor(int x, int y, int width, int height);
	
	/**
	 * Lays out the left and right areas of the compare viewer.
	 * It is called whenever the viewer is resized or when the sashes between
	 * the areas are moved to adjust the size of the areas.
	 *
	 * @param x the horizontal position of the left area within its container
	 * @param y the vertical position of the left and right area within its container
	 * @param leftWidth the width of the left area
	 * @param centerWidth the width of the gap between the left and right areas
	 * @param rightWidth the width of the right area
	 * @param height the height of the left and right areas
	 */
	abstract protected void handleResizeLeftRight(int x, int y, int leftWidth, int centerWidth,
			int rightWidth, int height);

	/**
	 * Contributes items to the given <code>ToolBarManager</code>.
	 * It is called when this viewer is installed in its container and if the container
	 * has a <code>ToolBarManager</code>.
	 * The <code>ContentMergeViewer</code> implementation of this method does nothing.
	 * Subclasses may reimplement.
	 *
	 * @param toolBarManager the toolbar manager to contribute to
	 */
	protected void createToolItems(ToolBarManager toolBarManager) {
	}

	/**
	 * Initializes the controls of the three content areas with the given input objects.
	 *
	 * @param ancestor the input for the ancestor area
	 * @param left the input for the left area
	 * @param right the input for the right area
	 */
	abstract protected void updateContent(Object ancestor, Object left, Object right);
		
	/**
	 * Copies the content of one side to the other side.
	 * Called from the (internal) actions for copying the sides of the viewer's input object.
	 * 
	 * @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
	 */
	abstract protected void copy(boolean leftToRight);

	/**
	 * Returns the byte contents of the left or right side. If the viewer
	 * has no editable content <code>null</code> can be returned.
	 *
	 * @param left if <code>true</code>, the byte contents of the left area is returned;
	 * 	if <code>false</code>, the byte contents of the right area
	 * @return the content as an array of bytes, or <code>null</code>
	 */
	abstract protected byte[] getContents(boolean left);

	//----------------------------
	
	/**
	 * Returns the resource bundle of this viewer.
	 *
	 * @return the resource bundle
	 */
	protected ResourceBundle getResourceBundle() {
		return fBundle;
	}
	
	/**
	 * Returns the compare configuration of this viewer,
	 * or <code>null</code> if this viewer does not yet have a configuration.
	 *
	 * @return the compare configuration, or <code>null</code> if none
	 */
	protected CompareConfiguration getCompareConfiguration() {
		return fCompareConfiguration;
	}
	
	/**
	 * The <code>ContentMergeViewer</code> implementation of this 
	 * <code>ContentViewer</code> method
	 * checks to ensure that the content provider is an <code>IMergeViewerContentProvider</code>.
	 */
	public void setContentProvider(IContentProvider contentProvider) {
		Assert.isTrue(contentProvider instanceof IMergeViewerContentProvider);
		super.setContentProvider(contentProvider);
	}

	/* package */ IMergeViewerContentProvider getMergeContentProvider() {
		return (IMergeViewerContentProvider) getContentProvider();
	}

	/**
	 * The <code>ContentMergeViewer</code> implementation of this 
	 * <code>Viewer</code> method returns the empty selection. Subclasses may override.
	 */
	public ISelection getSelection() {
		return new ISelection() {
			public boolean isEmpty() {
				return true;
			}
		};
	}
	
	/**
	 * The <code>ContentMergeViewer</code> implementation of this 
	 * <code>Viewer</code> method does nothing. Subclasses may reimplement.
	 */
	public void setSelection(ISelection s, boolean reveal) {
	}

	/* package */ void propertyChange(PropertyChangeEvent event) {
		
		String key= event.getProperty();

		if (key.equals(ANCESTOR_ENABLED)) {
			fAncestorEnabled= Utilities.getBoolean(getCompareConfiguration(), ANCESTOR_ENABLED, fAncestorEnabled);
			fComposite.layout(true);
			return;
		}
	}
	
	void setAncestorVisibility(boolean visible, boolean enabled) {
		if (fAncestorItem != null) {
			Action action= (Action) fAncestorItem.getAction();
			if (action != null) {
				action.setChecked(visible);
				action.setEnabled(enabled);
			}
		}
		if (fCompareConfiguration != null)
			fCompareConfiguration.setProperty(ANCESTOR_ENABLED, new Boolean(visible));
	}

	//---- input
			 
	/* package */ boolean isThreeWay() {
		return fIsThreeWay;
	}
	
	/**
	 * Internal hook method called when the input to this viewer is
	 * initially set or subsequently changed.
	 * <p>
	 * The <code>ContentMergeViewer</code> implementation of this <code>Viewer</code>
	 * method tries to save the old input by calling <code>doSave(...)</code> and
	 * then calls <code>internalRefresh(...)</code>.
	 *
	 * @param input the new input of this viewer, or <code>null</code> if there is no new input
	 * @param oldInput the old input element, or <code>null</code> if there was previously no input
	 */
	protected final void inputChanged(Object input, Object oldInput) {
		
		if (input != oldInput)
			if (oldInput instanceof ICompareInput)
				((ICompareInput)oldInput).removeCompareInputChangeListener(fCompareInputChangeListener);
		
		boolean success= doSave(input, oldInput);
		
		if (input != oldInput)
			if (input instanceof ICompareInput)
				((ICompareInput)input).addCompareInputChangeListener(fCompareInputChangeListener);
		
		if (success) {
			setLeftDirty(false);
			setRightDirty(false);
		}

		if (input != oldInput)
			internalRefresh(input);
	}
	
	/**
	 * This method is called from the <code>Viewer</code> method <code>inputChanged</code>
	 * to save any unsaved changes of the old input.
	 * <p>
	 * The <code>ContentMergeViewer</code> implementation of this
	 * method calls <code>saveContent(...)</code>. If confirmation has been turned on
	 * with <code>setConfirmSave(true)</code>, a confirmation alert is posted before saving.
	 * </p>
	 * Clients can override this method and are free to decide whether
	 * they want to call the inherited method.
	 * @param newInput the new input of this viewer, or <code>null</code> if there is no new input
	 * @param oldInput the old input element, or <code>null</code> if there was previously no input
	 * @return <code>true</code> if saving was successful, or if the user didn't want to save (by pressing 'NO' in the confirmation dialog).
	 * @since 2.0
	 */
	protected boolean doSave(Object newInput, Object oldInput) {
		
		// before setting the new input we have to save the old
		if (fLeftSaveAction.isEnabled() || fRightSaveAction.isEnabled()) {
			
			// post alert
			if (fConfirmSave) {
				Shell shell= fComposite.getShell();
				
				MessageDialog dialog= new MessageDialog(shell,
					Utilities.getString(getResourceBundle(), "saveDialog.title"), //$NON-NLS-1$
					null, 	// accept the default window icon
					Utilities.getString(getResourceBundle(), "saveDialog.message"), //$NON-NLS-1$
					MessageDialog.QUESTION,
					new String[] {
						IDialogConstants.YES_LABEL,
						IDialogConstants.NO_LABEL,
					},
					0);		// default button index
									
				switch (dialog.open()) {	// open returns index of pressed button
				case 0:
					saveContent(oldInput);
					break;
				case 1:
					setLeftDirty(false);
					setRightDirty(false);
					break;
				case 2:
					throw new ViewerSwitchingCancelled();
				}
			} else
				saveContent(oldInput);
			return true;
		}
		return false;
	}
		
	/**
	 * Controls whether <code>doSave(Object, Object)</code> asks for confirmation before saving
	 * the old input with <code>saveContent(Object)</code>.
	 * @param enable a value of <code>true</code> enables confirmation
	 * @since 2.0
	 */
	public void setConfirmSave(boolean enable) {
		fConfirmSave= enable;
	}
	
	/* (non Javadoc)
	 * see Viewer.refresh
	 */
	public void refresh() {
		internalRefresh(getInput());
	}
	
	private void internalRefresh(Object input) {
		
		IMergeViewerContentProvider content= getMergeContentProvider();
		if (content != null) {
			Object ancestor= content.getAncestorContent(input);
			if (input instanceof ICompareInput)	
				fIsThreeWay= (((ICompareInput)input).getKind() & Differencer.DIRECTION_MASK) != 0;
			else
				fIsThreeWay= ancestor != null;
				
			if (fAncestorItem != null)
				fAncestorItem.setVisible(fIsThreeWay);
				
			boolean oldFlag= fShowAncestor;
			fShowAncestor= fIsThreeWay && content.showAncestor(input);
			
			if (fAncestorEnabled && oldFlag != fShowAncestor)
				fComposite.layout(true);
			
			ToolBarManager tbm= CompareViewerSwitchingPane.getToolBarManager(fComposite.getParent());
			if (tbm != null) {
				updateToolItems();
				tbm.update(true);
				tbm.getControl().getParent().layout(true);
			}
			
			updateHeader();
									
			Object left= content.getLeftContent(input);
			Object right= content.getRightContent(input);
			updateContent(ancestor, left, right);
		}
	}
	
	//---- layout & SWT control creation
		
	/**
	 * Builds the SWT controls for the three areas of a compare/merge viewer.
	 * <p>
	 * Calls the hooks <code>createControls</code> and <code>createToolItems</code>
	 * to let subclasses build the specific content areas and to add items to
	 * an enclosing toolbar.
	 * <p>
	 * This method must only be called in the constructor of subclasses.
	 *
	 * @param parent the parent control
	 * @return the new control
	 */
	protected final Control buildControl(Composite parent) {
									
		fComposite= new Composite(parent, fStyles) {
			public boolean setFocus() {
				return internalSetFocus();
			}
		};
		fComposite.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());
		
		hookControl(fComposite);	// hook help & dispose listener
		
		fComposite.setLayout(new ContentMergeViewerLayout());
		
		int style= SWT.SHADOW_OUT;
		fAncestorLabel= new CLabel(fComposite, style);
		
		fLeftLabel= new CLabel(fComposite, style);
		new Resizer(fLeftLabel, VERTICAL);
		
		fDirectionLabel= new CLabel(fComposite, style);
		fDirectionLabel.setAlignment(SWT.CENTER);
		new Resizer(fDirectionLabel, HORIZONTAL | VERTICAL);
		
		fRightLabel= new CLabel(fComposite, style);
		new Resizer(fRightLabel, VERTICAL);
		
		if (fCenter == null || fCenter.isDisposed())
			fCenter= createCenter(fComposite);
				
		createControls(fComposite);
		
		IWorkbenchPartSite ps= Utilities.findSite(fComposite);
		fKeyBindingService= ps != null ? ps.getKeyBindingService() : null;
						
		ToolBarManager tbm= CompareViewerSwitchingPane.getToolBarManager(parent);
		if (tbm != null) {
			tbm.removeAll();
			
			// define groups
			tbm.add(new Separator("modes"));	//$NON-NLS-1$
			tbm.add(new Separator("merge"));	//$NON-NLS-1$
			tbm.add(new Separator("navigation"));	//$NON-NLS-1$
			
			CompareConfiguration cc= getCompareConfiguration();
		
			if (cc.isRightEditable()) {
				fCopyLeftToRightAction=
					new Action() {
						public void run() {
							copy(true);
						}
					};
				Utilities.initAction(fCopyLeftToRightAction, getResourceBundle(), "action.CopyLeftToRight."); //$NON-NLS-1$
				tbm.appendToGroup("merge", fCopyLeftToRightAction); //$NON-NLS-1$
				Utilities.registerAction(fKeyBindingService, fCopyLeftToRightAction, "org.eclipse.compare.copyAllLeftToRight");	//$NON-NLS-1$
			}
			
			if (cc.isLeftEditable()) {
				fCopyRightToLeftAction=
					new Action() {
						public void run() {
							copy(false);
						}
					};
				Utilities.initAction(fCopyRightToLeftAction, getResourceBundle(), "action.CopyRightToLeft."); //$NON-NLS-1$
				tbm.appendToGroup("merge", fCopyRightToLeftAction); //$NON-NLS-1$
				Utilities.registerAction(fKeyBindingService, fCopyRightToLeftAction, "org.eclipse.compare.copyAllRightToLeft");	//$NON-NLS-1$
			}
			
			Action a= new ChangePropertyAction(fBundle, fCompareConfiguration, "action.EnableAncestor.", ANCESTOR_ENABLED); //$NON-NLS-1$
			a.setChecked(fAncestorEnabled);
			fAncestorItem= new ActionContributionItem(a);
			fAncestorItem.setVisible(false);
			tbm.appendToGroup("modes", fAncestorItem); //$NON-NLS-1$
			
			createToolItems(tbm);
			updateToolItems();
			
			tbm.update(true);
		}
	
		return fComposite;
	}
	
	/* package */ boolean internalSetFocus() {
		return false;
	}
	
	/* package */ int getCenterWidth() {
		return 3;
	}
	
	/* package */ boolean getAncestorEnabled() {
		return fAncestorEnabled;
	}
	
	/* package */ Control createCenter(Composite parent) {
		Sash sash= new Sash(parent, SWT.VERTICAL);
		new Resizer(sash, HORIZONTAL);
		return sash;
	}
	
	/* package */ Control getCenter() {
		return fCenter;
	}
		
	/* 
	 * @see Viewer.getControl()
	 */
	public Control getControl() {
		return fComposite;
	}
	
	/**
	 * 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 (fKeyBindingService != null) {
			if (fCopyLeftToRightAction != null)
				fKeyBindingService.unregisterAction(fCopyLeftToRightAction);
			if (fCopyRightToLeftAction != null)
				fKeyBindingService.unregisterAction(fCopyRightToLeftAction);
			fKeyBindingService= null;
		}
		
		Object input= getInput();	
		if (input instanceof ICompareInput)
			((ICompareInput)input).removeCompareInputChangeListener(fCompareInputChangeListener);
		
		if (fCompareConfiguration != null && fPropertyChangeListener != null) {
			fCompareConfiguration.removePropertyChangeListener(fPropertyChangeListener);
			fPropertyChangeListener= null;
		}

		fAncestorLabel= null;
		fLeftLabel= null;
		fDirectionLabel= null;
		fRightLabel= null;
		fCenter= null;
				
		if (fRightArrow != null) {
			fRightArrow.dispose();
			fRightArrow= null;
		}
		if (fLeftArrow != null) {
			fLeftArrow.dispose();
			fLeftArrow= null;
		}
		if (fBothArrow != null) {
			fBothArrow.dispose();
			fBothArrow= null;
		}
		
		super.handleDispose(event);
  	}
  	
	/**
	 * Updates the enabled state of the toolbar items.
	 * <p>
	 * This method is called whenever the state of the items needs updating.
	 * <p>
	 * Subclasses may extend this method, although this is generally not required.
	 */
	protected void updateToolItems() {
										
		IMergeViewerContentProvider content= getMergeContentProvider();
		
		Object input= getInput();
		
		if (fCopyLeftToRightAction != null) {
			boolean enable= content.isRightEditable(input);
//			if (enable && input instanceof ICompareInput) {
//				ITypedElement e= ((ICompareInput) input).getLeft();
//				if (e == null)
//					enable= false;
//			}
			fCopyLeftToRightAction.setEnabled(enable);
		}
		
		if (fCopyRightToLeftAction != null) {
			boolean enable= content.isLeftEditable(input);
//			if (enable && input instanceof ICompareInput) {
//				ITypedElement e= ((ICompareInput) input).getRight();
//				if (e == null)
//					enable= false;
//			}
			fCopyRightToLeftAction.setEnabled(enable);
		}
	}
	
	/**
	 * Updates the headers of the three areas
	 * by querying the content provider for a name and image for
	 * the three sides of the input object.
	 * <p>
	 * This method is called whenever the header must be updated.
	 * <p>
	 * Subclasses may extend this method, although this is generally not required.
	 */
	protected void updateHeader() {
						
		IMergeViewerContentProvider content= getMergeContentProvider();
		Object input= getInput();

		if (fAncestorLabel != null) {
			fAncestorLabel.setImage(content.getAncestorImage(input));
			fAncestorLabel.setText(content.getAncestorLabel(input));
		}
		if (fLeftLabel != null) {
			fLeftLabel.setImage(content.getLeftImage(input));
			fLeftLabel.setText(content.getLeftLabel(input));
		}
		if (fRightLabel != null) {
			fRightLabel.setImage(content.getRightImage(input));
			fRightLabel.setText(content.getRightLabel(input));
		}
	}
	
//	private Image loadImage(String name) {
//		ImageDescriptor id= ImageDescriptor.createFromFile(ContentMergeViewer.class, name);
//		if (id != null)
//			return id.createImage();
//		return null;
//	}
		
	/**
	 * Calculates the height of the header.
	 */
	/* package */ int getHeaderHeight() {
		int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
		headerHeight= Math.max(headerHeight, fDirectionLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y);		
		return headerHeight;
	}

	//---- merge direction
	
	/**
	 * Returns true if both sides are editable.
	 */
	/* package */ boolean canToggleMergeDirection() {
		IMergeViewerContentProvider content= getMergeContentProvider();
		Object input= getInput();
		return content.isLeftEditable(input) && content.isRightEditable(input);
	}
	
	//---- dirty state & saving state
	
	/* (non Javadoc)
	 * see IPropertyChangeNotifier.addPropertyChangeListener
	 */
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		if (fListenerList == null)
			fListenerList= new ListenerList();
		fListenerList.add(listener);
	}
	
	/* (non Javadoc)
	 * see IPropertyChangeNotifier.removePropertyChangeListener
	 */
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		if (fListenerList != null) {
			fListenerList.remove(listener);
			if (fListenerList.isEmpty())
				fListenerList= null;
		}
	}
	
	/* package */ void fireDirtyState(boolean state) {
		Utilities.firePropertyChange(fListenerList, this, CompareEditorInput.DIRTY_STATE, null, new Boolean(state));
	}
	
	/**
	 * Sets the dirty state of the left side of this viewer.
	 * If the new value differs from the old
	 * all registered listener are notified with
	 * a <code>PropertyChangeEvent</code> with the
	 * property name <code>CompareEditorInput.DIRTY_STATE</code>.
	 *
	 * @param dirty the state of the left side dirty flag
	 */
	protected void setLeftDirty(boolean dirty) {
		if (fLeftSaveAction.isEnabled() != dirty) {
			fLeftSaveAction.setEnabled(dirty);
			fireDirtyState(dirty);
		}
	}
	
	/**
	 * Sets the dirty state of the right side of this viewer.
	 * If the new value differs from the old
	 * all registered listener are notified with
	 * a <code>PropertyChangeEvent</code> with the
	 * property name <code>CompareEditorInput.DIRTY_STATE</code>.
	 *
	 * @param dirty the state of the right side dirty flag
	 */
	protected void setRightDirty(boolean dirty) {
		if (fRightSaveAction.isEnabled() != dirty) {
			fRightSaveAction.setEnabled(dirty);
			fireDirtyState(dirty);
		}
	}
	
	/**
	 * Save the viewers's content.
	 * Note: this method is for internal use only. Clients should not call this method. 
	 * @since 2.0
	 */
	public void save(IProgressMonitor pm) throws CoreException {
		saveContent(getInput());
	}
	
	/**
	 * Save modified content back to input elements via the content provider.
	 */
	/* package */ void saveContent(Object oldInput) {
				
		// write back modified contents
		IMergeViewerContentProvider content= (IMergeViewerContentProvider) getContentProvider();
		
		boolean leftEmpty= content.getLeftContent(oldInput) == null;
		boolean rightEmpty= content.getRightContent(oldInput) == null;

		if (fCompareConfiguration.isLeftEditable() && fLeftSaveAction.isEnabled()) {
			byte[] bytes= getContents(true);
			if (leftEmpty && bytes != null && bytes.length == 0)
				bytes= null;
			setLeftDirty(false);
			content.saveLeftContent(oldInput, bytes);
		}
		
		if (fCompareConfiguration.isRightEditable() && fRightSaveAction.isEnabled()) {
			byte[] bytes= getContents(false);
			if (rightEmpty && bytes != null && bytes.length == 0)
				bytes= null;
			setRightDirty(false);
			content.saveRightContent(oldInput, bytes);
		}
	}
}
