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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.docmlet.tex.core.TexBuildParticipant;
import org.eclipse.statet.docmlet.tex.core.model.LtxSuModelContainer;
import org.eclipse.statet.docmlet.tex.core.model.TexWorkspaceSourceUnit;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.RProjects;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelIndexUpdate;
import org.eclipse.statet.redocs.tex.r.core.model.LtxRweaveSourceUnit;
import org.eclipse.statet.redocs.tex.r.core.model.TexRweaveModel;


public class LtxRweaveTexBuildParticipant extends TexBuildParticipant {
	
	
	private static final ImList<String> TEX_R_MODEL_TYPES= ImCollections.newList(
			TexRweaveModel.LTX_R_MODEL_TYPE_ID );
	
	
	private RModelIndexUpdate rIndexUpdate;
	
	
	public LtxRweaveTexBuildParticipant() {
	}
	
	
	@Override
	public void init() {
		super.init();
		
		final RProject rProject= RProjects.getRProject(getTexProject().getProject());
		if (rProject != null) {
			setEnabled(true);
			this.rIndexUpdate= new RModelIndexUpdate(rProject, TEX_R_MODEL_TYPES,
					(getBuildType() == IncrementalProjectBuilder.FULL_BUILD) );
		}
	}
	
	
	@Override
	public void clear(final IFile file) throws CoreException {
		file.deleteMarkers("org.eclipse.statet.r.resourceMarkers.Tasks", false, IResource.DEPTH_INFINITE); //$NON-NLS-1$
	}
	
	@Override
	public void ltxUnitUpdated(final TexWorkspaceSourceUnit sourceUnit,
			final IProgressMonitor monitor) throws CoreException {
		if (sourceUnit instanceof LtxRweaveSourceUnit) {
			final LtxRweaveSourceUnit unit= (LtxRweaveSourceUnit) sourceUnit;
			final LtxRweaveSuModelContainer modelContainer= (LtxRweaveSuModelContainer) unit.getAdapter(LtxSuModelContainer.class);
			if (modelContainer != null) {
				this.rIndexUpdate.update(unit,
						RModel.getRModelInfo(modelContainer.getCurrentModel()) );
			}
			else {
				this.rIndexUpdate.remove(unit);
			}
		}
	}
	
	@Override
	public void ltxUnitRemoved(final IFile file,
			final IProgressMonitor monitor) throws CoreException {
		this.rIndexUpdate.remove(file);
	}
	
	@Override
	public void ltxFinished(final IProgressMonitor monitor) throws CoreException {
		this.rIndexUpdate.submit(monitor);
	}
	
}
