//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.richtext.actions;

import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.richtext.IRichText;
import org.eclipse.epf.richtext.RichTextCommand;
import org.eclipse.epf.richtext.RichTextEditor;
import org.eclipse.epf.richtext.RichTextImages;
import org.eclipse.epf.richtext.RichTextPlugin;
import org.eclipse.epf.richtext.RichTextResources;
import org.eclipse.epf.richtext.dialogs.FindReplaceDialog;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

/**
 * Finds and replaces text in a rich text control.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class FindReplaceAction extends RichTextAction {

	/**
	 * Finds text sub action.
	 */
	public static final int FIND_TEXT = 1;

	/**
	 * Replaces text sub action.
	 */
	public static final int REPLACE_TEXT = 2;

	/**
	 * Replaces and finds text sub action.
	 */
	public static final int REPLACE_FIND_TEXT = 3;

	/**
	 * Replaces all sub action.
	 */
	public static final int REPLACE_ALL_TEXT = 4;

	/**
	 * Find match in a forward direction.
	 */
	public static final int FORWARD_MATCH = 1;

	/**
	 * Find match in a backward direction.
	 */
	public static final int BACKWARD_MATCH = -1;

	/**
	 * Whole word match.
	 */
	public static final int WHOLE_WORD_MATCH = 2;

	/**
	 * Case sensitive match.
	 */
	public static final int CASE_SENSITIVE_MATCH = 4;

	// Encoded single quote.
	private static final String ENCODED_SINGLE_QUOTE = "%sq%"; //$NON-NLS-1$

	private IRichText richText;

	private StyledText styledText;

	protected boolean foundMatch = false;
	
	// the dialog instance
	protected FindReplaceDialog dialog;

	/**
	 * Creates a new instance.
	 */
	public FindReplaceAction(IRichText richText) {
		super(richText, IAction.AS_PUSH_BUTTON);
		setImageDescriptor(RichTextImages.IMG_DESC_FIND_REPLACE);
		setDisabledImageDescriptor(RichTextImages.DISABLED_IMG_DESC_FIND_REPLACE);
		setToolTipText(RichTextResources.findReplaceAction_toolTipText);
	}

	/**
	 * Returns <code>true</code> if this action should be disabled when the
	 * rich text editor is in readonly mode.
	 */
	public boolean disableInReadOnlyMode() {
		return false;
	}

	/**
	 * Returns <code>true</code> if this action should be disabled when the
	 * rich text editor is in source edit mode.
	 */
	public boolean disableInSourceMode() {
		return false;
	}

	/**
	 * Executes the action.
	 * 
	 * @param richText
	 *            a rich text control
	 */
	public void execute(IRichText richText) {
		if (this.richText == null)
			this.richText = richText;
		if (this.richText != null) {
			try {
				if (dialog != null) {
					dialog.setFindOnly(!this.richText.getEditable());
					dialog.open();
				} else {
					dialog = new FindReplaceDialog(Display
							.getCurrent().getActiveShell(), this, !this.richText
							.getEditable());
					dialog.open();
				}
			} catch (Exception e) {
				RichTextPlugin.getDefault().getLogger().logError(e);
			}
		}
	}

	/**
	 * Returns <code>true</code> if a match is found.
	 * 
	 * @return <code>true</code> if a match is found.
	 */
	public boolean getFoundMatch() {
		return foundMatch;
	}

	/**
	 * Executes the action.
	 * 
	 * @param subAction
	 *            the sub action to execute
	 * @param findText
	 *            the find text
	 * @param replaceText
	 *            the replace text
	 * @param matchDir
	 *            the match direction; the value can either be
	 *            <code>FIND_FORWARD</code> or <code>FIND_BACKWARD</code>.
	 * @param matchOptions
	 *            the match options
	 */
	public void run(int subAction, String findText, String replaceText,
			int matchDir, int matchOptions) {
		styledText = null;
		if (richText instanceof RichTextEditor
				&& ((RichTextEditor) richText).isHTMLTabSelected()) {
			styledText = ((RichTextEditor) richText).getSourceEdit();
		}
		if (styledText == null) {
			if (findText.indexOf("'") != -1) { //$NON-NLS-1$
				findText = findText.replaceAll("'", ENCODED_SINGLE_QUOTE); //$NON-NLS-1$
			}
			if (replaceText.indexOf("'") != -1) { //$NON-NLS-1$
				replaceText = replaceText.replaceAll("'", ENCODED_SINGLE_QUOTE); //$NON-NLS-1$
			}
		}
		try {
			foundMatch = false;
			int status = 0;
			switch (subAction) {
			case FIND_TEXT:
				status = findText(findText, matchDir, matchOptions);
				break;
			case REPLACE_TEXT:
				status = replaceText(replaceText, matchDir, matchOptions);
				break;
			case REPLACE_FIND_TEXT:
				status = replaceFindText(findText, replaceText, matchDir,
						matchOptions);
				break;
			case REPLACE_ALL_TEXT:
				replaceAll(findText, replaceText, matchOptions);
				break;
			}
			if (status > 0)
				foundMatch = true;
		} catch (Exception e) {
			RichTextPlugin.getDefault().getLogger().logError(e);
		}
	}

	/**
	 * Escapes the given text.
	 * 
	 * @param text
	 *            text to be escaped
	 */
	private static String escape(String text) {
		if (text == null || text.length() == 0)
			return ""; //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		int textSize = text.length();
		for (int i = 0; i < textSize; i++) {
			char ch = text.charAt(i);
			switch (ch) {
			case '<':
				sb.append(XMLUtil.XML_LT);
				break;
			case '>':
				sb.append(XMLUtil.XML_GT);
				break;
			case '&':
				sb.append(XMLUtil.XML_AMP);
				break;
			default:
				sb.append(ch);
				break;
			}
		}
		return sb.toString();
	}

	private int findText(String findText, int matchDir, int matchOptions) {
		int status = 0;
		if (styledText != null) {
			status = styledTextFindTextAndSelect(findText, matchDir,
					matchOptions);
		} else {
			status = richText
					.executeCommand(RichTextCommand.FIND_TEXT, new String[] {
							findText, "" + matchDir, "" + matchOptions }); //$NON-NLS-1$ //$NON-NLS-2$				
		}
		return status;
	}

	private int replaceText(String replaceText, int matchDir, int matchOptions) {
		int status = 0;
		if (styledText != null) {
			status = styledTextReplaceTextAndSelect(replaceText);
		} else {
			status = richText.executeCommand(RichTextCommand.REPLACE_TEXT,
					new String[] { replaceText,
							"" + matchDir, "" + matchOptions }); //$NON-NLS-1$ //$NON-NLS-2$					
		}
		return status;
	}

	private int replaceFindText(String findText, String replaceText,
			int matchDir, int matchOptions) {
		int status = 0;
		if (styledText != null) {
			styledTextReplaceTextAndSelect(replaceText);
			status = styledTextFindTextAndSelect(findText, matchDir,
					matchOptions);
		} else {
			richText.executeCommand(RichTextCommand.REPLACE_TEXT, new String[] {
					replaceText, "" + matchDir, "" + matchOptions }); //$NON-NLS-1$ //$NON-NLS-2$
			status = richText
					.executeCommand(RichTextCommand.FIND_TEXT, new String[] {
							findText, "" + matchDir, "" + matchOptions }); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return status;
	}

	private void replaceAll(String findText, String replaceText,
			int matchOptions) {
		if (styledText != null) {
			styledTextReplaceAll(findText, replaceText, matchOptions);
		} else {
			richText.executeCommand(RichTextCommand.REPLACE_ALL_TEXT,
					new String[] { escape(findText), escape(replaceText),
							"" + matchOptions }); //$NON-NLS-1$
		}
	}

	private int styledTextFindTextAndSelect(String findText, int matchDir,
			int matchOptions) {
		Point selectionOffset = styledText.getSelectionRange();
		int firstSelectedOffset = selectionOffset.x;
		int lastSelectedOffset = selectionOffset.x + selectionOffset.y - 1;
		String htmlText = styledText.getText();
		int indexOfMatch = -1;
		if ((matchOptions & CASE_SENSITIVE_MATCH) == 0) {
			// TODO: use toUpperCase(Locale) once library has locale attribute
			htmlText = htmlText.toUpperCase();
			findText = findText.toUpperCase();
		}
		do {
			if (indexOfMatch != -1) {
				lastSelectedOffset = indexOfMatch + 1;
				firstSelectedOffset = indexOfMatch - 1;
			}
			if (matchDir == FORWARD_MATCH) {
				indexOfMatch = htmlText.indexOf(findText,
						lastSelectedOffset + 1);
			} else {
				indexOfMatch = htmlText.lastIndexOf(findText,
						firstSelectedOffset - 1);
			}
		} while (indexOfMatch != -1
				&& ((matchOptions & WHOLE_WORD_MATCH) == WHOLE_WORD_MATCH)
				&& isPartOfWord(htmlText, indexOfMatch, findText.length()));
		if (indexOfMatch != -1) {
			styledText.setSelectionRange(indexOfMatch, findText.length());
			styledText.showSelection();
		} else {
			String selectedText = styledText.getSelectionText();
			if ((matchOptions & CASE_SENSITIVE_MATCH) == 0) {
				selectedText = selectedText.toUpperCase();
			}
			if (selectedText.equals(findText)) {
				indexOfMatch = styledText.getSelectionRange().x;
			}
		}
		return indexOfMatch;

	}

	private int styledTextReplaceTextAndSelect(String replaceText) {
		Point selectionOffset = styledText.getSelectionRange();
		styledText.replaceTextRange(selectionOffset.x, selectionOffset.y,
				replaceText);
		styledText.setSelectionRange(selectionOffset.x, replaceText.length());

		return 1;
	}

	private void styledTextReplaceAll(String findText, String replaceText,
			int matchOptions) {
		styledText.setSelectionRange(0, 0);
		while (styledTextFindTextAndSelect(findText, FORWARD_MATCH,
				matchOptions) != -1) {
			styledTextReplaceTextAndSelect(replaceText);
		}
	}

	private boolean isWordChar(char c) {
		if (Character.isLetterOrDigit(c))
			return true;
		return false;
	}

	private boolean isPartOfWord(String text, int index, int length) {
		if (index > 0)
			if (isWordChar(text.charAt(index - 1)))
				return true;
		if (text.length() >= index + length)
			if (isWordChar(text.charAt(index + length)))
				return true;
		return false;
	}

	public IRichText getRichText() {
		return richText;
	}

	public void setRichText(IRichText richText) {
		this.richText = richText;
	}
	
	public void dispose() {
		if (dialog != null) {
			dialog.close();
			dialog = null;
		}
	}

}
