/*=============================================================================#
 # Copyright (c) 2009, 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.jcommons.text.core;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import org.eclipse.statet.jcommons.lang.Immutable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public class BasicTextLineInformation implements TextLineInformation, Immutable {
	
	
	private final int[] startOffsets;
	private final int textLength;
	
	
	public BasicTextLineInformation(final int[] offsets, final int textLength) {
		this.startOffsets= nonNullAssert(offsets);
		this.textLength= textLength;
	}
	
	
	@Override
	public int getNumberOfLines() {
		return this.startOffsets.length;
	}
	
	@Override
	public int getLineOfOffset(final int offset) {
		if (offset < 0 || offset > this.textLength) {
			throw new IllegalArgumentException("offset= " + offset); //$NON-NLS-1$
		}
		if (this.startOffsets.length == 0) {
			return 0;
		}
		int low= 0;
		int high= this.startOffsets.length - 1;
		
		while (low <= high) {
			final int mid= (low + high) >> 1;
			final int lineOffset= this.startOffsets[mid];
			
			if (lineOffset < offset) {
				low= mid + 1;
			}
			else if (lineOffset > offset) {
				high= mid - 1;
			}
			else {
				return mid;
			}
		}
		return low - 1;
	}
	
	@Override
	public int getStartOffset(final int line) {
		if (line < 0 || line >= this.startOffsets.length) {
			throw new IllegalArgumentException("line= " + line); //$NON-NLS-1$
		}
		return this.startOffsets[line];
	}
	
	@Override
	public int getEndOffset(final int line) {
		if (line < 0 || line >= this.startOffsets.length) {
			throw new IllegalArgumentException("line= " + line); //$NON-NLS-1$
		}
		return (line + 1 == this.startOffsets.length) ?
				this.textLength :
				this.startOffsets[line + 1];
	}
	
	@Override
	public int getLength(final int line) {
		if (line < 0 || line >= this.startOffsets.length) {
			throw new IllegalArgumentException("line= " + line); //$NON-NLS-1$
		}
		return (line + 1 == this.startOffsets.length) ?
				(this.textLength - this.startOffsets[line]) :
				(this.startOffsets[line + 1] - this.startOffsets[line]);
	}
	
	@Override
	public TextRegion getRegion(final int line) {
		if (line < 0 || line >= this.startOffsets.length) {
			throw new IllegalArgumentException("line= " + line); //$NON-NLS-1$
		}
		return new BasicTextRegion(this.startOffsets[line],
				(line + 1 == this.startOffsets.length) ?
						this.textLength :
						this.startOffsets[line + 1] );
	}
	
	
	@Override
	public int hashCode() {
		return this.startOffsets.hashCode() + this.textLength;
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof TextLineInformation) {
			final TextLineInformation other= (TextLineInformation) obj;
			final int n= getNumberOfLines();
			if (n != other.getNumberOfLines()) {
				return false;
			}
			for (int line= 0; line <= n; line++) {
				if (getStartOffset(line) != other.getStartOffset(line)
						|| getEndOffset(line) != other.getEndOffset(line) ) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
	
}
