/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
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.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.resource.ImageDescriptor;
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.contentmergeviewer.IMergeViewerContentProvider;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
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 {
		
		private boolean fLeft;
		
		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;
		
		public Resizer(Control c, int dir) {
			fDirection= dir;
			fControl= c;
			fControl.addMouseListener(this);
			fLiveResize= !(fControl instanceof Sash);
			
			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;
			fControl.addMouseMoveListener(this);
		}
		
		public void mouseUp(MouseEvent e) {
			fControl.removeMouseMoveListener(this);
			if (!fLiveResize)
				resize(e);
		}
		
		public void mouseMove(MouseEvent e) {
			if (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;

	// 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 retrieves the content from the three sides by calling the methods
	 * <code>getAncestorContent</code>, <code>getLeftContent</code>,
	 * and <code>getRightContent</code> on the content provider.
	 * The values returned from these calls are passed to the hook method <code>updateContent</code>.
	 * </p>
	 *
	 * @param input the new input of this viewer, or <code>null</code> if none
	 * @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);
	}
	
	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,
//						IDialogConstants.CANCEL_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;
	}
		
	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);
						
		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$
			}
			
			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$
			}
			
			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) {
		
		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);
		}
	}
	
	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);
		}
	}
}
