/*******************************************************************************
 * Copyright (c) 2004, 2015 Tasktop Technologies and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *     Kevin Barnes, IBM Corporation - fix for bug 277974
 *     Robert Munteanu - fix for bug 350771
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.ui.views;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.mylyn.commons.core.DateUtil;
import org.eclipse.mylyn.commons.ui.CommonImages;
import org.eclipse.mylyn.commons.ui.GradientToolTip;
import org.eclipse.mylyn.commons.ui.PlatformUiUtil;
import org.eclipse.mylyn.commons.ui.compatibility.CommonFonts;
import org.eclipse.mylyn.commons.workbench.forms.ScalingHyperlink;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.AbstractTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.DateRange;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
import org.eclipse.mylyn.internal.tasks.core.UncategorizedTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer;
import org.eclipse.mylyn.internal.tasks.ui.AbstractTaskListFilter;
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
import org.eclipse.mylyn.internal.tasks.ui.TaskScalingHyperlink;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotifier;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskScheduleContentProvider.StateTaskContainer;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
import org.eclipse.mylyn.tasks.core.ITaskContainer;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
import org.eclipse.mylyn.tasks.ui.TaskElementLabelProvider;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.mylyn.tasks.ui.TasksUiImages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.IFormColors;

import com.google.common.base.Strings;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;

/**
 * @author Mik Kersten
 * @author Eric Booth
 * @author Leo Dos Santos
 * @author Steffen Pingel
 */
public class TaskListToolTip extends GradientToolTip {

	public static interface TaskListToolTipListener {

		void toolTipHidden(Event event);

	}

	private final static int MAX_WIDTH = 600;

	private final static int X_SHIFT = PlatformUiUtil.getToolTipXShift();

	private final static int Y_SHIFT = 1;

	private IRepositoryElement currentTipElement;

	private final List<TaskListToolTipListener> listeners = new ArrayList<TaskListToolTipListener>();

	private boolean visible;

	private boolean triggeredByMouse = true;

	private final Control control;

	private final Color titleColor;

	private boolean enabled;

	public TaskListToolTip(Control control) {
		super(control);
		this.control = control;
		setEnabled(true);
		setShift(new Point(1, 1));
		titleColor = TasksUiPlugin.getDefault().getFormColors(control.getDisplay()).getColor(IFormColors.TITLE);
	}

	public void dispose() {
		hide();
	}

	@Override
	protected void afterHideToolTip(Event event) {
		triggeredByMouse = true;
		visible = false;
		for (TaskListToolTipListener listener : listeners.toArray(new TaskListToolTipListener[0])) {
			listener.toolTipHidden(event);
		}
	}

	public void addTaskListToolTipListener(TaskListToolTipListener listener) {
		listeners.add(listener);
	}

	public void removeTaskListToolTipListener(TaskListToolTipListener listener) {
		listeners.remove(listener);
	}

	private IRepositoryElement getTaskListElement(Object hoverObject) {
		if (hoverObject instanceof ScalingHyperlink) {
			TaskScalingHyperlink hyperlink = (TaskScalingHyperlink) hoverObject;
			return hyperlink.getTask();
		} else if (hoverObject instanceof Widget) {
			Object data = ((Widget) hoverObject).getData();
			if (data != null) {
				if (data instanceof ITaskContainer) {
					return (IRepositoryElement) data;
				} else if (data instanceof IAdaptable) {
					return (IRepositoryElement) ((IAdaptable) data).getAdapter(AbstractTaskContainer.class);
				}
			}
		}
		return null;
	}

