/*=============================================================================#
 # Copyright (c) 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.ecommons.text.ui.presentation;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
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.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public class FixTokenScanner implements ITokenScanner {
	
	
	private final TextStyleManager<?> textStyles;
	private final IToken defaultToken;
	
	private ImList<ITypedRegion> styleRegions;
	
	private int documentStartOffset;
	private int documentEndOffset;
	
	private int regionIdx;
	
	private int tokenOffset;
	private int tokenLength;
	
	
	public FixTokenScanner(final TextStyleManager<?> textStyles, final String defaultTokenKey) {
		this.textStyles= textStyles;
		this.defaultToken= textStyles.getToken(defaultTokenKey);
		
		this.styleRegions= ImCollections.emptyList();
	}
	
	
	public void setStyleRegions(final ImList<ITypedRegion> regions) {
		this.styleRegions= regions;
		this.regionIdx= 0;
	}
	
	
	@Override
	public void setRange(final IDocument document, final int offset, final int length) {
		this.documentStartOffset= offset;
		this.documentEndOffset= length;
		
		this.regionIdx= 0;
		this.tokenOffset= offset;
		this.tokenLength= 0;
	}
	
	@Override
	public IToken nextToken() {
		this.tokenOffset+= this.tokenLength;
		
		if (this.tokenOffset == this.documentEndOffset) {
			return Token.EOF;
		}
		
		final ITypedRegion region= nextRegion();
		if (region != null) {
			if (this.tokenOffset >= region.getOffset()) {
				setTokenEndOffset(region.getOffset() + region.getLength());
				return this.textStyles.getToken(region.getType());
			}
			setTokenEndOffset(region.getOffset());
			return this.defaultToken;
		}
		else {
			setTokenEndOffset(Integer.MAX_VALUE);
			return this.defaultToken;
		}
	}
	
	private @Nullable ITypedRegion nextRegion() {
		for (int idx= this.regionIdx; idx < this.styleRegions.size(); idx++) {
			final ITypedRegion region= this.styleRegions.get(idx);
			if (this.tokenOffset < region.getOffset() + region.getLength()) {
				this.regionIdx= idx;
				return region;
			}
		}
		return null;
	}
	
	private void setTokenEndOffset(final int offset) {
		this.tokenLength= Math.min(offset, this.documentEndOffset) - this.tokenOffset;
	}
	
	@Override
	public int getTokenOffset() {
		return this.tokenOffset;
	}
	
	@Override
	public int getTokenLength() {
		return this.tokenLength;
	}
	
	
}
