/*=============================================================================#
 # 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.r.core.source;

import static org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartitionNode.END_UNCLOSED;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.ICharacterScanner;

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

import org.eclipse.statet.r.core.source.RPartitionNodeScanner;
import org.eclipse.statet.r.core.source.RPartitionNodeType;


/**
 * Abstract partition scanner for R chunks e.g. in Sweave files.
 */
public abstract class AbstractRChunkPartitionNodeScanner extends RPartitionNodeScanner {
	
	
	private static final int S_CHUNKCONTROL= 8;
	private static final int S_CHUNKCOMMENT= 9;
	
	public static final RPartitionNodeType R_CHUNK_BASE_TYPE= new RPartitionNodeType() {
		
		@Override
		public String getPartitionType() {
			return RweaveDocumentConstants.RCHUNK_BASE_CONTENT_TYPE;
		}
		
		@Override
		public byte getScannerState() {
			return S_CHUNKCONTROL;
		}
		
	};
	
	public static final RPartitionNodeType R_CHUNK_CONTROL_TYPE= new RPartitionNodeType() {
		
		@Override
		public String getPartitionType() {
			return RweaveDocumentConstants.RCHUNK_CONTROL_CONTENT_TYPE;
		}
		
		@Override
		public byte getScannerState() {
			return S_CHUNKCONTROL;
		}
		
		@Override
		public boolean prefereAtBegin(final TreePartitionNode node, final IDocument document) {
			return true;
		}
		
		@Override
		public boolean prefereAtEnd(final TreePartitionNode node, final IDocument document) {
			return true;
		}
		
	};
	
	public static final RPartitionNodeType R_CHUNK_COMMENT_TYPE= new RPartitionNodeType.Comment() {
		
		@Override
		public String getPartitionType() {
			return RweaveDocumentConstants.RCHUNK_COMMENT_CONTENT_TYPE;
		}
		
		@Override
		public byte getScannerState() {
			return S_CHUNKCOMMENT;
		}
		
		@Override
		public boolean prefereAtBegin(final TreePartitionNode node, final IDocument document) {
			return true;
		}
		
	};
	
	
	protected static final byte NONE= 0;
	protected static final byte START_LINE= 1;
	protected static final byte REF_LINE= 2;
	protected static final byte STOP_LINE= 3;
	
	
	private TreePartitionNode chunkNode;
	
	private byte chunkLine;
	
	
	public AbstractRChunkPartitionNodeScanner() {
	}
	
	
	@Override
	protected void init() {
		this.chunkNode= null;
		
		super.init();
		
		final TreePartitionNode rootNode= getRootNode();
		if (rootNode.getType().getPartitionType() == RweaveDocumentConstants.RCHUNK_BASE_CONTENT_TYPE) {
			this.chunkNode= rootNode;
		}
		this.chunkLine= NONE;
	}
	
	protected final TreePartitionNode getChunkNode() {
		return this.chunkNode;
	}
	
	protected final byte getChunkLine() {
		return this.chunkLine;
	}
	
	protected final void exitToChunkBase(final byte chunkLine, final int offset) {
		exitNodesTo(this.chunkNode, offset, END_UNCLOSED);
		this.chunkLine= chunkLine;
	}
	
	@Override
	protected abstract void handleNewLine(final RPartitionNodeType type);
	
	@Override
	protected void handleEOF(final RPartitionNodeType type) {
		final TreePartitionNode rootNode= getRootNode();
		final int offset= this.reader.getOffset();
		exitNodesTo(rootNode, offset, END_UNCLOSED);
		getScan().expand(rootNode, offset, (this.chunkLine == STOP_LINE) ? 0 : END_UNCLOSED, true);
	}
	
	@Override
	protected void processExt(final RPartitionNodeType type) {
		if (this.chunkNode != null) {
			switch (type.getScannerState()) {
			case S_CHUNKCONTROL:
				processChunkControlOpen(this.chunkLine);
				return;
			case S_CHUNKCOMMENT:
				processChunkComment();
				return;
			default:
				break;
			}
		}
		super.processExt(type);
	}
	
	protected abstract void processChunkControlOpen(byte chunkLink);
	
	protected void processChunkComment() {
		LOOP: while (true) {
			switch (this.reader.read()) {
			case ICharacterScanner.EOF:
				this.last= LAST_EOF;
				return;
			case '\r':
				this.reader.read('\n');
				//$FALL-THROUGH$
			case '\n':
				exitNode(this.reader.getOffset(), 0);
				if (this.chunkLine == STOP_LINE) {
					this.last= LAST_EOF;
					return;
				}
				else {
					addNode(getDefaultRootType(), this.reader.getOffset());
					this.last= LAST_NEWLINE;
					return;
				}
			default:
				continue LOOP;
			}
		}
	}
	
}
