/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 *     Pierre-Yves B., pyvesdev@gmail.com - Bug 121634: [find/replace] status bar must show the string being searched when "String Not Found"
 *******************************************************************************/

package org.eclipse.ui.texteditor;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import java.util.regex.PatternSyntaxException;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.dialogs.IDialogSettings;

import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.text.IFindReplaceTargetExtension3;
import org.eclipse.jface.text.TextUtilities;

import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.internal.texteditor.NLSUtility;
import org.eclipse.ui.internal.texteditor.TextEditorPlugin;


/**
 * An action which finds the next/previous occurrence of the last search or the
 * current selection if present.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 *
 * @since 2.0
 * @noextend This class is not intended to be subclassed by clients.
 */
public class FindNextAction extends ResourceAction implements IUpdate {

	/** The action's target */
	private IFindReplaceTarget fTarget;
	/** The part the action is bound to */
	private IWorkbenchPart fWorkbenchPart;
	/** The workbench window */
	private IWorkbenchWindow fWorkbenchWindow;
	/** The dialog settings to retrieve the last search */
	private IDialogSettings fDialogSettings;
	/** The find history as initially given in the dialog settings. */
	private List<String> fFindHistory= new ArrayList<>();
	/** The find string as initially given in the dialog settings. */
	private String fFindString;
	/** The search direction as initially given in the dialog settings. */
	private boolean fForward;
	/** The wrapping flag as initially given in the dialog settings. */
	private boolean fWrapInit;
	/** The case flag as initially given in the dialog settings. */
	private boolean fCaseInit;
	/** The whole word flag as initially given in the dialog settings. */
	private boolean fWholeWordInit;
	/**
	 * The regExSearch flag as initially given in the dialog settings.
	 *
	 * @since 3.0
	 */
	private boolean fRegExSearch;
	/**
	 * The last selection set by find/replace.
	 *
	 * @since 3.0
	 */
	private String fSelection;

	/**
	 * Creates a new find/replace action for the given workbench part.
	 * The action configures its visual representation from the given
	 * resource bundle.
	 *
	 * @param bundle the resource bundle
	 * @param prefix a prefix to be prepended to the various resource keys
	 *   (described in <code>ResourceAction</code> constructor), or
	 *   <code>null</code> if none
	 * @param workbenchPart the workbench part
	 * @param forward the search direction
	 * @see ResourceAction#ResourceAction(ResourceBundle, String)
	 */
	public FindNextAction(ResourceBundle bundle, String prefix, IWorkbenchPart workbenchPart, boolean forward) {
		super(bundle, prefix);
		fWorkbenchPart= workbenchPart;
		fForward= forward;
		update();
	}

	/**
	 * Creates a new find/replace action for the given workbench window.
	 * The action configures its visual representation from the given
	 * resource bundle.
	 *
	 * @param bundle the resource bundle
	 * @param prefix a prefix to be prepended to the various resource keys
	 *   (described in <code>ResourceAction</code> constructor), or
	 *   <code>null</code> if none
	 * @param workbenchWindow the workbench window
	 * @param forward the search direction
	 * @see ResourceAction#ResourceAction(ResourceBundle, String)
	 *
	 * @deprecated use FindReplaceAction(ResourceBundle, String, IWorkbenchPart, boolean) instead
	 */
	@Deprecated
	public FindNextAction(ResourceBundle bundle, String prefix, IWorkbenchWindow workbenchWindow, boolean forward) {
		super(bundle, prefix);
		fWorkbenchWindow= workbenchWindow;
		fForward= forward;
		update();
	}

	/**
	 * Returns the find string based on the selection or the find history.
	 * @return the find string
	 */
	private String getFindString() {
		String fullSelection= fTarget.getSelectionText();
		String firstLine= getFirstLine(fullSelection);
		if ((firstLine.isEmpty() || fRegExSearch && fullSelection.equals(fSelection)) && !fFindHistory.isEmpty())
			return fFindHistory.get(0);
		else if (fRegExSearch && !fullSelection.isEmpty())
			return FindReplaceDocumentAdapter.escapeForRegExPattern(fullSelection);
		else
			return firstLine;
	}

