package common.plugin.literal.popup.actions;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * リテラル化アクション
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class ToLiteralAction implements IEditorActionDelegate {
	/** エディタパート */
	private IEditorPart targetPart = null;

	/**
	 * @see org.eclipse.ui.IEditorActionDelegate
	 * #setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
	 */
	@Override
	public void setActiveEditor(final IAction action, final IEditorPart targetEditor) {
		this.targetPart = targetEditor;
	}

	/**
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	@Override
	public void run(final IAction action) {
		IWorkbenchPage wbp = this.targetPart.getEditorSite().getPage();
		ITextSelection sel = (ITextSelection)wbp.getSelection();
		String str = sel.getText();
		if (str.isEmpty()) {
			return;
		}

		boolean dquote = false;
		MultiTextEdit mte = new MultiTextEdit();
		for (int i = 0; i < sel.getLength(); i++) {
			if (!Character.isWhitespace(str.codePointAt(i))) {
				if (!dquote) {
					if (0 < mte.getChildrenSize()) {
						mte.addChild(new InsertEdit(sel.getOffset() + i, "+ \""));
					} else {
						mte.addChild(new InsertEdit(sel.getOffset() + i, "\""));
					}

					dquote = true;
				}

				if (str.codePointAt(i) == '\\' || str.codePointAt(i) == '"') {
					mte.addChild(new InsertEdit(sel.getOffset() + i, "\\"));
				}
			} else if (str.codePointAt(i) == '\n') {
				if (dquote) {
					int loc = i;
					if (0 < i && str.codePointAt(i - 1) == '\r') {
						loc = i - 1;
					}
					mte.addChild(new InsertEdit(sel.getOffset() + loc, "\\n\""));

					dquote = false;
				}
			}
		}

		if (dquote) {
			mte.addChild(new InsertEdit(sel.getOffset() + sel.getLength(), "\""));
		}

		ITextEditor te = (ITextEditor)this.targetPart;
		IDocument doc = te.getDocumentProvider().getDocument(this.targetPart.getEditorInput());
		try {
			mte.apply(doc);
		} catch (BadLocationException ex) {
			MessageDialog.openInformation(
					this.targetPart.getEditorSite().getShell(), "", sel.getText());
		}
	}

	/**
	 * @see org.eclipse.ui.IActionDelegate
	 * #selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
	 */
	@Override
	public void selectionChanged(final IAction action, final ISelection selection) {
		// NOP
	}
}
