/*
 * Copyright (c) 2009-2012 Eike Stepper (Berlin, Germany) 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.explorer.ui.checkouts.actions;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.ui.checkouts.CDOCheckoutContentProvider;
import org.eclipse.emf.cdo.explorer.ui.checkouts.wizards.NewWizard;
import org.eclipse.emf.cdo.internal.ui.actions.TransactionalBackgroundAction;
import org.eclipse.emf.cdo.internal.ui.editor.CDOEditor;
import org.eclipse.emf.cdo.internal.ui.editor.CDOEditor.NewRootMenuPopulator;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.action.CreateChildAction;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.navigator.CommonActionProvider;
import org.eclipse.ui.navigator.ICommonActionExtensionSite;
import org.eclipse.ui.navigator.ICommonMenuConstants;
import org.eclipse.ui.navigator.ICommonViewerSite;
import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
import org.eclipse.ui.navigator.WizardActionGroup;
import org.eclipse.ui.wizards.IWizardCategory;
import org.eclipse.ui.wizards.IWizardDescriptor;
import org.eclipse.ui.wizards.IWizardRegistry;

import java.util.Collection;

/**
 * @author Eike Stepper
 */
public class NewActionProvider extends CommonActionProvider implements ISelectionChangedListener
{
  private static final String NEW_MENU_NAME = "common.new.menu"; //$NON-NLS-1$

  private ICommonActionExtensionSite extensionSite;

  private CDOCheckoutContentProvider contentProvider;

  private ActionFactory.IWorkbenchAction showDlgAction;

  private WizardActionGroup newWizardActionGroup;

  private IWorkbenchPage page;

  private TreeViewer viewer;

  private Object selectedObject;

  public NewActionProvider()
  {
  }

  @Override
  public void init(ICommonActionExtensionSite extensionSite)
  {
    this.extensionSite = extensionSite;
    ICommonViewerSite viewSite = extensionSite.getViewSite();
    if (viewSite instanceof ICommonViewerWorkbenchSite)
    {
      page = ((ICommonViewerWorkbenchSite)viewSite).getPage();
      IWorkbenchWindow window = page.getWorkbenchWindow();

      showDlgAction = ActionFactory.NEW.create(window);

      CDOCheckoutContentProvider contentProvider = getContentProvider();
      IWizardRegistry wrapperRegistry = new WizardRegistryWrapper(contentProvider);

      newWizardActionGroup = new WizardActionGroup(window, wrapperRegistry, WizardActionGroup.TYPE_NEW,
          extensionSite.getContentService());

      viewer = (TreeViewer)extensionSite.getStructuredViewer();
      viewer.addSelectionChangedListener(this);
      updateSelectedObject(viewer.getSelection());
    }
  }

  @Override
  public void dispose()
  {
    if (viewer != null)
    {
      viewer.removeSelectionChangedListener(this);
    }

    if (showDlgAction != null)
    {
      showDlgAction.dispose();
      showDlgAction = null;
    }

    super.dispose();
  }

  public void selectionChanged(SelectionChangedEvent event)
  {
    ISelection selection = event.getSelection();
    updateSelectedObject(selection);
  }

  private void updateSelectedObject(ISelection selection)
  {
    if (selection instanceof IStructuredSelection)
    {
      IStructuredSelection ssel = (IStructuredSelection)selection;
      if (ssel.size() == 1)
      {
        selectedObject = ssel.getFirstElement();
        if (selectedObject instanceof CDOCheckout)
        {
          CDOCheckout checkout = (CDOCheckout)selectedObject;
          selectedObject = checkout.getRootObject();
        }

        return;
      }
    }

    selectedObject = null;
  }

  @Override
  public void fillContextMenu(IMenuManager menu)
  {
    IMenuManager submenu = new MenuManager("&New", NEW_MENU_NAME);
    if (viewer == null)
    {
      return;
    }

    CDOCheckout checkout = CDOExplorerUtil.getCheckout(selectedObject);
    if (checkout == null)
    {
      return;
    }

    // Fill the menu from the commonWizard contributions.
    newWizardActionGroup.setContext(getContext());
    newWizardActionGroup.fillContextMenu(submenu);

    // Filter out the dubious "Ecore Diagram" action that appears everywhere.
    for (IContributionItem item : submenu.getItems())
    {
      if (item instanceof ActionContributionItem)
      {
        ActionContributionItem actionItem = (ActionContributionItem)item;
        IAction action = actionItem.getAction();
        if (action != null)
        {
          if ("Ecore Diagram".equals(action.getText()))
          {
            submenu.remove(item);
            break;
          }
        }
      }
    }

    if (selectedObject instanceof CDOResource)
    {
      CDOResource resource = (CDOResource)selectedObject;
      if (!resource.isRoot())
      {
        fillNewRootActions(submenu, checkout, resource);
      }
    }
    else if (selectedObject instanceof CDOResourceNode)
    {
      // Do nothing. CDOResourceFolder contributions have already been added by newWizardActionGroup.
    }
    else if (selectedObject instanceof EObject)
    {
      fillNewChildActions(submenu, checkout, (EObject)selectedObject);
    }

    submenu.add(new Separator(ICommonMenuConstants.GROUP_ADDITIONS));

    // Add other...
    submenu.add(new Separator());
    submenu.add(showDlgAction);

    // Append the submenu after the GROUP_NEW group.
    menu.insertAfter(ICommonMenuConstants.GROUP_NEW, submenu);
  }