	/**
	 * Returns the status line manager of the active editor.
	 * @return the status line manager of the active editor
	 */
	private IStatusLineManager getStatusLineManager() {
		IEditorPart editor= fWorkbenchPart.getSite().getPage().getActiveEditor();
		if (editor == null)
			return null;

		return editor.getEditorSite().getActionBars().getStatusLineManager();
	}

	/**
	 * Sets the "no matches found" error message to the status line.
	 *
	 * @since 3.0
	 */
	private void statusNotFound() {
		fWorkbenchPart.getSite().getShell().getDisplay().beep();

		IStatusLineManager manager= getStatusLineManager();
		if (manager == null)
			return;

		String msg= NLSUtility.format(EditorMessages.FindNext_Status_noMatch_label, fFindString);
		manager.setMessage(msg);
	}

	/**
	 * Clears the status line.
	 */
	private void statusClear() {
		IStatusLineManager manager= getStatusLineManager();
		if (manager == null)
			return;

		manager.setErrorMessage(""); //$NON-NLS-1$
		manager.setMessage(""); //$NON-NLS-1$
	}

	@Override
	public void run() {
		if (fTarget != null) {
			readConfiguration();

			fFindString= getFindString();
			if (fFindString == null) {
				statusNotFound();
				return;
			}

			boolean wholeWord= fWholeWordInit && !fRegExSearch && isWord(fFindString);

			statusClear();
			if (!findNext(fFindString, fForward, fCaseInit, fWrapInit, wholeWord, fRegExSearch))
				statusNotFound();

			writeConfiguration();
		}
	}

	/**
	 * Tests whether each character in the given string is a letter.
	 *
	 * @param str the string to check
	 * @return <code>true</code> if the given string is a word
	 * @since 3.2
	 */
	private boolean isWord(String str) {
		if (str == null || str.isEmpty())
			return false;

		for (int i= 0; i < str.length(); i++) {
			if (!Character.isJavaIdentifierPart(str.charAt(i)))
				return false;
		}
		return true;
	}

	@Override
	public void update() {

		if (fWorkbenchPart == null && fWorkbenchWindow != null)
			fWorkbenchPart= fWorkbenchWindow.getPartService().getActivePart();

		if (fWorkbenchPart != null)
			fTarget= fWorkbenchPart.getAdapter(IFindReplaceTarget.class);
		else
			fTarget= null;

		setEnabled(fTarget != null && fTarget.canPerformFind());
	}

	/*
	 * @see FindReplaceDialog#findIndex(String, int, boolean, boolean, boolean, boolean)
	 * @since 3.0
	 */
	private int findIndex(String findString, int startPosition, boolean forwardSearch, boolean caseSensitive, boolean wrapSearch, boolean wholeWord, boolean regExSearch) {

		if (forwardSearch) {
			if (wrapSearch) {
				int index= findAndSelect(startPosition, findString, true, caseSensitive, wholeWord, regExSearch);
				if (index == -1) {
					beep();
					index= findAndSelect(-1, findString, true, caseSensitive, wholeWord, regExSearch);
				}
				return index;
			}
			return findAndSelect(startPosition, findString, true, caseSensitive, wholeWord, regExSearch);
		}

		// backward
		if (wrapSearch) {
			int index= findAndSelect(startPosition - 1, findString, false, caseSensitive, wholeWord, regExSearch);
			if (index == -1) {
				beep();
				index= findAndSelect(-1, findString, false, caseSensitive, wholeWord, regExSearch);
			}
			return index;
		}
		return findAndSelect(startPosition - 1, findString, false, caseSensitive, wholeWord, regExSearch);
	}

	/**
	 * Returns whether the specified  search string can be found using the given options.
	 *
	 * @param findString the string to search for
	 * @param forwardSearch the search direction
	 * @param caseSensitive should the search honor cases
	 * @param wrapSearch	should the search wrap to the start/end if end/start reached
	 * @param wholeWord does the find string represent a complete word
	 * @param regExSearch if <code>true</code> findString represents a regular expression
	 * @return <code>true</code> if the find string can be found using the given options
	 * @since 3.0
	 */
	private boolean findNext(String findString, boolean forwardSearch, boolean caseSensitive, boolean wrapSearch, boolean wholeWord, boolean regExSearch) {

		Point r= fTarget.getSelection();
		int findReplacePosition= r.x;
		if (forwardSearch)
			findReplacePosition += r.y;

		int index= findIndex(findString, findReplacePosition, forwardSearch, caseSensitive, wrapSearch, wholeWord, regExSearch);

		if (index != -1)
			return true;

		return false;
	}

