/*******************************************************************************
 * Copyright (c) 2009 University of Illinois at Urbana-Champaign 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:
 *    UIUC - Initial API and implementation
 *******************************************************************************/
package org.eclipse.rephraserengine.ui.menus;

import java.util.LinkedList;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.rephraserengine.core.refactorings.IEditorRefactoring;
import org.eclipse.rephraserengine.core.refactorings.IResourceRefactoring;
import org.eclipse.rephraserengine.core.resources.IResourceFilter;
import org.eclipse.rephraserengine.internal.ui.actions.RefactoringAction;
import org.eclipse.rephraserengine.ui.WorkbenchSelectionInfo;
import org.eclipse.rephraserengine.ui.refactoring.CustomUserInputPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.ui.menus.CommandContributionItem;

/**
 * A dynamically-populated set of menu items for the Refactor menu in the menu bar and for various
 * pop-up menus.
 * <p>
 * This class iterates through the contributions to the <i>refactorings</i> extension point and uses
 * them to populate the menu.
 * <ul>
 * <li> When a <i>resourceRefactoring</i> is contributed, if there is some way to get at least one
 *      {@link IResource} from the current selection in the workbench, then that refactoring is
 *      shown in the menu.
 * <li> When a <i>editorRefactoring<i> is selected, if an editor is active and there is an
 *      {@link ITextSelection} available from that editor, then that refactoring is
 *      shown in the menu.
 * <li> When a <i>command</i> is contributed, the Eclipse Platform determines how it is displayed,
 *      whether it is enabled, etc.  It is always shown in the menu, but it might be disabled
 *      depending on the current selection.
 * </ul>
 *
 * @author Jeff Overbey
 *
 * @since 1.0
 */
@SuppressWarnings("restriction")
public final class RefactorMenu extends CompoundContributionItem
{
    private static final String REFACTORING_EXTENSION_POINT_ID = "org.eclipse.rephraserengine.ui.refactoring.refactorings"; //$NON-NLS-1$

    private WorkbenchSelectionInfo selection;

    @Override
    protected IContributionItem[] getContributionItems()
    {
        selection = new WorkbenchSelectionInfo();
        LinkedList<IContributionItem> result = loadRefactoringsFromExtensionPoint();
        return fixMenu(result);
    }

    private IContributionItem[] fixMenu(LinkedList<IContributionItem> result)
    {
        // The last item in a menu should never be a separator, and there
        // should never be two separators in a row (e.g., if this menu is
        // followed by another group of commands).  Both of those look
        // strange, and they can be avoided by never ending the list of
        // contribution items with a separator.
        if (!result.isEmpty() && result.getLast() instanceof SeparatorContributionItem)
            result.removeLast();

        // Adds an informative item ("No refactorings available") when
        // necessary, since an empty menu looks like a bug.
        if (result.isEmpty())
            return new IContributionItem[] { new EmptyMenuContributionItem() };

        return result.toArray(new IContributionItem[result.size()]);
    }

    private LinkedList<IContributionItem> loadRefactoringsFromExtensionPoint()
    {
        return loadRefactoringsFrom(Platform.getExtensionRegistry().getConfigurationElementsFor(REFACTORING_EXTENSION_POINT_ID));
    }

    private LinkedList<IContributionItem> loadRefactoringsFrom(IConfigurationElement[] configs)
    {
        LinkedList<IContributionItem> result = new LinkedList<IContributionItem>();

        for (IConfigurationElement elt : configs)
        {
            try
            {
                processConfigElt(elt, result);
            }
            catch (CoreException e)
            {
                e.printStackTrace();
            }
        }

        return result;
    }

    private void processConfigElt(IConfigurationElement elt, LinkedList<IContributionItem> result)
        throws CoreException
    {
        if (elt.getName().equals("resourceFilter")) //$NON-NLS-1$
        {
            IResourceFilter resourceFilter = (IResourceFilter)elt.createExecutableExtension("class"); //$NON-NLS-1$
            selection = new WorkbenchSelectionInfo(resourceFilter); // since resourceFilter changed
        }
        else if (elt.getName().equals("group")) //$NON-NLS-1$
        {
            if (!result.isEmpty() && !(result.getLast() instanceof SeparatorContributionItem))
                result.add(new SeparatorContributionItem());

            result.addAll(loadRefactoringsFrom(elt.getChildren()));
        }
        else if (elt.getName().equals("resourceRefactoring")) //$NON-NLS-1$
        {
            addResourceRefactoring(elt, result);
        }
        else if (elt.getName().equals("editorRefactoring")) //$NON-NLS-1$
        {
            addEditorRefactoring(elt, result);
        }
        else if (elt.getName().equals("command")) //$NON-NLS-1$
        {
            addCommand(elt, result);
        }
    }

    @SuppressWarnings("rawtypes")
    private void addResourceRefactoring(IConfigurationElement elt,
        LinkedList<IContributionItem> result) throws CoreException
    {
        if (selection.someFilesAreSelected())
        {
            if (elt.getAttribute("class") != null && environmentOK(elt)) //$NON-NLS-1$
            {
                try
                {
                    IResourceRefactoring refactoring = (IResourceRefactoring)elt.createExecutableExtension("class"); //$NON-NLS-1$
                    String label = elt.getAttribute("label"); //$NON-NLS-1$
                    CustomUserInputPage customInputPage =
                        elt.getAttribute("inputPage") == null //$NON-NLS-1$
                        ? null
                        : (CustomUserInputPage)elt.createExecutableExtension("inputPage"); //$NON-NLS-1$
                    result.add(new ResourceRefactoringContributionItem(
                        refactoring,
                        label,
                        customInputPage,
                        selection));
                }
                catch (Throwable t)
                {
                    t.printStackTrace();
                }
            }
            else if (elt.getAttribute("command") != null) //$NON-NLS-1$
            {
                result.add(commandContribution(elt.getAttribute("command"))); //$NON-NLS-1$
            }
        }
    }