  private void fillNewRootActions(IMenuManager menu, final CDOCheckout checkout, final CDOResource resource)
  {
    CDOPackageRegistry packageRegistry = resource.cdoView().getSession().getPackageRegistry();
    NewRootMenuPopulator populator = new NewRootMenuPopulator(packageRegistry)
    {
      @Override
      protected IAction createAction(EObject object)
      {
        ComposedAdapterFactory adapterFactory = getAdapterFactory(checkout);

        Object image = CDOEditor.getLabelImage(adapterFactory, object);
        ImageDescriptor imageDescriptor = ExtendedImageRegistry.getInstance().getImageDescriptor(image);

        return new NewRootAction(resource, checkout, object, imageDescriptor);
      }
    };

    populator.populateMenu(menu);
  }

  private void fillNewChildActions(IMenuManager menu, CDOCheckout checkout, EObject object)
  {
    ResourceSet resourceSet = checkout.getView().getResourceSet();

    ComposedAdapterFactory adapterFactory = getAdapterFactory(checkout);

    EditingDomain editingDomain = new AdapterFactoryEditingDomain(adapterFactory, new BasicCommandStack(), resourceSet);
    IStructuredSelection selection = new StructuredSelection(object);
    CDOObject cdoObject = CDOUtil.getCDOObject(object);

    Collection<?> childDescriptors = editingDomain.getNewChildDescriptors(object, null);
    for (Object childDescriptor : childDescriptors)
    {
      CreateChildAction delegate = new CreateChildAction(editingDomain, selection, childDescriptor);
      String text = delegate.getText();
      String toolTipText = delegate.getToolTipText();
      ImageDescriptor imageDescriptor = delegate.getImageDescriptor();

      NewChildAction action = new NewChildAction(text, toolTipText, imageDescriptor, checkout, cdoObject,
          childDescriptor);
      menu.add(action);
    }
  }

  private ComposedAdapterFactory getAdapterFactory(CDOCheckout checkout)
  {
    CDOCheckoutContentProvider contentProvider = getContentProvider();
    return contentProvider.getStateManager().getState(checkout).getAdapterFactory();
  }

  private CDOCheckoutContentProvider getContentProvider()
  {
    if (contentProvider == null)
    {
      String viewerID = extensionSite.getContentService().getViewerId();
      contentProvider = CDOCheckoutContentProvider.getInstance(viewerID);
    }

    return contentProvider;
  }

  /**
   * @author Eike Stepper
   */
  private static final class WizardRegistryWrapper implements IWizardRegistry
  {
    private static final IWizardRegistry DELEGATE = PlatformUI.getWorkbench().getNewWizardRegistry();

    private final CDOCheckoutContentProvider contentProvider;

    private WizardRegistryWrapper(CDOCheckoutContentProvider contentProvider)
    {
      this.contentProvider = contentProvider;
    }

    public IWizardCategory getRootCategory()
    {
      return DELEGATE.getRootCategory();
    }

    public IWizardDescriptor[] getPrimaryWizards()
    {
      return DELEGATE.getPrimaryWizards();
    }

    public IWizardDescriptor findWizard(String id)
    {
      final IWizardDescriptor delegate = DELEGATE.findWizard(id);
      if (delegate != null)
      {
        return new WizardDescriptorWrapper(delegate, contentProvider);
      }

      return delegate;
    }