	private String getTitleText(IRepositoryElement element) {
		if (element instanceof ScheduledTaskContainer) {
			StringBuilder sb = new StringBuilder();
			sb.append(((ScheduledTaskContainer) element).getShortSummary());
			if (!(element instanceof StateTaskContainer)) {
				Calendar start = ((ScheduledTaskContainer) element).getDateRange().getStartDate();
				sb.append(" - "); //$NON-NLS-1$
				sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(start.getTime()));
			}
			return sb.toString();
		} else if (element instanceof IRepositoryQuery) {
			IRepositoryQuery query = (IRepositoryQuery) element;
			StringBuilder sb = new StringBuilder();
			sb.append(element.getSummary());
			sb.append("  ["); //$NON-NLS-1$
			sb.append(getRepositoryLabel(query.getConnectorKind(), query.getRepositoryUrl()));
			sb.append("]"); //$NON-NLS-1$
			return sb.toString();
		} else if (element instanceof ITask) {
			return ((ITask) element).getSummary();
		} else {
			return new TaskElementLabelProvider(false).getText(element);
		}
	}

	private String getDetailsText(IRepositoryElement element) {
		if (element instanceof ScheduledTaskContainer) {
			ScheduledTaskContainer container = (ScheduledTaskContainer) element;
			int estimateTotal = 0;
			long activeTotal = 0;
			for (ITask child : container.getChildren()) {
				if (child instanceof AbstractTask) {
					estimateTotal += ((AbstractTask) child).getEstimatedTimeHours();
					activeTotal += TasksUiPlugin.getTaskActivityManager().getElapsedTime(child,
							container.getDateRange());
				}
			}
			StringBuilder sb = new StringBuilder();
			appendEstimateAndActive(sb, estimateTotal, activeTotal);
			return sb.toString();
		} else if (element instanceof ITask) {
			ITask task = (ITask) element;
			StringBuilder sb = new StringBuilder();
			AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(task.getConnectorKind());
			String kindLabel = null;
			if (connectorUi != null) {
				kindLabel = connectorUi.getTaskKindLabel(task);
				sb.append(kindLabel);
			}
			String key = task.getTaskKey();
			if (key != null) {
				sb.append(" "); //$NON-NLS-1$
				sb.append(key);
			}
			String taskKind = task.getTaskKind();
			if (taskKind != null && taskKind.length() > 0 && !taskKind.equals(kindLabel)) {
				sb.append(" ("); //$NON-NLS-1$
				sb.append(taskKind);
				sb.append(") "); //$NON-NLS-1$
			}
			sb.append(", "); //$NON-NLS-1$
			String priorityLabel = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_PRIORITY_LABEL);
			if (Strings.isNullOrEmpty(priorityLabel)) {
				priorityLabel = task.getPriority();
			}
			sb.append(priorityLabel);
			sb.append("  ["); //$NON-NLS-1$
			sb.append(getRepositoryLabel(task.getConnectorKind(), task.getRepositoryUrl()));
			sb.append("]"); //$NON-NLS-1$
			return sb.toString();
		} else {
			return null;
		}
	}

	private void appendEstimateAndActive(StringBuilder sb, int estimateTotal, long activeTotal) {
		sb.append(NLS.bind(Messages.TaskListToolTip_Estimate, estimateTotal));
		sb.append("\n"); //$NON-NLS-1$
		if (TasksUiInternal.isActivityTrackingEnabled()) {
			sb.append(NLS.bind(Messages.TaskListToolTip_Active_X, DateUtil.getFormattedDurationShort(activeTotal)));
			sb.append("\n"); //$NON-NLS-1$
		}
	}

	private String getRepositoryLabel(String repositoryKind, String repositoryUrl) {
		TaskRepository repository = TasksUi.getRepositoryManager().getRepository(repositoryKind, repositoryUrl);
		if (repository != null) {
			String label = repository.getRepositoryLabel();
			if (label.indexOf("//") != -1) { //$NON-NLS-1$
				return label.substring((repository.getRepositoryUrl().indexOf("//") + 2)); //$NON-NLS-1$
			}
			return label;
		}
		return ""; //$NON-NLS-1$
	}

	private String getOwnerText(IRepositoryElement element) {
		if (element instanceof ITask) {
			String owner = ((ITask) element).getOwner();
			if (owner != null) {
				return NLS.bind(Messages.TaskListToolTip_Assigned_to_X, owner);
			}
		}
		return null;
	}

	private Image getOwnerImage(IRepositoryElement element) {
		if (element instanceof ITask) {
			ITask task = (ITask) element;
			AbstractRepositoryConnector connector = TasksUi.getRepositoryConnector(task.getConnectorKind());
			TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(),
					task.getRepositoryUrl());
			if (connector.isOwnedByUser(repository, task)) {
				return CommonImages.getImage(CommonImages.PERSON_ME);
			}
		}
		return null;
	}

	private String getExtendedToolTipText(IRepositoryElement element) {
		if (element instanceof ITask) {
			ITask task = (ITask) element;
			String extendedToolTipInfo = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_TASK_EXTENDED_TOOLTIP);
			if (extendedToolTipInfo != null && extendedToolTipInfo.length() > 0) {
				return extendedToolTipInfo;
			}
		}
		return null;
	}

	private String getActivityText(IRepositoryElement element) {
		if (element instanceof AbstractTask) {
			AbstractTask task = (AbstractTask) element;

			StringBuilder sb = new StringBuilder();

			Date dueDate = task.getDueDate();
			if (dueDate != null) {
				sb.append(NLS.bind(Messages.TaskListToolTip_Due,
						new Object[] { new SimpleDateFormat("E").format(dueDate), //$NON-NLS-1$
								DateFormat.getDateInstance(DateFormat.LONG).format(dueDate),
								DateFormat.getTimeInstance(DateFormat.SHORT).format(dueDate) }));
				sb.append("\n"); //$NON-NLS-1$
			}

			DateRange scheduledDate = task.getScheduledForDate();
			if (scheduledDate != null) {
				sb.append(NLS.bind(Messages.TaskListToolTip_Scheduled, scheduledDate.toString()));
				sb.append("\n"); //$NON-NLS-1$
			}
			long elapsed = TasksUiPlugin.getTaskActivityManager().getElapsedTime(task);
			appendEstimateAndActive(sb, task.getEstimatedTimeHours(), elapsed);
			return sb.toString();
		}
		return null;
	}

	private String getIncomingText(IRepositoryElement element) {
		String text = null;
		if (element instanceof ITask) {
			ITask task = (ITask) element;
			if (task.getSynchronizationState().isIncoming()) {
				text = task.getAttribute(TaskListNotifier.KEY_INCOMING_NOTIFICATION_TEXT);
				if (Strings.isNullOrEmpty(text)) {
					TaskListNotifier notifier = new TaskListNotifier(TasksUiPlugin.getTaskDataManager(),
							TasksUiPlugin.getDefault().getSynchronizationManger());
					text = notifier.computeNotificationText(task);
				}
			}
		}
		return text;
	}

	private ImageDescriptor getIncomingImage() {
		ImageDescriptor incomingImage = CommonImages.OVERLAY_SYNC_INCOMMING;
		if (currentTipElement instanceof ITask) {
			ITask task = (ITask) currentTipElement;
			if (task.getSynchronizationState() == SynchronizationState.INCOMING_NEW) {
				incomingImage = CommonImages.OVERLAY_SYNC_INCOMMING_NEW;
			}
		}
		return incomingImage;
	}

	private String getSynchronizationStateText(IRepositoryElement element) {
		if (element instanceof ITaskContainer) {
			Collection<ITask> tasks = ((ITaskContainer) element).getChildren();
			if (tasks.size() > 0) {
				int incoming = 0;
				int outgoing = 0;
				for (ITask task : tasks) {
					if (task.getSynchronizationState().isIncoming()) {
						incoming++;
					}
					if (task.getSynchronizationState().isOutgoing()) {
						outgoing++;
					}
				}
				return NLS.bind(Messages.TaskListToolTip_Incoming_Outgoing, new Object[] { incoming, outgoing });
			}
		}
		return null;
	}

	private Image getStatusIcon(IRepositoryElement element) {
		if (element instanceof RepositoryQuery) {
			return CommonImages.getImage(TasksUiInternal.getIconFromStatusOfQuery((RepositoryQuery) element));
		}
		return CommonImages.getImage(CommonImages.WARNING);
	}

	private String getStatusText(IRepositoryElement element) {
		IStatus status = null;
		if (element instanceof AbstractTask) {
			AbstractTask task = (AbstractTask) element;
			status = task.getStatus();
		} else if (element instanceof IRepositoryQuery) {
			RepositoryQuery query = (RepositoryQuery) element;
			status = query.getStatus();
		}

		if (status != null) {
			StringBuilder sb = new StringBuilder();
			sb.append(status.getMessage());
			if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
				sb.append(Messages.TaskListToolTip_Please_synchronize_manually_for_full_error_message);
			}
			return sb.toString();
		}

		return null;
	}

	@Override
	public Point getLocation(Point tipSize, Event event) {
		Widget widget = getTipWidget(event);
		if (widget != null) {
			Rectangle bounds = getBounds(widget);
			if (bounds != null) {
				return control.toDisplay(bounds.x + X_SHIFT, bounds.y + bounds.height + Y_SHIFT);
			}
		}
		return super.getLocation(tipSize, event);
	}

	private ProgressData getProgressData(IRepositoryElement element) {
		if (element instanceof ITaskContainer) {
			Object[] children = new Object[0];

			children = ((ITaskContainer) element).getChildren().toArray();

			int total = children.length;
			if (total > 0) {
				int completed = 0;
				for (ITask task : ((ITaskContainer) element).getChildren()) {
					if (task.isCompleted()) {
						completed++;
					}
				}
				String text = NLS.bind(Messages.TaskListToolTip_Total_Complete_Incomplete, new Object[] { //
						total, completed, (total - completed) });
				return new ProgressData(completed, total, text);
			}
		}
		return null;
	}

	private Image getImage(IRepositoryElement element) {
		if (element instanceof IRepositoryQuery) {
			IRepositoryQuery query = (IRepositoryQuery) element;
			TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryUrl());
			if (repository != null) {
				return TasksUiPlugin.getDefault().getBrandManager().getBrandingIcon(repository);
			}
			return TasksUiPlugin.getDefault().getBrandManager().getDefaultBrandingIcon(query.getConnectorKind());
		} else if (element instanceof ITask) {
			ITask task = (ITask) element;
			TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(task.getRepositoryUrl());
			if (repository != null) {
				return TasksUiPlugin.getDefault().getBrandManager().getBrandingIcon(repository);
			}
			return TasksUiPlugin.getDefault().getBrandManager().getDefaultBrandingIcon(task.getConnectorKind());
		} else if (element instanceof ScheduledTaskContainer) {
			return CommonImages.getImage(CommonImages.CALENDAR);
		}
		return null;
	}

	protected Widget getTipWidget(Event event) {
		Point widgetPosition = new Point(event.x, event.y);
		Widget widget = event.widget;
		if (widget instanceof ToolBar) {
			ToolBar w = (ToolBar) widget;
			return w.getItem(widgetPosition);
		}
		if (widget instanceof Table) {
			Table w = (Table) widget;
			return w.getItem(widgetPosition);
		}
		if (widget instanceof Tree) {
			Tree w = (Tree) widget;
			return w.getItem(widgetPosition);
		}

		return widget;
	}

	private Rectangle getBounds(Widget widget) {
		if (widget instanceof ToolItem) {
			ToolItem w = (ToolItem) widget;
			return w.getBounds();
		}
		if (widget instanceof TableItem) {
			TableItem w = (TableItem) widget;
			return w.getBounds();
		}
		if (widget instanceof TreeItem) {
			TreeItem w = (TreeItem) widget;
			return w.getBounds();
		}
		return null;
	}

	@Override
	protected boolean shouldCreateToolTip(Event event) {
		currentTipElement = null;

		if (isTriggeredByMouse() && !enabled) {
			return false;
		}

		if (super.shouldCreateToolTip(event)) {
			Widget tipWidget = getTipWidget(event);
			if (tipWidget != null) {
				Rectangle bounds = getBounds(tipWidget);
				if (tipWidget instanceof ScalingHyperlink) {
					currentTipElement = getTaskListElement(tipWidget);
				} else if (bounds != null && contains(bounds.x, bounds.y)) {
					currentTipElement = getTaskListElement(tipWidget);
				}
			}
		}

		if (currentTipElement == null) {
			hide();
			return false;
		} else {
			return true;
		}
	}

	private boolean contains(int x, int y) {
		if (control instanceof Scrollable) {
			return ((Scrollable) control).getClientArea().contains(x, y);
		} else {
			return control.getBounds().contains(x, y);
		}
	}

	@Override
	protected Composite createToolTipArea(Event event, Composite parent) {
		assert currentTipElement != null;

		Composite composite = createToolTipContentAreaComposite(parent);

		addIconAndLabel(composite, getImage(currentTipElement), getTitleText(currentTipElement), true);

		String detailsText = getDetailsText(currentTipElement);
		if (detailsText != null) {
			addIconAndLabel(composite, null, detailsText);
		}

		String ownerText = getOwnerText(currentTipElement);
		if (ownerText != null) {
			addIconAndLabel(composite, getOwnerImage(currentTipElement), ownerText);
		}

		String extendedText = getExtendedToolTipText(currentTipElement);
		if (extendedText != null) {
			addIconAndLabel(composite, null, extendedText);
		}

		String synchText = getSynchText(currentTipElement);
		if (synchText != null) {
			addIconAndLabel(composite, CommonImages.getImage(TasksUiImages.REPOSITORY_SYNCHRONIZE), synchText);
		}

		String activityText = getActivityText(currentTipElement);
		if (activityText != null) {
			addIconAndLabel(composite, CommonImages.getImage(CommonImages.CALENDAR), activityText);
		}

		String incomingText = getIncomingText(currentTipElement);
		if (!StringUtils.isEmpty(incomingText)) {
			ImageDescriptor incomingImage = getIncomingImage();
			addIconAndLabel(composite, CommonImages.getImage(incomingImage), incomingText);
		}

		String synchronizationStateText = getSynchronizationStateText(currentTipElement);
		if (synchronizationStateText != null) {
			addIconAndLabel(composite, null, synchronizationStateText);
		}

		ProgressData progress = getProgressData(currentTipElement);
		if (progress != null) {
			addIconAndLabel(composite, null, progress.text);

			// label height need to be set to 0 to remove gap below the progress bar
			Label label = new Label(composite, SWT.NONE);
			GridData labelGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
			labelGridData.heightHint = 0;
			label.setLayoutData(labelGridData);

			Composite progressComposite = new Composite(composite, SWT.NONE);
			GridLayout progressLayout = new GridLayout(1, false);
			progressLayout.marginWidth = 0;
			progressLayout.marginHeight = 0;
			progressComposite.setLayout(progressLayout);
			progressComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));

			WorkweekProgressBar taskProgressBar = new WorkweekProgressBar(progressComposite);
			taskProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
			taskProgressBar.reset(progress.completed, progress.total);

			// do we really need custom canvas? code below renders the same
