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

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.Token;

import org.eclipse.statet.ecommons.text.core.input.DocumentParserInput;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.text.ui.settings.TextStyleManager;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;

import org.eclipse.statet.internal.r.ui.RIdentifierGroups;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.r.core.rlang.RTerminal;
import org.eclipse.statet.r.core.rsource.RLexer;


/**
 * Text token scanner for R code.
 * Mainly for R default partitions, but also works for other partitions (without special styles).
 * 
 * Version 2 uses RLexer instead of rules to parse the sources.
 */
public class RDefaultTextStyleScanner extends DocumentParserInput implements ITokenScanner, ISettingsChangedHandler {
	
	
	protected static void putAll(final Map<String, IToken> map, final String[] symbols, final IToken token) {
		for (int i= 0; i < symbols.length; i++) {
			map.put(symbols[i], token);
		}
	}
	
	protected static void putAll(final Map<RTerminal, IToken> map, final RTerminal[] types, final IToken token) {
		for (int i= 0; i < types.length; i++) {
			map.put(types[i], token);
		}
	}
	
	
	private final RLexer lexer;
	private RTerminal lexerToken;
	
	private final EnumMap<RTerminal, IToken> tokens;
	private final IToken defaultToken;
	private final Map<String, IToken> specialSymbols;
	private final TextStyleManager textStyles;
	
	private int currentOffset;
	private int currentLength;
	
	
	public RDefaultTextStyleScanner(final TextStyleManager textStyles) {
		this.lexer= createLexer();
		this.lexer.reset(this);
		this.textStyles= textStyles;
		
		this.defaultToken= getToken(IRTextTokens.SYMBOL_KEY);
		this.tokens= new EnumMap<>(RTerminal.class);
		registerTokens(this.tokens);
//		checkTokenMap();
		this.specialSymbols= new HashMap<>();
		updateSymbols(this.specialSymbols);
	}
	
	
	protected RLexer createLexer() {
		return new RLexer((RLexer.DEFAULT | RLexer.SKIP_WHITESPACE | RLexer.SKIP_LINEBREAK |
				RLexer.ENABLE_QUICK_CHECK ));
	}
	
	protected void checkTokenMap() {
		final RTerminal[] all= RTerminal.values();
		for (final RTerminal t : all) {
			if (this.tokens.get(t) == null) {
				System.out.println("Style Missing for: " + t.name()); //$NON-NLS-1$
			}
		}
	}
	
	
	protected final RLexer getLexer() {
		return this.lexer;
	}
	
	protected final TextStyleManager getTextStyles() {
		return this.textStyles;
	}
	
	@Override
	public void setRange(final IDocument document, final int offset, final int length) {
		reset(document);
		init(offset, offset + length);
		this.lexer.reset(this);
		
		this.currentOffset= offset;
		this.currentLength= 0;
	}
	
	protected void resetSpecialSymbols() {
		this.specialSymbols.clear();
		updateSymbols(this.specialSymbols);
	}
	
	
	@Override
	public IToken nextToken() {
		this.currentOffset+= this.currentLength;
		if (this.lexerToken == null) {
			this.lexerToken= this.lexer.next();
		}
		this.currentLength= this.lexer.getOffset() - this.currentOffset;
		if (this.currentLength != 0) {
			return this.defaultToken;
		}
		this.currentLength= this.lexer.getLength();
		return getTokenFromScannerToken();
	}
	
	protected IToken getTokenFromScannerToken() {
		IToken token;
		if (this.lexerToken == RTerminal.SYMBOL) {
			final String text= this.lexer.getText();
			if (text != null) {
				token= this.specialSymbols.get(text);
				if (token != null) {
					this.lexerToken= null;
					return token;
				}
			}
			this.lexerToken= null;
			return this.defaultToken;
		}
		token= this.tokens.get(this.lexerToken);
		this.lexerToken= null;
		return token;
	}
	
	@Override
	public int getTokenOffset() {
		return this.currentOffset;
	}
	
	@Override
	public int getTokenLength() {
		return this.currentLength;
	}
	
	
	protected IToken getToken(final String key) {
		return this.textStyles.getToken(key);
	}
	
