/*=============================================================================#
 # Copyright (c) 2005, 2020 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.internal.r.ui.editors;

import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.source.IAnnotationModel;

import org.eclipse.statet.jcommons.lang.Disposable;

import org.eclipse.statet.ecommons.preferences.PreferencesUtil;
import org.eclipse.statet.ecommons.preferences.SettingsChangeNotifier;
import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;

import org.eclipse.statet.ltk.core.LTK;
import org.eclipse.statet.ltk.issues.core.Problem;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.sourceediting.SourceAnnotationModel;
import org.eclipse.statet.ltk.ui.sourceediting.SourceDocumentProvider;
import org.eclipse.statet.ltk.ui.sourceediting.SourceProblemAnnotation;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.source.RDocumentSetupParticipant;
import org.eclipse.statet.r.ui.editors.REditorBuild;


public class RDocumentProvider extends SourceDocumentProvider<IRSourceUnit> implements Disposable {
	
	
	private class ThisAnnotationModel extends SourceAnnotationModel {
		
		public ThisAnnotationModel(final IResource resource) {
			super(resource);
		}
		
		@Override
		protected boolean isHandlingTemporaryProblems() {
			return fHandleTemporaryProblems;
		}
		
		@Override
		protected SourceProblemAnnotation createAnnotation(final Problem problem) {
			if (problem.getCategoryId() == RModel.R_TYPE_ID) {
				switch (problem.getSeverity()) {
				case Problem.SEVERITY_ERROR:
					return new SourceProblemAnnotation(REditorBuild.ERROR_ANNOTATION_TYPE, problem,
							SourceProblemAnnotation.ERROR_CONFIG );
				case Problem.SEVERITY_WARNING:
					return new SourceProblemAnnotation(REditorBuild.WARNING_ANNOTATION_TYPE, problem,
							SourceProblemAnnotation.WARNING_CONFIG );
				default:
					return new SourceProblemAnnotation(REditorBuild.INFO_ANNOTATION_TYPE, problem,
							SourceProblemAnnotation.INFO_CONFIG );
				}
			}
			return null;
		}
		
	}
	
	
	private SettingsChangeNotifier.ChangeListener fEditorPrefListener;
	
	private boolean fHandleTemporaryProblems;
	
	
	public RDocumentProvider() {
		super(RModel.R_TYPE_ID, new RDocumentSetupParticipant());
		
		fEditorPrefListener = new SettingsChangeNotifier.ChangeListener() {
			@Override
			public void settingsChanged(final Set<String> groupIds) {
				if (groupIds.contains(REditorBuild.GROUP_ID)) {
					updateEditorPrefs();
				}
			}
		};
		PreferencesUtil.getSettingsChangeNotifier().addChangeListener(fEditorPrefListener);
		final PreferenceAccess access = PreferenceUtils.getInstancePrefs();
		fHandleTemporaryProblems = access.getPreferenceValue(REditorBuild.PROBLEMCHECKING_ENABLED_PREF);
	}
	
	
	@Override
	public void dispose() {
		if (fEditorPrefListener != null) {
			PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(fEditorPrefListener);
			fEditorPrefListener = null;
		}
	}
	
	private void updateEditorPrefs() {
		final PreferenceAccess access = PreferenceUtils.getInstancePrefs();
		final boolean newHandleTemporaryProblems = access.getPreferenceValue(REditorBuild.PROBLEMCHECKING_ENABLED_PREF);
		if (fHandleTemporaryProblems != newHandleTemporaryProblems) {
			fHandleTemporaryProblems = newHandleTemporaryProblems;
			if (fHandleTemporaryProblems) {
				RModel.getRModelManager().refresh(LTK.EDITOR_CONTEXT);
			}
			else {
				final List<? extends ISourceUnit> sus = LTK.getSourceUnitManager().getOpenSourceUnits(
						RModel.R_TYPE_ID, LTK.EDITOR_CONTEXT );
				for (final ISourceUnit su : sus) {
					final IAnnotationModel model = getAnnotationModel(su);
					if (model instanceof ThisAnnotationModel) {
						((ThisAnnotationModel) model).clearProblems(null);
					}
				}
			}
		}
	}
	
	@Override
	protected IAnnotationModel createAnnotationModel(final IFile file) {
		return new ThisAnnotationModel(file);
	}
	
}
