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

import static org.eclipse.statet.redocs.r.core.source.AbstractRChunkPartitionNodeScanner.R_CHUNK_BASE_TYPE;

import org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartitionNode;
import org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartitionNodeType;

import org.eclipse.statet.docmlet.wikitext.core.markup.WikitextMarkupLanguage;
import org.eclipse.statet.docmlet.wikitext.core.source.EmbeddingAttributes;
import org.eclipse.statet.docmlet.wikitext.core.source.extdoc.WikidocPartitionNodeScanner;
import org.eclipse.statet.r.core.source.RPartitionNodeType;
import org.eclipse.statet.redocs.r.core.source.AbstractRChunkPartitionNodeScanner;


public class WikidocRweavePartitionNodeScanner extends WikidocPartitionNodeScanner {
	
	
	private AbstractRChunkPartitionNodeScanner rScanner;
	
	
	public WikidocRweavePartitionNodeScanner(final WikitextMarkupLanguage markupLanguage) {
		super(markupLanguage);
	}
	
	public WikidocRweavePartitionNodeScanner(final WikitextMarkupLanguage markupLanguage,
			final int markupLanguageMode) {
		super(markupLanguage, markupLanguageMode);
	}
	
	
	@Override
	protected void init() {
		{	final WikitextMarkupLanguage markupLanguage= getMarkupLanguage();
			if (markupLanguage instanceof RweaveMarkupLanguage) {
				final RweaveMarkupLanguage rweaveLanguage= (RweaveMarkupLanguage) markupLanguage;
				
				this.rScanner= rweaveLanguage.getRChunkPartitionScanner();
			}
			else {
				throw new IllegalArgumentException("markupLanguage"); //$NON-NLS-1$
			}
		}
		
		final TreePartitionNode beginNode= getScan().getBeginNode();
		if (beginNode.getType() instanceof RPartitionNodeType) {
			assert (false);
//			this.rBeginNode= beginNode;
//			while (beginNode.getParent().getType() instanceof RPartitionNodeType) {
//				beginNode= beginNode.getParent();
//			}
//			// !(beginNode.getParent().getType() instanceof RPartitionNodeType)
//			final RPartitionNodeType rType= (RPartitionNodeType) beginNode.getType();
//			if (rType == WikitextRChunkPartitionNodeScanner.R_CHUNK_CONTROL_TYPE) {
//				initNode(beginNode, RCHUNK_WIKITEXT_TYPE);
//			}
//			else {
//				initNode(beginNode, RINLINE_WIKITEXT_TYPE);
//			}
//			return;
		}
		super.init();
	}
	
	
	@Override
	protected void beginEmbeddingBlock(final BlockType type, final Embedding embedding) {
		if (type == BlockType.CODE
				&& embedding.getForeignType() == RweaveMarkupLanguage.EMBEDDED_R) {
			addNode(R_CHUNK_BASE_TYPE, getEventBeginOffset());
			embedding.init(getNode());
			return;
		}
		super.beginEmbeddingBlock(type, embedding);
	}
	
	@Override
	protected void endEmbeddingBlock(final TreePartitionNodeType type, final Embedding embedding) {
		if (type instanceof RPartitionNodeType) {
//			embedded.setContentEndOffset(getScan().getDocument().getLength());
			embedding.executeForeignScanner(this.rScanner);
			exitNode(getEventEndOffset(), 0);
			return;
		}
		super.endEmbeddingBlock(type, embedding);
	}
	
	@Override
	protected void beginEmbeddingSpan(final SpanType type, final Embedding embedding) {
		if (type == SpanType.CODE
				&& embedding.getForeignType() == RweaveMarkupLanguage.EMBEDDED_R) {
			final EmbeddingAttributes attributes= embedding.getAttributes();
			addNode(this.rScanner.getDefaultRootType(),
					getStartOffset() + attributes.getContentRegion().getStartOffset() );
			embedding.init(getNode());
			return;
		}
		super.beginEmbeddingSpan(type, embedding);
	}
	
	@Override
	protected void endEmbeddingSpan(final TreePartitionNodeType type, final Embedding embedding) {
		if (type instanceof RPartitionNodeType) {
			if (embedding.getContentEndOffset() < 0) {
				embedding.setContentEndOffset(getEventEndOffset() - 1);
			}
			
			exitNode(embedding.getContentEndOffset(), 0);
			
			if (embedding.getNode().getLength() > 0) {
				embedding.executeForeignScanner(this.rScanner);
			}
			return;
		}
		super.endEmbeddingSpan(type, embedding);
	}
	
}
