/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.text;

import java.text.CharacterIterator;
import java.util.Locale;

import com.ibm.icu.text.BreakIterator;



/**
 * Standard implementation of
 * {@link org.eclipse.jface.text.ITextDoubleClickStrategy}.
 * <p>
 * Selects words using <code>java.text.BreakIterator</code> for the default
 * locale.</p>
 *
 * @see java.text.BreakIterator
 */
public class DefaultTextDoubleClickStrategy implements ITextDoubleClickStrategy {


	/**
	 * Implements a character iterator that works directly on
	 * instances of <code>IDocument</code>. Used to collaborate with
	 * the break iterator.
	 *
	 * @see IDocument
	 * @since 2.0
	 */
	static class DocumentCharacterIterator implements CharacterIterator {

		/** Document to iterate over. */
		private IDocument fDocument;
		/** Start offset of iteration. */
		private int fOffset= -1;
		/** End offset of iteration. */
		private int fEndOffset= -1;
		/** Current offset of iteration. */
		private int fIndex= -1;

		/** Creates a new document iterator. */
		public DocumentCharacterIterator() {
		}

		/**
		 * Configures this document iterator with the document section to be visited.
		 *
		 * @param document the document to be iterated
		 * @param iteratorRange the range in the document to be iterated
		 */
		public void setDocument(IDocument document, IRegion iteratorRange) {
			fDocument= document;
			fOffset= iteratorRange.getOffset();
			fEndOffset= fOffset + iteratorRange.getLength();
		}

		@Override
		public char first() {
			fIndex= fOffset;
			return current();
		}

		@Override
		public char last() {
			fIndex= fOffset < fEndOffset ? fEndOffset -1 : fEndOffset;
			return current();
		}

		@Override
		public char current() {
			if (fOffset <= fIndex && fIndex < fEndOffset) {
				try {
					return fDocument.getChar(fIndex);
				} catch (BadLocationException x) {
				}
			}
			return DONE;
		}

		@Override
		public char next() {
			++fIndex;
			int end= getEndIndex();
			if (fIndex >= end) {
				fIndex= end;
				return DONE;
			}
			return current();
		}

		@Override
		public char previous() {
			if (fIndex == fOffset)
				return DONE;

			if (fIndex > fOffset)
				-- fIndex;

			return current();
		}

		@Override
		public char setIndex(int index) {
			fIndex= index;
			return current();
		}

		@Override
		public int getBeginIndex() {
			return fOffset;
		}

		@Override
		public int getEndIndex() {
			return fEndOffset;
		}

		@Override
		public int getIndex() {
			return fIndex;
		}

		@Override
		public Object clone() {
			DocumentCharacterIterator i= new DocumentCharacterIterator();
			i.fDocument= fDocument;
			i.fIndex= fIndex;
			i.fOffset= fOffset;
			i.fEndOffset= fEndOffset;
			return i;
		}
	}


	/**
	 * The document character iterator used by this strategy.
	 * @since 2.0
	 */
	private DocumentCharacterIterator fDocIter= new DocumentCharacterIterator();

	/**
	 * The locale specific word break iterator.
	 * @since 3.7
	 */
	private BreakIterator fWordBreakIterator;

	/**
	 * The POSIX word break iterator.
	 * <p>
	 * Used to workaround ICU bug not treating '.' as word boundary, see
	 * http://bugs.icu-project.org/trac/ticket/8371 for details.
	 * </p>
	 *
	 * @since 3.7
	 */
	private BreakIterator fPOSIXWordBreakIterator;


	/**
	 * Creates a new default text double click strategy.
	 */
	public DefaultTextDoubleClickStrategy() {
	}

	@Override
	public void doubleClicked(ITextViewer text) {

		int offset= text.getSelectedRange().x;

		if (offset < 0)
			return;

		final IDocument document= text.getDocument();
		IRegion region= findExtendedDoubleClickSelection(document, offset);
		if (region == null)
			region= findWord(document, offset);
		if (region != null)
			text.setSelectedRange(region.getOffset(), region.getLength());

	}