	@Override
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		if (groupIds.contains(RIdentifierGroups.GROUP_ID)) {
			resetSpecialSymbols();
			options.put(ITextPresentationConstants.SETTINGSCHANGE_AFFECTSPRESENTATION_KEY, Boolean.TRUE);
		}
	}
	
	
	//-- Concrete associations
	
	protected void registerTokens(final EnumMap<RTerminal,IToken> map) {
		map.put(RTerminal.EOF, Token.EOF);
		
		putAll(map, IRTextTokens.FLOWCONTROL, getToken(IRTextTokens.FLOWCONTROL_KEY));
		putAll(map, IRTextTokens.GROUPING, getToken(IRTextTokens.GROUPING_KEY));
		putAll(map, IRTextTokens.SEPARATOR, getToken(IRTextTokens.SEPARATOR_KEY));
		putAll(map, IRTextTokens.ASSIGN, getToken(IRTextTokens.ASSIGN_KEY));
		putAll(map, IRTextTokens.ASSIGN_SUB_EQUAL, getToken(IRTextTokens.ASSIGN_SUB_EQUAL_KEY));
		putAll(map, IRTextTokens.OP, getToken(IRTextTokens.OP_KEY));
		putAll(map, IRTextTokens.OP_SUB_LOGICAL, getToken(IRTextTokens.OP_SUB_LOGICAL_KEY));
		putAll(map, IRTextTokens.OP_SUB_RELATIONAL, getToken(IRTextTokens.OP_SUB_RELATIONAL_KEY));
		putAll(map, IRTextTokens.SUBACCESS, getToken(IRTextTokens.SUBACCESS_KEY));
		putAll(map, IRTextTokens.NSGET, getToken(IRTextTokens.SUBACCESS_KEY));
		
		putAll(map, IRTextTokens.SPECIALCONST, getToken(IRTextTokens.SPECIALCONST_KEY));
		putAll(map, IRTextTokens.LOGICALCONST, getToken(IRTextTokens.LOGICALCONST_KEY));
		putAll(map, IRTextTokens.SYMBOL, getToken(IRTextTokens.SYMBOL_KEY));
		
		putAll(map, IRTextTokens.NUM, getToken(IRTextTokens.NUM_KEY));
		putAll(map, IRTextTokens.NUM_SUB_INT, getToken(IRTextTokens.NUM_SUB_INT_KEY));
		putAll(map, IRTextTokens.NUM_SUB_CPLX, getToken(IRTextTokens.NUM_SUB_CPLX_KEY));
		putAll(map, IRTextTokens.UNDEFINED, getToken(IRTextTokens.UNDEFINED_KEY));
		
		// usually not in default partition
		putAll(map, IRTextTokens.STRING, getToken(IRTextTokens.STRING_KEY));
		map.put(RTerminal.SYMBOL_G, getToken(IRTextTokens.STRING_KEY));
		map.put(RTerminal.SPECIAL, getToken(IRTextTokens.OP_KEY));
		putAll(map, IRTextTokens.COMMENT, getToken(IRTextTokens.COMMENT_KEY));
	}
	
	protected void updateSymbols(final Map<String, IToken> map) {
		final RIdentifierGroups groups= RUIPlugin.getInstance().getRIdentifierGroups();
		groups.getReadLock().lock();
		try {
			putAll(map, groups.getAssignmentIdentifiers(),
					getToken(IRTextTokens.SYMBOL_SUB_ASSIGN_KEY));
			putAll(map, groups.getLogicalIdentifiers(),
					getToken(IRTextTokens.SYMBOL_SUB_LOGICAL_KEY));
			putAll(map, groups.getFlowcontrolIdentifiers(),
					getToken(IRTextTokens.SYMBOL_SUB_FLOWCONTROL_KEY));
			putAll(map, groups.getCustom1Identifiers(),
					getToken(IRTextTokens.SYMBOL_SUB_CUSTOM1_KEY));
			putAll(map, groups.getCustom2Identifiers(),
					getToken(IRTextTokens.SYMBOL_SUB_CUSTOM2_KEY));
		}
		finally {
			groups.getReadLock().unlock();
		}
	}
	
}
