/*=============================================================================#
 # 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.ecommons.text;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;

import org.eclipse.statet.ecommons.text.core.PartitionConstraint;


/**
 * Text utilities, in addition to {@link TextUtilities} of JFace.
 */
public class TextUtil {
	
	public static final Pattern LINE_DELIMITER_PATTERN= Pattern.compile("\\r[\\n]?|\\n"); //$NON-NLS-1$
	
	private static final IScopeContext PLATFORM_SCOPE= InstanceScope.INSTANCE;
	
	
	private static class PositionComparator implements Comparator<Position> {
		
		@Override
		public int compare(final Position o1, final Position o2) {
			final int diff= o1.offset - o2.offset;
			if (diff != 0) {
				return diff;
			}
			return o1.length - o2.length;
		}
		
	}
	
	public static final Comparator<Position> POSITION_COMPARATOR= new PositionComparator();
	
	
	/**
	 * Returns the default line delimiter of the Eclipse platform (workbench)
	 * 
	 * @return the line delimiter string
	 */
	public static final String getPlatformLineDelimiter() {
		final String lineDelimiter= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null,
				new IScopeContext[] { PLATFORM_SCOPE });
		if (lineDelimiter != null) {
			return lineDelimiter;
		}
		return System.getProperty("line.separator"); //$NON-NLS-1$
	}
	
	/**
	 * Returns the default line delimiter for the specified project
	 * 
	 * If it cannot find a project specific setting, it returns the
	 * {@link #getPlatformLineDelimiter()}
	 * 
	 * @param project the project handle, may be <code>null</code>
	 * @return the line delimiter string
	 */
	public static String getLineDelimiter(final IProject project) {
		if (project != null) {
			final String lineSeparator= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null,
					new IScopeContext[] { new ProjectScope(project.getProject()), PLATFORM_SCOPE });
			if (lineSeparator != null) {
				return lineSeparator;
			}
		}
		return getPlatformLineDelimiter();
	}
	
	
	/**
	 * Return the length of the overlapping length of two regions.
	 * If they don't overlap, it return the negative distance of the regions.
	 */
	public static final int overlaps(final int reg1Start, final int reg1End, final int reg2Start, final int reg2End) {
		if (reg1Start <= reg2Start) {
			if (reg2End < reg1End) {
				return reg2End-reg2Start;
			}
			return reg1End-reg2Start;
		}
		else {
			if (reg1End < reg2End) {
				return reg1End-reg1Start;
			}
			return reg2End-reg1Start;
		}
	}
	
	public static ArrayList<String> toLines(final String text) {
		final ArrayList<String> lines= new ArrayList<>(2 + text.length() / 30);
		TextUtil.addLines(text, lines);
		return lines;
	}
	
	/**
	 * Adds text of lines of a string without its line delimiters to the list.
	 * 
	 * @param text the text
	 * @param lines list the lines are added to
	 */
	public static void addLines(final String text, final List<String> lines) {
		final int n= text.length();
		int i= 0;
		int lineStart= 0;
		while (i < n) {
			switch (text.charAt(i)) {
			case '\r':
				lines.add(text.substring(lineStart, i));
				i++;
				if (i < n && text.charAt(i) == '\n') {
					i++;
				}
				lineStart= i;
				continue;
			case '\n':
				lines.add(text.substring(lineStart, i));
				i++;
				if (i < n && text.charAt(i) == '\r') {
					i++;
				}
				lineStart= i;
				continue;
			default:
				i++;
				continue;
			}
		}
		if (lineStart < n) {
			lines.add(text.substring(lineStart, n));
		}
	}
	
	/**
	 * Adds text of lines of a document without its line delimiters to the list.
	 * 
	 * The first line begins at <code>offset</code>, the last line ends at <code>offset+length</code>.
	 * The positions must not be inside a line delimiter (if it consists of multiple chars).
	 * 
	 * @param document the document
	 * @param offset the offset of region to include
	 * @param length the length of region to include
	 * @param lines list the lines are added to
	 * @throws BadLocationException
	 */
	public static final void addLines(final IDocument document, final int offset, final int length,
			final ArrayList<String> lines) throws BadLocationException {
		final int startLine= document.getLineOfOffset(offset);
		final int endLine= document.getLineOfOffset(offset+length);
		lines.ensureCapacity(lines.size() + endLine-startLine+1);
		
		IRegion lineInfo;
		if (startLine > endLine) {
			throw new IllegalArgumentException();
		}
		if (startLine == endLine) {
			lineInfo= document.getLineInformation(endLine);
			lines.add(document.get(offset, length));
			return;
		}
		else {
			lineInfo= document.getLineInformation(startLine);
			lines.add(document.get(offset, Math.max(0, lineInfo.getOffset()+lineInfo.getLength()-offset)));
			for (int line= startLine+1; line < endLine; line++) {
				lineInfo= document.getLineInformation(line);
				lines.add(document.get(lineInfo.getOffset(), lineInfo.getLength()));
			}
			lineInfo= document.getLineInformation(endLine);
			if (offset+length > lineInfo.getOffset()) {
				lines.add(document.get(lineInfo.getOffset(), offset+length-lineInfo.getOffset()));
			}
		}
	}
	
	/**
	 * Computes the region of full lines containing the two specified positions 
	 * (e.g. begin and end offset of the editor selection).
	 * 
	 * If the second position is in column 0 and in another line than the first position,
	 * the line of second position is not included in the region. The last line contains
	 * the line delimiter, if exists (not if EOF).
	 * 
	 * @param document the document
	 * @param position1 first position
	 * @param position2 second position >= position1
	 * @return a region for the block
	 * @throws BadLocationException
	 */
	public static final IRegion getBlock(final IDocument document, final int position1, final int position2) throws BadLocationException {
		final int line1= document.getLineOfOffset(position1);
		int line2= document.getLineOfOffset(position2);
		if (line1 < line2 && document.getLineOffset(line2) == position2) {
			line2--;
		}
		final int start= document.getLineOffset(line1);
		final int length= document.getLineOffset(line2)+document.getLineLength(line2)-start;
		return new Region(start, length);
	}
	
	public static final int getColumn(final IDocument document, final int offset, int line, int tabWidth)
			throws BadLocationException {
		if (offset > document.getLength()) {
			return -1;
		}
		if (line < 0) {
			line= document.getLineOfOffset(offset);
		}
		if (tabWidth <= 0) {
			tabWidth= 8;
		}
		int currentColumn= 0;
		int currentOffset= document.getLineOffset(line);
		while (currentOffset < offset) {
			final char c= document.getChar(currentOffset++);
			switch (c) {
			case '\n':
			case '\r':
				return -1;
			case '\t':
				currentColumn+= tabWidth - (currentColumn % tabWidth);
				continue;
			default:
				currentColumn++;
				continue;
			}
		}
		return currentColumn;
	}
	
	public static final int getColumn(final String text, final int offset, int tabWidth) {
		if (offset > text.length()) {
			return -1;
		}
		if (tabWidth <= 0) {
			tabWidth= 8;
		}
		int currentColumn= 0;
		int currentOffset= 0;
		while (currentOffset < offset) {
			final char c= text.charAt(currentOffset++);
			switch (c) {
			case '\n':
			case '\r':
				return -1;
			case '\t':
				currentColumn+= tabWidth - (currentColumn % tabWidth);
				continue;
			default:
				currentColumn++;
				continue;
			}
		}
		return currentColumn;
	}
	
	
	public static final int countBackward(final IDocument document, int offset, final char c)
			throws BadLocationException {
		int count= 0;
		while (offset > 0 && document.getChar(--offset) == c) {
			count++;
		}
		return count;
	}
	
	public static final int countForward(final IDocument document, int offset, final char c)
			throws BadLocationException {
		int count= 0;
		final int length= document.getLength();
		while (offset < length && document.getChar(offset++) == c) {
			count++;
		}
		return count;
	}
	
	
	public static List<IRegion> getMatchingRegions(final AbstractDocument document,
			final String partitioning, final PartitionConstraint contraint,
			final IRegion region, final boolean extend) throws BadLocationException, BadPartitioningException {
		final List<IRegion> regions= new ArrayList<>();
		
		final int regionEnd= region.getOffset() + region.getLength();
		int validBegin= -1;
		int offset= region.getOffset();
		
		if (extend && offset > 0) {
			final ITypedRegion partition= document.getPartition(partitioning, offset - 1, false);
			if (contraint.matches(partition.getType())) {
				offset= partition.getOffset();
				do {
					final ITypedRegion prevPartition= document.getPartition(partitioning, offset - 1, false);
					if (!contraint.matches(prevPartition.getType())) {
						break;
					}
					offset= prevPartition.getOffset();
				} while (offset > 0);
				validBegin= offset;
			}
			offset= partition.getOffset() + partition.getLength();
		}
		
		do {
			final ITypedRegion partition= document.getPartition(partitioning, offset, false);
			if (validBegin < 0) {
				if (contraint.matches(partition.getType())) {
					validBegin= partition.getOffset();
				}
			}
			else { // (validBegin >= 0)
				if (!contraint.matches(partition.getType())) {
					regions.add(new Region(validBegin, offset - validBegin));
					validBegin= -1;
				}
			}
			offset= partition.getOffset() + partition.getLength();
		} while (offset < regionEnd);
		
		if (validBegin >= 0) {
			if (extend) {
				do {
					final ITypedRegion partition= document.getPartition(partitioning, offset, false);
					if (!contraint.matches(partition.getType())) {
						break;
					}
					offset= partition.getOffset() + partition.getLength();
				} while (offset < document.getLength());
			}
			regions.add(new Region(validBegin, offset - validBegin));
		}
		
		return regions;
	}
	
}