    @SuppressWarnings("rawtypes")
    private void addEditorRefactoring(IConfigurationElement elt,
        LinkedList<IContributionItem> result) throws CoreException
    {
        if (selection.editingAnIFile() && selection.isTextSelectedInEditor())
        {
            if (elt.getAttribute("class") != null && environmentOK(elt)) //$NON-NLS-1$
            {
                try
                {
                    IEditorRefactoring refactoring = (IEditorRefactoring)elt.createExecutableExtension("class"); //$NON-NLS-1$
                    String label = elt.getAttribute("label"); //$NON-NLS-1$
                    CustomUserInputPage customInputPage =
                        elt.getAttribute("inputPage") == null //$NON-NLS-1$
                        ? null
                        : (CustomUserInputPage)elt.createExecutableExtension("inputPage"); //$NON-NLS-1$
                    result.add(new EditorRefactoringContributionItem(
                        refactoring,
                        label,
                        customInputPage,
                        selection.getFileInEditor(),
                        selection.getSelectionInEditor()));
                }
                catch (Throwable t)
                {
                    t.printStackTrace();
                }
            }
            else if (elt.getAttribute("command") != null) //$NON-NLS-1$
            {
                result.add(commandContribution(elt.getAttribute("command"))); //$NON-NLS-1$
            }
        }
    }

    private boolean environmentOK(IConfigurationElement elt)
    {
        if (elt.getAttribute("require_env") != null) //$NON-NLS-1$
            return System.getenv(elt.getAttribute("require_env")) != null; //$NON-NLS-1$
        else
            return true;
    }

    private void addCommand(IConfigurationElement elt, LinkedList<IContributionItem> result)
    {
        result.add(commandContribution(elt.getAttribute("id"))); //$NON-NLS-1$
    }

    @SuppressWarnings("deprecation")
    private CommandContributionItem commandContribution(String commandID)
    {
//        CommandContributionItemParameter param = new CommandContributionItemParameter(
//            Workbench.getInstance().getServiceLocator(),    // Service locator
//            null,                                           // ID
//            commandID,                                      // Command ID
//            CommandContributionItem.STYLE_PUSH);            // Style
//        return new CommandContributionItem(param);
        
        return new CommandContributionItem(
            Workbench.getInstance().getActiveWorkbenchWindow(), // Service locator
            null,                                           // ID
            commandID,                                      // Command ID
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            CommandContributionItem.STYLE_PUSH);            // Style
    }

    @SuppressWarnings("rawtypes")
    private static class ResourceRefactoringContributionItem extends ContributionItem
    {
        private IResourceRefactoring refactoring;
        private String label;
        private CustomUserInputPage customInputPage;
        private WorkbenchSelectionInfo selection;

        public ResourceRefactoringContributionItem(
            IResourceRefactoring refactoring,
            String label,
            CustomUserInputPage customInputPage,
            WorkbenchSelectionInfo selection)
        {
            this.refactoring = refactoring;
            this.label = label != null ? label : refactoring.getName() + "..."; //$NON-NLS-1$
            this.customInputPage = customInputPage;
            this.selection = selection;
        }

        @Override public void fill(Menu parent, int index)
        {
            MenuItem menuItem = new MenuItem(parent, SWT.NONE, index);
            menuItem.setText(label);
            menuItem.addSelectionListener(new SelectionAdapter()
            {
                @SuppressWarnings("unchecked")
                @Override public void widgetSelected(SelectionEvent e)
                {
                    refactoring.initialize(selection.getAllFilesInSelectedResources());
                    new RefactoringAction(refactoring, customInputPage).run();
                }
            });
        }
    };

    @SuppressWarnings("rawtypes")
    private static class EditorRefactoringContributionItem extends ContributionItem
    {
        private IEditorRefactoring refactoring;
        private String label;
        private CustomUserInputPage customInputPage;
        private IFile fileInEditor;
        private ITextSelection textSelection;

        public EditorRefactoringContributionItem(
            IEditorRefactoring refactoring,
            String label,
            CustomUserInputPage customInputPage,
            IFile fileInEditor,
            ITextSelection textSelection)
        {
            this.refactoring = refactoring;
            this.label = label != null ? label : refactoring.getName() + "..."; //$NON-NLS-1$
            this.customInputPage = customInputPage;
            this.fileInEditor = fileInEditor;
            this.textSelection = textSelection;
        }

        @Override public void fill(Menu parent, int index)
        {
            MenuItem menuItem = new MenuItem(parent, SWT.NONE, index);
            menuItem.setText(label);
            menuItem.addSelectionListener(new SelectionAdapter()
            {
                @SuppressWarnings("unchecked")
                @Override public void widgetSelected(SelectionEvent e)
                {
                    refactoring.initialize(fileInEditor, textSelection);
                    new RefactoringAction(refactoring, customInputPage).run();
                }
            });
        }
    }

    private static class SeparatorContributionItem extends ContributionItem
    {
        @Override public void fill(Menu parent, int index)
        {
            new MenuItem(parent, SWT.SEPARATOR, index);
        }
    };

    private static class EmptyMenuContributionItem extends ContributionItem
    {
        @Override public void fill(Menu parent, int index)
        {
            MenuItem item = new MenuItem(parent, SWT.NONE, index);
            item.setText(Messages.RefactorMenu_NoRefactoringsAvailable);
            item.setEnabled(false);
        }
    };
}
