/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ui.IPreferenceIds;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.ui.ISharedImages;
import org.eclipse.team.ui.synchronize.ISynchronizeModelElement;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * A label provider that decorates viewers showing
 * {@link ISynchronizeModelElement}.
 *
 * @since 3.0
 */
public class SynchronizeModelElementLabelProvider extends LabelProvider implements IColorProvider, IFontProvider {

	// Cache for folder images that have been overlayed with conflict icon
	private Map<ImageDescriptor, Image> fgImageCache;

	// Contains direction images
	CompareConfiguration compareConfig = new CompareConfiguration();

	// Used as the base label provider for retreiving image and text from
	// the workbench adapter.
	private WorkbenchLabelProvider workbenchLabelProvider = new WorkbenchLabelProvider();

	// Font used to display busy elements
	private Font busyFont;

	public SynchronizeModelElementLabelProvider() {
	}

	@Override
	public Color getForeground(Object element) {
		return null;
	}

	@Override
	public Color getBackground(Object element) {
		return null;
	}

	@Override
	public Font getFont(Object element) {
		if (element instanceof ISynchronizeModelElement) {
			ISynchronizeModelElement node = (ISynchronizeModelElement)element;
			if(node.getProperty(ISynchronizeModelElement.BUSY_PROPERTY)) {
				if (busyFont == null) {
					Font defaultFont = JFaceResources.getDefaultFont();
					FontData[] data = defaultFont.getFontData();
					for (int i = 0; i < data.length; i++) {
						data[i].setStyle(SWT.ITALIC);
					}
					busyFont = new Font(TeamUIPlugin.getStandardDisplay(), data);
				}
				return busyFont;
			}
		}
		return null;
	}

	@Override
	public Image getImage(Object element) {
		Image base = workbenchLabelProvider.getImage(element);
		if (base != null) {
			if (element instanceof ISynchronizeModelElement) {
				ISynchronizeModelElement syncNode = (ISynchronizeModelElement) element;
				int kind = syncNode.getKind();
				Image decoratedImage;
				decoratedImage = getCompareImage(base, kind);
				// The reason we still overlay the compare image is to
				// ensure that the image width for all images shown in the viewer
				// are consistent.
				return propagateConflicts(decoratedImage, syncNode);
			}
		}
		return base;
	}

	@Override
	public String getText(Object element) {
		String base = workbenchLabelProvider.getText(element);
		if (element instanceof DiffNode) {
			if (TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL)) {
				// if the folder is already conflicting then don't bother
				// propagating the conflict
				int kind = ((DiffNode) element).getKind();
				if (kind != SyncInfo.IN_SYNC) {
					String syncKindString = SyncInfo.kindToString(kind);
					return NLS.bind(TeamUIMessages.TeamSubscriberSyncPage_labelWithSyncKind, new String[] { base, syncKindString }); //
				}
			}
		}
		return base;
	}

	protected Image getCompareImage(Image base, int kind) {
		switch (kind & SyncInfo.DIRECTION_MASK) {
			case SyncInfo.OUTGOING :
				kind = (kind & ~SyncInfo.OUTGOING) | SyncInfo.INCOMING;
				break;
			case SyncInfo.INCOMING :
				kind = (kind & ~SyncInfo.INCOMING) | SyncInfo.OUTGOING;
				break;
		}
		return compareConfig.getImage(base, kind);
	}

	private Image propagateConflicts(Image base, ISynchronizeModelElement element) {

		ImageDescriptor[] overlayImages = new ImageDescriptor[4];
		boolean hasOverlay = false;

		// Decorate with the busy indicator
		if (element.getProperty(ISynchronizeModelElement.BUSY_PROPERTY)) {
			overlayImages[IDecoration.TOP_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_HOURGLASS_OVR);
			hasOverlay = true;
		}
		// Decorate with propagated conflicts and problem markers
		int kind = element.getKind();
		if ((kind & SyncInfo.DIRECTION_MASK) != SyncInfo.CONFLICTING) {
			// if the folder is already conflicting then don't bother propagating
			// the conflict
			if (hasDecendantConflicts(element)) {
				overlayImages[IDecoration.BOTTOM_RIGHT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR);
				hasOverlay = true;
			}
		}
		if (hasErrorMarker(element)) {
			overlayImages[IDecoration.BOTTOM_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_ERROR_OVR);
			hasOverlay = true;
		} else if (hasWarningMarker(element)) {
			overlayImages[IDecoration.BOTTOM_LEFT] = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_WARNING_OVR);
			hasOverlay = true;
		}
		if (hasOverlay) {
			ImageDescriptor overlay = new DecorationOverlayIcon(base, overlayImages, new Point(base.getBounds().width, base.getBounds().height));
			if (fgImageCache == null) {
				fgImageCache = new HashMap<>(10);
			}
			Image conflictDecoratedImage = fgImageCache.get(overlay);
			if (conflictDecoratedImage == null) {
				conflictDecoratedImage = overlay.createImage();
				fgImageCache.put(overlay, conflictDecoratedImage);
			}
			return conflictDecoratedImage;
		}
		return base;
	}

	/**
	 * Return whether this diff node has descendant conflicts in the view in
	 * which it appears.
	 * @return whether the node has descendant conflicts
	 */
	private boolean hasDecendantConflicts(ISynchronizeModelElement node) {
		return node.getProperty(ISynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY);
	}

	/**
	 * Return whether this diff node has descendant conflicts in the view in which it appears.
	 * @return whether the node has descendant conflicts
	 */
	private boolean hasErrorMarker(ISynchronizeModelElement node) {
		return node.getProperty(ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY);
	}

	/**
	 * Return whether this diff node has descendant conflicts in the view in which it appears.
	 * @return whether the node has descendant conflicts
	 */
	private boolean hasWarningMarker(ISynchronizeModelElement node) {
		return node.getProperty(ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY);
	}

	@Override
	public void dispose() {
		workbenchLabelProvider.dispose();
		if(busyFont != null) {
			busyFont.dispose();
		}
		compareConfig.dispose();
		if (fgImageCache != null) {
			Iterator it = fgImageCache.values().iterator();
			while (it.hasNext()) {
				Image element = (Image) it.next();
				element.dispose();
			}
		}
	}
}
