/*=============================================================================#
 # Copyright (c) 2007, 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.redocs.tex.r.ui.sourceediting;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.filebuffers.IDocumentSetupParticipant;

import org.eclipse.statet.base.core.preferences.TaskTagsPreferences;
import org.eclipse.statet.docmlet.tex.core.TexCodeStyleSettings;
import org.eclipse.statet.docmlet.tex.core.TexCoreAccess;
import org.eclipse.statet.docmlet.tex.core.util.TexCoreAccessWrapper;
import org.eclipse.statet.internal.r.ui.RUIPreferenceInitializer;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditorViewerConfigurator;
import org.eclipse.statet.r.core.RCodeStyleSettings;
import org.eclipse.statet.r.core.RCoreAccess;
import org.eclipse.statet.r.core.util.RCoreAccessWrapper;
import org.eclipse.statet.redocs.tex.r.core.source.LtxRweaveDocumentSetupParticipant;


/**
 * Configurator for Sweave (LaTeX+R) code source viewers.
 */
public class LtxRweaveSourceViewerConfigurator extends SourceEditorViewerConfigurator {
	
	
	private static final Set<String> RESET_GROUP_IDS= new HashSet<>(Arrays.asList(new String[] {
			TexCodeStyleSettings.INDENT_GROUP_ID,
			RCodeStyleSettings.INDENT_GROUP_ID,
			TaskTagsPreferences.GROUP_ID,
	}));
	
	
	private final TexCoreAccessWrapper docCoreAccess;
	private final RCoreAccessWrapper rCoreAccess;
	
	
	public LtxRweaveSourceViewerConfigurator(
			final TexCoreAccess texCoreAccess, final RCoreAccess rCoreAccess,
			final LtxRweaveSourceViewerConfiguration config) {
		super(config);
		
		this.docCoreAccess= new TexCoreAccessWrapper(texCoreAccess) {
			private final TexCodeStyleSettings codeStyle= new TexCodeStyleSettings(1);
			@Override
			public TexCodeStyleSettings getTexCodeStyle() {
				return this.codeStyle;
			}
		};
		this.rCoreAccess= new RCoreAccessWrapper(rCoreAccess) {
			private final RCodeStyleSettings codeStyle= new RCodeStyleSettings(1);
			@Override
			public RCodeStyleSettings getRCodeStyle() {
				return this.codeStyle;
			}
		};
		config.setCoreAccess(this.docCoreAccess, this.rCoreAccess);
		
		this.docCoreAccess.getTexCodeStyle().load(
				this.docCoreAccess.getParent().getTexCodeStyle() );
		this.docCoreAccess.getTexCodeStyle().resetDirty();
		this.docCoreAccess.getTexCodeStyle().addPropertyChangeListener(this);
		
		this.rCoreAccess.getRCodeStyle().load(
				this.rCoreAccess.getParent().getRCodeStyle() );
		this.rCoreAccess.getRCodeStyle().resetDirty();
		this.rCoreAccess.getRCodeStyle().addPropertyChangeListener(this);
	}
	
	
	public final TexCoreAccess getTexCoreAccess() {
		return this.docCoreAccess;
	}
	
	public final RCoreAccess getRCoreAccess() {
		return this.rCoreAccess;
	}
	
	@Override
	public IDocumentSetupParticipant getDocumentSetupParticipant() {
		return new LtxRweaveDocumentSetupParticipant();
	}
	
	@Override
	protected Set<String> getResetGroupIds() {
		return RESET_GROUP_IDS;
	}
	
	
	public void setSource(final TexCoreAccess texCoreAccess, final RCoreAccess rCoreAccess) {
		boolean changed= false;
		if (texCoreAccess != null) {
			changed|= this.docCoreAccess.setParent(texCoreAccess);
		}
		if (rCoreAccess != null) {
			changed|= this.rCoreAccess.setParent(rCoreAccess);
		}
		if (changed) {
			handleSettingsChanged(null, null);
		}
	}
	
	
	@Override
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		super.handleSettingsChanged(groupIds, options);
		
		this.docCoreAccess.getTexCodeStyle().resetDirty();
		this.rCoreAccess.getRCodeStyle().resetDirty();
	}
	
	@Override
	protected void checkSettingsChanges(final Set<String> groupIds, final Map<String, Object> options) {
		super.checkSettingsChanges(groupIds, options);
		
		if (groupIds.contains(TexCodeStyleSettings.INDENT_GROUP_ID)) {
			this.docCoreAccess.getTexCodeStyle().load(
					this.docCoreAccess.getParent().getTexCodeStyle() );
		}
		if (groupIds.contains(RCodeStyleSettings.INDENT_GROUP_ID)
				|| groupIds.contains(RCodeStyleSettings.WS_GROUP_ID)) {
			this.rCoreAccess.getRCodeStyle().load(
					this.rCoreAccess.getParent().getRCodeStyle() );
		}
		if (groupIds.contains(TexRweaveEditingOptions.LTX_EDITOR_NODE)) {
			this.updateCompleteConfig= true;
		}
		if (groupIds.contains(RUIPreferenceInitializer.REDITOR_HOVER_GROUP_ID)) {
			this.updateInfoHovers= true;
		}
	}
	
}
