/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.refactorings.extractstring;

import com.android.ide.eclipse.adt.AdtConstants;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;

/*
 * Quick Reference Link:
 * http://www.eclipse.org/articles/article.php?file=Article-Unleashing-the-Power-of-Refactoring/index.html
 * and
 * http://www.ibm.com/developerworks/opensource/library/os-ecjdt/
 */

/**
 * Action executed when the "Extract String" menu item is invoked.
 * <p/>
 * The intent of the action is to start a refactoring that extracts a source string and
 * replaces it by an Android string resource ID.
 * <p/>
 * Workflow:
 * <ul>
 * <li> The action is currently located in the Refactoring menu in the main menu.
 * <li> TODO: extend the popup refactoring menu in a Java or Android XML file.
 * <li> The action is only enabled if the selection is 1 character or more. That is at least part
 *     of the string must be selected, it's not enough to just move the insertion point. This is
 *     a limitation due to {@link #selectionChanged(IAction, ISelection)} not being called when
 *     the insertion point is merely moved. TODO: address this limitation.
 * <ul> The action gets the current {@link ISelection}. It also knows the current
 *     {@link IWorkbenchWindow}. However for the refactoring we are also interested in having the
 *     actual resource file. By looking at the Active Window > Active Page > Active Editor we
 *     can get the {@link IEditorInput} and find the {@link ICompilationUnit} (aka Java file)
 *     that is being edited.
 * <ul> TODO: change this to find the {@link IFile} being manipulated. The {@link ICompilationUnit}
 *     can be inferred using {@link JavaCore#createCompilationUnitFrom(IFile)}. This will allow
 *     us to be able to work with a selection from an Android XML file later.
 * <li> The action creates a new {@link ExtractStringRefactoring} and make it run on in a new
 *     {@link ExtractStringWizard}.
 * <ul>
 */
public class ExtractStringAction implements IWorkbenchWindowActionDelegate {

    /** Keep track of the current workbench window. */
    private IWorkbenchWindow mWindow;
    private ITextSelection mSelection;
    private IEditorPart mEditor;
    private IFile mFile;

    /**
     * Keep track of the current workbench window.
     */
    @Override
    public void init(IWorkbenchWindow window) {
        mWindow = window;
    }

    @Override
    public void dispose() {
        // Nothing to do
    }

    /**
     * Examine the selection to determine if the action should be enabled or not.
     * <p/>
     * Keep a link to the relevant selection structure (i.e. a part of the Java AST).
     */
    @Override
    public void selectionChanged(IAction action, ISelection selection) {

        // Note, two kinds of selections are returned here:
        // ITextSelection on a Java source window
        // IStructuredSelection in the outline or navigator
        // This simply deals with the refactoring based on a non-empty selection.
        // At that point, just enable the action and later decide if it's valid when it actually
        // runs since we don't have access to the AST yet.

        mSelection = null;
        mFile = null;

        if (selection instanceof ITextSelection) {
            mSelection = (ITextSelection) selection;
            if (mSelection.getLength() > 0) {
                mEditor = getActiveEditor();
                mFile = getSelectedFile(mEditor);
            }
        }

        action.setEnabled(mSelection != null && mFile != null);
    }

    /**
     * Create a new instance of our refactoring and a wizard to configure it.
     */
    @Override
    public void run(IAction action) {
        if (mSelection != null && mFile != null) {
            ExtractStringRefactoring ref = new ExtractStringRefactoring(mFile, mEditor, mSelection);
            RefactoringWizard wizard = new ExtractStringWizard(ref, mFile.getProject());
            RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
            try {
                op.run(mWindow.getShell(), wizard.getDefaultPageTitle());
            } catch (InterruptedException e) {
                // Interrupted. Pass.
            }
        }
    }

    /**
     * Returns the active editor (hopefully matching our selection) or null.
     */
    private IEditorPart getActiveEditor() {
        IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (wwin != null) {
            IWorkbenchPage page = wwin.getActivePage();
            if (page != null) {
                return page.getActiveEditor();
            }
        }

        return null;
    }

    /**
     * Returns the active {@link IFile} (hopefully matching our selection) or null.
     * The file is only returned if it's a file from a project with an Android nature.
     * <p/>
     * At that point we do not try to analyze if the selection nor the file is suitable
     * for the refactoring. This check is performed when the refactoring is invoked since
     * it can then produce meaningful error messages as needed.
     */
    private IFile getSelectedFile(IEditorPart editor) {
        if (editor != null) {
            IEditorInput input = editor.getEditorInput();

            if (input instanceof FileEditorInput) {
                FileEditorInput fi = (FileEditorInput) input;
                IFile file = fi.getFile();
                if (file.exists()) {
                    IProject proj = file.getProject();
                    try {
                        if (proj != null && proj.hasNature(AdtConstants.NATURE_DEFAULT)) {
                            return file;
                        }
                    } catch (CoreException e) {
                        // ignore
                    }
                }
            }
        }

        return null;
    }
}
