/*******************************************************************************
 * Copyright (c) 2008 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.mappings.details;

import java.text.Collator;
import java.util.Comparator;
import java.util.Iterator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jpt.ui.JptUiPlugin;
import org.eclipse.jpt.ui.details.MappingUiProvider;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.ui.internal.widgets.Pane;
import org.eclipse.jpt.ui.internal.widgets.PostExecution;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.model.Model;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;

/**
 * This map as composite simply shows a styled text where the name of the
 * mapping and its type are displayed. The mapping type can be clicked on to
 * invoke a dialog in order to change the type.
 * <p>
 * Here the layout of this pane:
 * <pre>
 * -----------------------------------------------------------------------------
 * |                                                                           |
 * | Attribute 'name' is mapped as one to one.                                 |
 * |                               ¯¯¯¯¯¯¯¯¯¯                                  |
 * -----------------------------------------------------------------------------</pre>
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public abstract class MapAsComposite<T extends Model> extends Pane<T> {

	private boolean dragEvent;
	private boolean enabled;
	private Cursor handCursor;
	private MappingChangeHandler mappingChangeHandler;
	private int mappingTypeLength;
	private int mappingTypeStart;
	private boolean mouseDown;
	private int nameLength;
	private int nameStart;
	private StyledText styledText;

	/**
	 * The constant ID used to retrieve the dialog settings.
	 */
	private static final String DIALOG_SETTINGS = "org.eclipse.jpt.ui.dialogs.MapAsDialog";

	/**
	 * Creates a new <code>MapAsComposite</code>.
	 *
	 * @param parentPane The parent pane of this one
	 * @param parent The parent container
	 */
	public MapAsComposite(Pane<? extends T> parentPane,
	                      Composite parent) {

		super(parentPane, parent);
	}

	/**
	 * Creates the default provider responsible for clearing the mapping type.
	 *
	 * @return A provider that acts as a default mapping provider
	 */
	protected abstract MappingUiProvider<?> buildDefaultProvider();

	/**
	 * Creates the handler responsible to give the information required for
	 * completing the behavior of this pane.
	 *
	 * @return A new <code>MappingChangeHandler</code>
	 */
	protected abstract MappingChangeHandler buildMappingChangeHandler();

	private MouseListener buildMouseListener() {
		return new MouseListener() {
			public void mouseDoubleClick(MouseEvent e) {
			}

			public void mouseDown(MouseEvent e) {
				if (e.button == 1) {
					mouseDown = true;
				}
			}

			public void mouseUp(MouseEvent e) {
				mouseDown = false;
				StyledText text = (StyledText) e.widget;
				int offset = text.getCaretOffset();

				if (dragEvent) {
					dragEvent = false;

					if (isOverLink(offset)) {
						text.setCursor(handCursor);
					}
				}
				else if (isOverLink(offset)) {
					text.setCursor(handCursor);
					openMappingSelectionDialog();
					text.setCursor(null);
				}
			}
		};
	}

	private MouseMoveListener buildMouseMoveListener() {
		return new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				StyledText text = (StyledText) e.widget;

				if (mouseDown) {
					if (!dragEvent) {
						text.setCursor(null);
					}

					dragEvent = true;
					return;
				}

				int offset = -1;

				try {
					offset = text.getOffsetAtLocation(new Point(e.x, e.y));
				}
				catch (IllegalArgumentException ex) {
				}

				if (isOverLink(offset)) {
					text.setCursor(handCursor);
				}
				else {
					text.setCursor(null);
				}
			}
		};
	}

	private PostExecution<MappingSelectionDialog> buildPostExecution() {

		return new PostExecution<MappingSelectionDialog>() {
			public void execute(MappingSelectionDialog dialog) {

				if (dialog.getReturnCode() == IDialogConstants.OK_ID) {
					MappingUiProvider<?> provider = (MappingUiProvider<?>) dialog.getFirstResult();
					morphMapping(provider);
				}
			}
		};
	}

	/**
	 * Creates the full localized string by formatting the label text returned
	 * by the <code>MappingChangeHandler</code> with the mapping name and the
	 * mapping type.
	 *
	 * @param name The display string of the mapping being edited
	 * @param mappingType The localized message describing the mapping type
	 * @return The localized string describing the mapping
	 */
	protected String buildText(String name, String mappingType) {
		return NLS.bind(
			mappingChangeHandler.getLabelText(),
			name,
			mappingType
		);
	}

	/**
	 * Removes any style applied to the styled text.
	 */
	protected void clearStyleRange() {
		styledText.setStyleRange(null);
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void doPopulate() {
		super.doPopulate();
		updateDescription();
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	public void enableWidgets(boolean enabled) {
		this.enabled = enabled;
		super.enableWidgets(enabled);

		if (!styledText.isDisposed()) {
			styledText.setEnabled(enabled);

			if (enabled) {
				updateLinkRange();
			}
			else {
				clearStyleRange();
			}
		}
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void initialize() {

		super.initialize();

		this.enabled = true;
		this.mappingChangeHandler = buildMappingChangeHandler();
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void initializeLayout(Composite container) {

		handCursor = getShell().getDisplay().getSystemCursor(SWT.CURSOR_HAND);

		styledText = new StyledText(container, SWT.WRAP | SWT.READ_ONLY);
		styledText.addMouseListener(buildMouseListener());
		styledText.addMouseMoveListener(buildMouseMoveListener());
		styledText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
	}

	/**
	 * Retreive the <code>MappingUiProvider</code> that provides the UI for the
	 * current mapping.
	 *
	 * @return The <code>MappingUiProvider</code> representing the type of the
	 * mapping being edited
	 */
	protected MappingUiProvider<?> initialSelection() {

		for (Iterator<? extends MappingUiProvider<?>> iter = mappingChangeHandler.providers(); iter.hasNext(); ) {
			MappingUiProvider<?> provider = iter.next();

			if (getMappingKey() == provider.getMappingKey()) {
				return provider;
			}
		}

		return null;
	}

	/**
	 * Determines whether the given location is within the mapping type range.
	 *
	 * @param location The mouse location in character coordinate
	 * @return <code>true</code> if the mouse is over the mapping type text;
	 * <code>false</code> otherwise
	 */
	protected boolean isOverLink(int location) {

		return (location >= mappingTypeStart &&
		        location <= mappingTypeStart + mappingTypeLength);
	}

	/**
	 * Returns the mapping key representing the current mapping object.
	 *
	 * @return A non-<code>null</code> unique identifier representing the type
	 * of the mapping being edited
	 */
	protected abstract String getMappingKey();

	/**
	 * Aks the <code>MappingChangeHandler</code> to change the mapping type using
	 * the given <code>MappingUiProvider</code>.
	 *
	 * @param provider The provider used to determine the mapping type used for
	 * morphing the mapping being edited
	 */
	protected void morphMapping(MappingUiProvider<?> provider) {
		mappingChangeHandler.morphMapping(provider);
	}

	/**
	 * Opens the dialog that shows the registered mapping types in order for the
	 * user to select a provider in order to change the mapping type of the
	 * mapping being edited.
	 */
	protected void openMappingSelectionDialog() {

		MappingSelectionDialog dialog = new MappingSelectionDialog();
		SWTUtil.show(dialog, buildPostExecution());
	}

	/**
	 * Updates the description by recreating the label.
	 */
	protected void updateDescription() {

		clearStyleRange();
		updateText();

		if (enabled) {
			updateLinkRange();
		}
	}

	/**
	 * Updates the colors of the text: (1) the name is shown in bold and (2) the
	 * mapping type is shown in bold and in hyperlink color.
	 */
	protected void updateLinkRange() {

		Color linkColor = JFaceColors.getHyperlinkText(getShell().getDisplay());

		// Make the name bold
		StyleRange styleRange = new StyleRange(
			nameStart, nameLength,
			null, null,
			SWT.BOLD
		);
		styledText.setStyleRange(styleRange);

		// Make the mapping type shown as a hyperlink
		if (mappingTypeStart > -1) {
			styleRange = new StyleRange(
				mappingTypeStart, mappingTypeLength,
				linkColor, null
			);

			styleRange.underline      = true;
			styleRange.underlineColor = linkColor;
			styleRange.underlineStyle = SWT.UNDERLINE_SINGLE;
			styledText.setStyleRange(styleRange);
		}
	}

	/**
	 * Updates the styles text's input.
	 */
	protected void updateText() {

		String name = mappingChangeHandler.getName();

		if (name == null) {
			name = JptUiMappingsMessages.NoNameSet;
		}

		String mappingType = mappingChangeHandler.getMappingType();
		String text = buildText(name, mappingType);

		mappingTypeStart  = text.lastIndexOf(mappingType);
		mappingTypeLength = mappingType.length();

		nameStart  = text.indexOf(name);
		nameLength = name.length();

		styledText.setText(text);
	}

	/**
	 * This handler is responsible to give the text information and to open the
	 * mapping dialog if the user clicked on the mapping type.
	 */
	protected interface MappingChangeHandler {

		/**
		 * Returns the entire text describing the mapping (entity or mapping) and
		 * its type.
		 *
		 * @return A localized text with two arguments where the first one should
		 * be replaced by the name and the second be replaced by the mapping type
		 */
		String getLabelText();

		/**
		 * Returns the displayable text representing the mapping type.
		 *
		 * @return A human readable text describing the mapping type
		 */
		String getMappingType();

		/**
		 * Morphes the current mapping into a new type by using the given provider.
		 *
		 * @param provider The provider that was selected for changing the mapping
		 */
		void morphMapping(MappingUiProvider<?> provider);

		/**
		 * Returns the name of the current mapping.
		 *
		 * @return The displayable name of the mapping
		 */
		String getName();

		/**
		 * Returns the list of providers that are registered with the JPT plugin.
		 *
		 * @return The supported types of mapping
		 */
		Iterator<? extends MappingUiProvider<?>> providers();
	}

	/**
	 * This dialog shows the list of possible mapping types and lets the user
	 * the option to filter them using a search field.
	 */
	protected class MappingSelectionDialog extends FilteredItemsSelectionDialog {

		private MappingUiProvider<?> defaultProvider;

		/**
		 * Creates a new <code>MappingSelectionDialog</code>.
		 */
		private MappingSelectionDialog() {
			super(MapAsComposite.this.getShell(), false);
			setMessage(JptUiMessages.MapAsComposite_labelText);
			setTitle(JptUiMessages.MapAsComposite_dialogTitle);
			setListLabelProvider(buildLabelProvider());
			setDetailsLabelProvider(buildLabelProvider());
		}

		private ILabelProvider buildLabelProvider() {
			return new LabelProvider() {

				@Override
				public Image getImage(Object element) {

					if (element == null) {
						return null;
					}

					MappingUiProvider<?> provider = (MappingUiProvider<?>) element;
					return provider.getImage();
				}

				@Override
				public String getText(Object element) {

					if (element == null) {
						return "";
					}

					MappingUiProvider<?> provider = (MappingUiProvider<?>) element;
					return provider.getLabel();
				}
			};
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected Control createExtendedContentArea(Composite parent) {
			return null;
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected ItemsFilter createFilter() {
			return new MappingTypeItemsFilter();
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected void fillContentProvider(AbstractContentProvider provider,
		                                   ItemsFilter itemsFilter,
		                                   IProgressMonitor monitor) throws CoreException {

			monitor.beginTask(null, -1);

			try {
				// Add the default provider
				defaultProvider = buildDefaultProvider();

				if (defaultProvider != null) {
					provider.add(defaultProvider, itemsFilter);
				}

				// Add the registered mapping providers to the dialog
				for (Iterator<? extends MappingUiProvider<?>> iter = mappingChangeHandler.providers(); iter.hasNext(); ) {
					MappingUiProvider<?> mappingProvider = iter.next();
					provider.add(mappingProvider, itemsFilter);
				}
			}
			finally {
				monitor.done();
			}
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected IDialogSettings getDialogSettings() {

			IDialogSettings dialogSettings = JptUiPlugin.getPlugin().getDialogSettings();
			IDialogSettings settings = dialogSettings.getSection(DIALOG_SETTINGS);

			if (settings == null) {
				settings = dialogSettings.addNewSection(DIALOG_SETTINGS);
			}

			return settings;
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		public String getElementName(Object object) {
			MappingUiProvider<?> provider = (MappingUiProvider<?>) object;
			return provider.getLabel();
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected Comparator<MappingUiProvider<?>> getItemsComparator() {
			return new Comparator<MappingUiProvider<?>>() {
				public int compare(MappingUiProvider<?> item1, MappingUiProvider<?> item2) {

					if (item1 == defaultProvider) {
						return -1;
					}

					if (item2 == defaultProvider) {
						return 1;
					}

					String displayString1 = item1.getLabel();
					String displayString2 = item2.getLabel();
					return Collator.getInstance().compare(displayString1, displayString2);
				}
			};
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		protected IStatus validateItem(Object item) {

			if (item == null) {
				return new Status(IStatus.ERROR, JptUiPlugin.PLUGIN_ID, IStatus.ERROR, "", null);
			}

			return Status.OK_STATUS;
		}

		/**
		 * Create the filter responsible to remove any mapping type based on the
		 * pattern entered in the text field.
		 */
		private class MappingTypeItemsFilter extends ItemsFilter {

			/**
			 * Creates a new <code>MappingTypeItemsFilter</code>.
			 */
			MappingTypeItemsFilter() {

				super();

				// Make sure that if the pattern is empty, we specify * in order
				// to show all the mapping types
				if (StringTools.stringIsEmpty(getPattern())) {
					patternMatcher.setPattern("*");
				}
			}

			/*
			 * (non-Javadoc)
			 */
			@Override
			public boolean isConsistentItem(Object item) {
				return true;
			}

			/*
			 * (non-Javadoc)
			 */
			@Override
			public boolean matchItem(Object item) {
				MappingUiProvider<?> provider = (MappingUiProvider<?>) item;
				return matches(provider.getLabel());
			}
		}
	}
}
