/*
 * Copyright (c) 2015 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();
      }
    }
  }
}