//			IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
//			Color color = themeManager.getCurrentTheme().getColorRegistry().get(
//					TaskListColorsAndFonts.THEME_COLOR_TASK_TODAY_COMPLETED);
//			ProgressBar bar = new ProgressBar(tipShell, SWT.SMOOTH);
//			bar.setForeground(color);
//			bar.setSelection((int) (100d * progress.completed / progress.total));
//			GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
//			gridData.heightHint = 5;
//			bar.setLayoutData(gridData);
		}

		String statusText = getStatusText(currentTipElement);
		if (statusText != null) {
			addIconAndLabel(composite, getStatusIcon(currentTipElement), statusText);
		}

		String helpText = getHelpText(currentTipElement);
		if (helpText != null) {
			addIconAndLabel(composite, CommonImages.getImage(CommonImages.QUESTION), helpText);
		}

		visible = true;

		return composite;
	}

	private String getHelpText(IRepositoryElement element) {
		if (element instanceof TaskCategory || element instanceof IRepositoryQuery) {
			if (AbstractTaskListFilter.hasDescendantIncoming((ITaskContainer) element)) {
				TaskListView taskListView = TaskListView.getFromActivePerspective();
				if (taskListView != null) {

					if (!taskListView.isFocusedMode() && TasksUiPlugin.getDefault()
							.getPreferenceStore()
							.getBoolean(ITasksUiPreferenceConstants.FILTER_COMPLETE_MODE)) {
						Object[] children = ((TaskListContentProvider) taskListView.getViewer().getContentProvider())
								.getChildren(element);
						boolean hasIncoming = false;
						for (Object child : children) {
							if (child instanceof ITask) {
								if (TasksUiInternal.shouldShowIncoming((ITask) child)) {
									hasIncoming = true;
									break;
								}
							}
						}
						if (!hasIncoming) {
							return Messages.TaskListToolTip_Some_incoming_elements_may_be_filtered;
						}
					}
				}
			}
			// if has incoming but no top level children have incoming, suggest incoming tasks may be filtered
		}
		if (element instanceof UncategorizedTaskContainer) {
			return Messages.TaskListToolTip_Automatic_container_for_all_local_tasks;
		} else if (element instanceof UnmatchedTaskContainer) {
			return Messages.TaskListToolTip_Automatic_container_for_repository_tasks;
		}
		return null;
	}

	protected Composite createToolTipContentAreaComposite(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		gridLayout.marginWidth = 5;
		gridLayout.marginHeight = 2;
		composite.setLayout(gridLayout);
		composite.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		return composite;
	}

	private String getSynchText(IRepositoryElement element) {
		if (element instanceof IRepositoryQuery) {
			String syncStamp = ((RepositoryQuery) element).getLastSynchronizedTimeStamp();
			if (syncStamp != null) {
				return NLS.bind(Messages.TaskListToolTip_Synchronized, syncStamp);
			}
		}
		return null;
	}

	private String removeTrailingNewline(String text) {
		if (text.endsWith("\n")) { //$NON-NLS-1$
			return text.substring(0, text.length() - 1);
		}
		return text;
	}

	protected void addIconAndLabel(Composite parent, Image image, String text) {
		addIconAndLabel(parent, image, text, false);
	}

	protected void addIconAndLabel(Composite parent, Image image, String text, boolean title) {
		Label imageLabel = new Label(parent, SWT.NONE);
		imageLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
		imageLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		imageLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING));
		imageLabel.setImage(image);

		Label textLabel = new Label(parent, SWT.WRAP);
		if (title) {
			textLabel.setFont(CommonFonts.BOLD);
		}
		textLabel.setForeground(titleColor);
		textLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		textLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
		text = removeTrailingNewline(text);
		textLabel.setText(LegacyActionTools.escapeMnemonics(text));
		int width = Math.min(textLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, MAX_WIDTH);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).hint(width, SWT.DEFAULT).applyTo(textLabel);
	}

	private static class ProgressData {

		int completed;

		int total;

		String text;

		public ProgressData(int completed, int total, String text) {
			this.completed = completed;
			this.total = total;
			this.text = text;
		}

	}

	public boolean isVisible() {
		return visible;
	}

	public boolean isTriggeredByMouse() {
		return triggeredByMouse;
	}

	@Override
	public void show(Point location) {
		triggeredByMouse = false;
		super.show(location);
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

}
