/*=============================================================================#
 # Copyright (c) 2008, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import org.eclipse.jface.text.quickassist.IQuickFixableAnnotation;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationAccessExtension;
import org.eclipse.jface.text.source.IAnnotationPresentation;
import org.eclipse.jface.text.source.ImageUtilities;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ltk.issues.core.Problem;


/**
 * Annotation representing an {@link Problem}.
 */
@NonNullByDefault
public class SourceProblemAnnotation extends Annotation
		implements IAnnotationPresentation, IQuickFixableAnnotation {
	
	public static final String TASK_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.task"; //$NON-NLS-1$
	public static final String SPELLING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.spelling"; //$NON-NLS-1$
	
	
	public static class PresentationConfig {
		
		private final int level;
		
		private @Nullable String imageKey;
		private @Nullable Image image;
		
		
		private PresentationConfig(final String referenceType, final int levelDiff) {
			final AnnotationPreference preference= EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(referenceType);
			
			if (levelDiff != Integer.MIN_VALUE) {
				this.level= ((preference != null) ?
								preference.getPresentationLayer() :
								IAnnotationAccessExtension.DEFAULT_LAYER ) +
						levelDiff;
			}
			else {
				this.level= 0;
			}
			
			if (preference != null) {
				final String symbolicImageName= preference.getSymbolicImageName();
				if (symbolicImageName != null) {
					this.imageKey= DefaultMarkerAnnotationAccess.getSharedImageName(preference.getSymbolicImageName());
				}
			}
		}
		
		public final int getLevel() {
			return this.level;
		}
		
		public final @Nullable Image getImage() {
			Image image= this.image;
			final String key;
			if (image == null && (key= this.imageKey) != null) {
				image= PlatformUI.getWorkbench().getSharedImages().getImage(key);
				this.image= image;
			}
			return image;
		}
		
	}
	
	
	public static final PresentationConfig ERROR_CONFIG= new PresentationConfig("org.eclipse.ui.workbench.texteditor.error", +1); //$NON-NLS-1$
	public static final PresentationConfig WARNING_CONFIG= new PresentationConfig("org.eclipse.ui.workbench.texteditor.warning", +1); //$NON-NLS-1$
	public static final PresentationConfig INFO_CONFIG= new PresentationConfig("org.eclipse.ui.workbench.texteditor.info", +1); //$NON-NLS-1$
	
	
	private final Problem problem;
	
	private boolean isQuickFixable= false;
	private boolean isQuickFixableStateSet= false;
	
	private final PresentationConfig config;
	
	
	public SourceProblemAnnotation(final String type, final Problem problem, final PresentationConfig config) {
		super(type, false, null);
		this.problem= problem;
		this.config= config;
	}
	
	
	@Override
	public String getText() {
		return this.problem.getMessage();
	}
	
	public Problem getProblem() {
		return this.problem;
	}
	
	
	@Override
	public int getLayer() {
		return this.config.getLevel();
	}
	
	@Override
	public void paint(final GC gc, final Canvas canvas, final Rectangle bounds) {
		final Image image= this.config.getImage();
		if (image != null) {
			ImageUtilities.drawImage(image, gc, canvas, bounds, SWT.CENTER, SWT.TOP);
		}
	}
	
	
	@Override
	public void setQuickFixable(final boolean state) {
		this.isQuickFixable= state;
		this.isQuickFixableStateSet= true;
	}
	
	@Override
	public boolean isQuickFixableStateSet() {
		return this.isQuickFixableStateSet;
	}
	
	@Override
	public boolean isQuickFixable() {
		return this.isQuickFixable;
	}
	
}