    public IWizardCategory findCategory(String id)
    {
      return DELEGATE.findCategory(id);
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class WizardDescriptorWrapper implements IWizardDescriptor
  {
    private final IWizardDescriptor delegate;

    private final CDOCheckoutContentProvider contentProvider;

    private WizardDescriptorWrapper(IWizardDescriptor delegate, CDOCheckoutContentProvider contentProvider)
    {
      this.delegate = delegate;
      this.contentProvider = contentProvider;
    }

    public String getId()
    {
      return delegate.getId();
    }

    public ImageDescriptor getImageDescriptor()
    {
      return delegate.getImageDescriptor();
    }

    public IStructuredSelection adaptedSelection(IStructuredSelection selection)
    {
      return delegate.adaptedSelection(selection);
    }

    public String getLabel()
    {
      return delegate.getLabel();
    }

    public <T> T getAdapter(Class<T> adapter)
    {
      return delegate.getAdapter(adapter);
    }

    public String getDescription()
    {
      return delegate.getDescription();
    }

    public String[] getTags()
    {
      return delegate.getTags();
    }

    public IWorkbenchWizard createWizard() throws CoreException
    {
      IWorkbenchWizard wizard = delegate.createWizard();
      if (wizard instanceof NewWizard)
      {
        NewWizard newWizard = (NewWizard)wizard;
        newWizard.setContentProvider(contentProvider);
      }

      return wizard;
    }

    public ImageDescriptor getDescriptionImage()
    {
      return delegate.getDescriptionImage();
    }

    public String getHelpHref()
    {
      return delegate.getHelpHref();
    }

    public IWizardCategory getCategory()
    {
      return delegate.getCategory();
    }

    public boolean canFinishEarly()
    {
      return delegate.canFinishEarly();
    }

    public boolean hasPages()
    {
      return delegate.hasPages();
    }
  }

  /**
   * @author Eike Stepper
   */
  private abstract class AbstractNewAction extends TransactionalBackgroundAction
  {
    private CDOCheckout checkout;

    private EObject newObject;

    public AbstractNewAction(String text, String toolTipText, ImageDescriptor image, CDOCheckout checkout,
        CDOObject parent)
    {
      super(page, text, toolTipText, image, parent);
      this.checkout = checkout;
    }

    @Override
    protected CDOTransaction openTransaction(CDOObject AbstractNewAction)
    {
      if (checkout != null)
      {
        return checkout.openTransaction();
      }

      return null;
    }

    @Override
    protected final void doRun(CDOTransaction transaction, CDOObject parent, IProgressMonitor monitor) throws Exception
    {
      ISelection selection = new StructuredSelection(CDOUtil.getEObject(parent));
      newObject = doRun(transaction, parent, selection);
    }

    protected abstract EObject doRun(CDOTransaction transaction, CDOObject parent, ISelection selection);

    @Override
    protected void postRun(CDOView view, CDOObject parent)
    {
      if (newObject != null)
      {
        EObject object = view.getObject(newObject);
        if (object != null)
        {
          CDOCheckoutContentProvider contentProvider = getContentProvider();
          if (contentProvider != null)
          {
            contentProvider.selectObjects(object);
          }
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private class NewRootAction extends AbstractNewAction
  {
    private final EObject object;

    public NewRootAction(CDOResource resource, CDOCheckout checkout, EObject object, ImageDescriptor image)
    {
      super(object.eClass().getName(), null, image, checkout, resource);
      this.object = object;
    }

    @Override
    protected EObject doRun(CDOTransaction transaction, CDOObject resource, ISelection selection)
    {
      EList<EObject> contents = ((CDOResource)resource).getContents();
      contents.add(object);
      return object;
    }
  }

  /**
   * @author Eike Stepper
   */
  private class NewChildAction extends AbstractNewAction
  {
    private final Object childDescriptor;

    public NewChildAction(String text, String toolTipText, ImageDescriptor image, CDOCheckout checkout,
        CDOObject parent, Object childDescriptor)
    {
      super(text, toolTipText, image, checkout, parent);
      this.childDescriptor = childDescriptor;
    }

    @Override
    protected EObject doRun(CDOTransaction transaction, CDOObject parent, ISelection selection)
    {
      ComposedAdapterFactory adapterFactory = CDOEditor.createAdapterFactory(true);

      try
      {
        BasicCommandStack commandStack = new BasicCommandStack();
        ResourceSet resourceSet = transaction.getResourceSet();

        EditingDomain editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, resourceSet);

        CreateChildAction delegate = new CreateChildAction(editingDomain, selection, childDescriptor);
        delegate.run();

        if (childDescriptor instanceof CommandParameter)
        {
          CommandParameter parameter = (CommandParameter)childDescriptor;
          Object value = parameter.getValue();
          if (value instanceof EObject)
          {
            return (EObject)value;
          }
        }

        return null;
      }
      finally
      {
        adapterFactory.dispose();
      }
    }
  }
}