	private void beep() {
		Shell shell= null;
		if (fWorkbenchPart != null)
			shell= fWorkbenchPart.getSite().getShell();
		else if (fWorkbenchWindow != null)
			shell= fWorkbenchWindow.getShell();

		if (shell != null && !shell.isDisposed())
			shell.getDisplay().beep();
	}

	/**
	 * Searches for a string starting at the given offset and using the specified search
	 * directives. If a string has been found it is selected and its start offset is
	 * returned.
	 *
	 * @param offset the offset at which searching starts
	 * @param findString the string which should be found
	 * @param forwardSearch the direction of the search
	 * @param caseSensitive <code>true</code> performs a case sensitive search, <code>false</code> an insensitive search
	 * @param wholeWord if <code>true</code> only occurrences are reported in which the findString stands as a word by itself
	 * @param regExSearch if <code>true</code> findString represents a regular expression
	 * @return the position of the specified string, or -1 if the string has not been found
	 * @since 3.0
	 */
	private int findAndSelect(int offset, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {
		if (fTarget instanceof IFindReplaceTargetExtension3) {
			try {
				return ((IFindReplaceTargetExtension3)fTarget).findAndSelect(offset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
			} catch (PatternSyntaxException ex) {
				return -1;
			}
		}
		return fTarget.findAndSelect(offset, findString, forwardSearch, caseSensitive, wholeWord);
	}

	//--------------- configuration handling --------------

	/**
	 * Returns the dialog settings object used to share state
	 * between several find/replace dialogs.
	 *
	 * @return the dialog settings to be used
	 */
	private IDialogSettings getDialogSettings() {
		IDialogSettings settings= TextEditorPlugin.getDefault().getDialogSettings();
		fDialogSettings= settings.getSection(FindReplaceDialog.class.getName());
		if (fDialogSettings == null)
			fDialogSettings= settings.addNewSection(FindReplaceDialog.class.getName());
		return fDialogSettings;
	}

	/**
	 * Initializes itself from the dialog settings with the same state
	 * as at the previous invocation.
	 */
	private void readConfiguration() {
		IDialogSettings s= getDialogSettings();

		fWrapInit= s.get("wrap") == null || s.getBoolean("wrap"); //$NON-NLS-1$ //$NON-NLS-2$
		fCaseInit= s.getBoolean("casesensitive"); //$NON-NLS-1$
		fWholeWordInit= s.getBoolean("wholeword"); //$NON-NLS-1$
		fRegExSearch= s.getBoolean("isRegEx"); //$NON-NLS-1$
		fSelection= s.get("selection"); //$NON-NLS-1$

		String[] findHistory= s.getArray("findhistory"); //$NON-NLS-1$
		if (findHistory != null) {
			fFindHistory.clear();
			Collections.addAll(fFindHistory, findHistory);
		}
	}

	/**
	 * Stores its current configuration in the dialog store.
	 */
	private void writeConfiguration() {
		if (fFindString == null)
			return;

		IDialogSettings s= getDialogSettings();
		s.put("selection", fTarget.getSelectionText()); //$NON-NLS-1$

		if (!fFindHistory.isEmpty() && fFindString.equals(fFindHistory.get(0)))
			return;

		int index= fFindHistory.indexOf(fFindString);
		if (index != -1)
			fFindHistory.remove(index);
		fFindHistory.add(0, fFindString);

		while (fFindHistory.size() > 8)
			fFindHistory.remove(8);
		String[] names= new String[fFindHistory.size()];
		fFindHistory.toArray(names);
		s.put("findhistory", names); //$NON-NLS-1$
	}

	/**
	 * Returns the first line of the given selection.
	 *
	 * @param selection the selection
	 * @return the first line of the selection
	 */
	private String getFirstLine(String selection) {
		if (!selection.isEmpty()) {
			int[] info= TextUtilities.indexOf(TextUtilities.DELIMITERS, selection, 0);
			if (info[0] > 0)
				return selection.substring(0, info[0]);
			else if (info[0] == -1)
				return selection;
		}
		return selection;
	}
}