	/**
	 * Tries to find a suitable double click selection for the given offset.
	 * <p>
	 * <strong>Note:</strong> This method must return <code>null</code> if it simply selects the word at
	 * the given offset.
	 * </p>
	 *
	 * @param document the document
	 * @param offset the offset
	 * @return the selection or <code>null</code> if none to indicate simple word selection
	 * @since 3.5
	 */
	protected IRegion findExtendedDoubleClickSelection(IDocument document, int offset) {
		return null;
	}

	/**
	 * Tries to find the word at the given offset.
	 *
	 * @param document the document
	 * @param offset the offset
	 * @return the word or <code>null</code> if none
	 * @since 3.5
	 */
	protected IRegion findWord(IDocument document, int offset) {
		return findWord(document, offset, getWordBreakIterator());
	}

	/**
	 * Returns the locale specific word break iterator.
	 *
	 * @return the locale specific word break iterator
	 * @since 3.7
	 */
	private BreakIterator getWordBreakIterator() {
		if (fWordBreakIterator == null)
			fWordBreakIterator= BreakIterator.getWordInstance();
		return fWordBreakIterator;
	}

	/**
	 * Returns the POSIX word break iterator.
	 *
	 * <p>
	 * Used to workaround ICU bug not treating '.' as word boundary, see
	 * http://bugs.icu-project.org/trac/ticket/8371 for details.
	 * </p>
	 *
	 * @return the POSIX word break iterator.
	 * @since 3.7
	 */
	private BreakIterator getPOSIXWordBreakIterator() {
		if (fPOSIXWordBreakIterator == null)
			fPOSIXWordBreakIterator= BreakIterator.getWordInstance(new Locale("en", "US", "POSIX")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		return fPOSIXWordBreakIterator;
	}

	/**
	 * Tries to find the word at the given offset.
	 *
	 * @param document the document
	 * @param offset the offset
	 * @param wordBreakIterator the word break iterator
	 * @return the word or <code>null</code> if none
	 * @since 3.7
	 */
	private IRegion findWord(IDocument document, int offset, BreakIterator wordBreakIterator) {
		IRegion line;
		try {
			line= document.getLineInformationOfOffset(offset);
		} catch (BadLocationException e) {
			return null;
		}

		if (offset == line.getOffset() + line.getLength())
			return null;

		fDocIter.setDocument(document, line);

		wordBreakIterator.setText(fDocIter);

		int start= wordBreakIterator.preceding(offset);
		if (start == BreakIterator.DONE)
			start= line.getOffset();

		int end= wordBreakIterator.following(offset);
		if (end == BreakIterator.DONE)
			end= line.getOffset() + line.getLength();

		if (wordBreakIterator.isBoundary(offset)) {
			if (end - offset > offset - start)
				start= offset;
			else
				end= offset;
		}

		if (end == start)
			return null;

		int length= end - start;
		try {
			// Workaround for ICU bug not treating '.' as word boundary, see http://bugs.icu-project.org/trac/ticket/8371 for details.
			if (fPOSIXWordBreakIterator != wordBreakIterator && document.get(start, length).indexOf('.') != -1) {
				IRegion wordRegion= findWord(document, offset, getPOSIXWordBreakIterator());
				if (wordRegion != null) {
					int wordStart= wordRegion.getOffset();
					int wordEnd= wordStart + wordRegion.getLength();
					// Check that no additional breaks besides '.' are introduced
					if ((wordStart == start || wordStart > start && document.getChar(wordStart - 1) == '.') && (wordEnd == end || wordEnd < end && document.getChar(wordEnd) == '.'))
						return wordRegion;
				}
			}
		} catch (BadLocationException e) {
			// Use previously computed word region
		}

		return new Region(start, length);

	}
}
