/*
 * Copyright (c) 2013, 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:
 *    Christian W. Damus (CEA LIST) - initial API and implementation
 */
package org.eclipse.emf.cdo.security.internal.ui.util;

import static org.eclipse.emf.cdo.security.internal.ui.util.SecurityUIUtil.applyTypeFilter;
import static org.eclipse.emf.cdo.security.internal.ui.util.SecurityUIUtil.getViewerFilter;

import org.eclipse.emf.cdo.security.Directory;
import org.eclipse.emf.cdo.security.Realm;
import org.eclipse.emf.cdo.security.SecurityItem;
import org.eclipse.emf.cdo.security.SecurityPackage;
import org.eclipse.emf.cdo.security.internal.ui.messages.Messages;
import org.eclipse.emf.cdo.security.internal.ui.util.ObjectExistsConverter.ObjectWritableConverter;
import org.eclipse.emf.cdo.security.provider.SecurityEditPlugin;
import org.eclipse.emf.cdo.ui.shared.SharedIcons;

import org.eclipse.net4j.util.ui.actions.SelectionListenerAction;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.IdentityCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.databinding.edit.EMFEditObservables;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.ui.celleditor.FeatureEditorDialog;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.IFilter;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * An encapsulation of a block of controls in a form that edits a one-to-many
 * reference in the security model.
 *
 * @author Christian W. Damus (CEA LIST)
 */
public class OneToManyBlock
{
  private final EditingDomain domain;

  private final AdapterFactory adapterFactory;

  private final DataBindingContext context;

  private final IObservableValue input;

  private final IOneToManyConfiguration configuration;

  private final IFilter supportedContentFilter;

  private IObservableList value;

  private TableViewer viewer;

  private INewObjectConfigurator newObjectConfigurator;

  private IActionBars editorActionBars;

  public OneToManyBlock(IManagedForm managedForm, DataBindingContext context, EditingDomain domain,
      AdapterFactory adapterFactory, EReference reference)
  {
    this(context, domain, adapterFactory, new OneToManyConfiguration(managedForm, reference));
  }

  public OneToManyBlock(IManagedForm managedForm, DataBindingContext context, EditingDomain domain,
      AdapterFactory adapterFactory, EReference reference, EClass itemType)
  {
    this(context, domain, adapterFactory, new OneToManyConfiguration(managedForm, reference, itemType));
  }

  public OneToManyBlock(DataBindingContext context, EditingDomain domain, AdapterFactory adapterFactory,
      IOneToManyConfiguration blockConfig)
  {
    this.context = context;
    this.domain = domain;
    this.adapterFactory = adapterFactory;
    configuration = blockConfig;
    input = new WritableValue(context.getValidationRealm());
    supportedContentFilter = SecurityUIUtil.getSupportedElementFilter(configuration.getItemType());
  }

  protected IOneToManyConfiguration getConfiguration()
  {
    return configuration;
  }

  protected boolean isTable()
  {
    return false;
  }

  public void setEditorActionBars(IActionBars actionBars)
  {
    editorActionBars = actionBars;
  }

  public void createControl(Composite parent, FormToolkit toolkit)
  {
    final EReference reference = getConfiguration().getModelReference();
    final EClass itemType = getConfiguration().getItemType();

    parent.setLayout(new GridLayout(2, false));

    Composite tableParent;
    TableColumnLayout tableLayout = null;
    if (isTable())
    {
      tableParent = toolkit.createComposite(parent);
      tableLayout = new TableColumnLayout();
      tableParent.setLayout(tableLayout);
    }
    else
    {
      tableParent = parent;
    }

    Table table = toolkit.createTable(tableParent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE);
    viewer = new TableViewer(table);

    if (isTable())
    {
      tableParent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
      configureColumns(viewer, tableLayout);
    }
    else
    {
      table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
      AdapterFactoryLabelProvider labels = new TableLabelProvider(adapterFactory);
      labels.setFireLabelUpdateNotifications(true); // Needed to support the data-binding input
      viewer.setLabelProvider(labels);
    }

    viewer.setContentProvider(new ObservableListContentProvider());
    SecurityUIUtil.applySupportedElementFilter(viewer, itemType);
    if (itemType != reference.getEReferenceType())
    {
      applyTypeFilter(viewer, itemType);
    }

    if (getConfiguration().getItemFilter() != null)
    {
      viewer.addFilter(getViewerFilter(getConfiguration().getItemFilter()));
    }

    viewer.setInput(value);
    hookUnsupportedModelContentValidation(value);

    if (!reference.isContainment())
    {
      configureDropSupport(viewer);
    }

    context.bindValue(WidgetProperties.enabled().observe(viewer.getControl()), input, null,
        ObjectWritableConverter.createUpdateValueStrategy());

    Composite buttons = toolkit.createComposite(parent);
    FillLayout fill = new FillLayout(SWT.VERTICAL);
    fill.spacing = 5;
    buttons.setLayout(fill);
    buttons.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));

    Button newButton = null;
    Button addButton = null;
    Button removeButton = null;

    newButton = toolkit.createButton(buttons, Messages.OneToManyBlock_0, SWT.PUSH);
    if (!reference.isContainment())
    {
      addButton = toolkit.createButton(buttons, Messages.OneToManyBlock_1, SWT.PUSH);
    }

    removeButton = toolkit.createButton(buttons, Messages.OneToManyBlock_2, SWT.PUSH);

    final IObservableValue selection = ViewersObservables.observeSingleSelection(viewer);

    context.bindValue(WidgetProperties.enabled().observe(newButton), input, null,
        ObjectWritableConverter.createUpdateValueStrategy());
    if (addButton != null)
    {
      context.bindValue(WidgetProperties.enabled().observe(addButton), input, null,
          ObjectWritableConverter.createUpdateValueStrategy());
    }

    context.bindValue(WidgetProperties.enabled().observe(removeButton), selection, null,
        ObjectWritableConverter.createUpdateValueStrategy());

    newButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        Realm realm = ((SecurityItem)input.getValue()).getRealm();

        Object owner;
        if (reference.isContainment())
        {
          owner = input.getValue();
        }
        else
        {
          owner = SecurityUIUtil.getDirectory(realm, itemType);
        }

        if (owner != null)
        {
          // Create a new object in the appropriate owner and add it to the
          // reference list if that's not the containment
          Object child = EcoreUtil.create(itemType);

          CommandParameter param;
          Command addToReference;

          if (reference.isContainment())
          {
            param = new CommandParameter(owner, reference, child);
            addToReference = IdentityCommand.INSTANCE;
          }
          else
          {
            param = new CommandParameter(owner, SecurityPackage.Literals.DIRECTORY__ITEMS, child);
            addToReference = AddCommand.create(domain, input.getValue(), reference, Collections.singleton(child));
          }

          Command command = CreateChildCommand.create(domain, owner, param, Collections.singleton(owner));
          command = command.chain(addToReference);

          if (getNewObjectConfigurator() != null)
          {
            command = command.chain(getNewObjectConfigurator().createConfigureCommand(child));
          }

          if (execute(command))
          {
            viewer.setSelection(new StructuredSelection(child));
            viewer.getControl().setFocus();
            viewer.refresh(child);
          }
        }
      }
    });

    if (addButton != null)
    {
      addButton.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
        {
          Realm realm = ((SecurityItem)input.getValue()).getRealm();
          Directory directory = SecurityUIUtil.getDirectory(realm, itemType);
          if (directory != null)
          {
            // Get the available items not already in our input's reference list
            List<?> available = new ArrayList<Object>(EcoreUtil.getObjectsByType(directory.getItems(), itemType));
            available.removeAll(value);
            SecurityUIUtil.applySupportedElementFilter(available, itemType);

            String label = NLS.bind(Messages.OneToManyBlock_3, SecurityEditPlugin.INSTANCE.getString(
                String.format("_UI_%s_%s_feature", reference.getEContainingClass().getName(), reference.getName()))); //$NON-NLS-1$

            FeatureEditorDialog dlg = new FeatureEditorDialog(viewer.getControl().getShell(),
                new TableLabelProvider(adapterFactory), input.getValue(), reference.getEContainingClass(),
                Collections.EMPTY_LIST, label, available, false, true, true);

            if (dlg.open() == Window.OK && !dlg.getResult().isEmpty())
            {
              Command command = AddCommand.create(domain, input.getValue(), reference, dlg.getResult());
              if (execute(command))
              {
                viewer.setSelection(new StructuredSelection(dlg.getResult()));
                viewer.getControl().setFocus();
              }
            }
          }
        }
      });
    }

    final SelectionListenerAction<EObject> removeAction = new SelectionListenerAction<EObject>(
        Messages.OneToManyBlock_2, SharedIcons.getDescriptor("etool16/delete.gif")) //$NON-NLS-1$
    {
      @Override
      public void run()
      {
        Object selected = selection.getValue();
        if (selected != null)
        {
          Command command;

          if (reference.isContainment())
          {
            command = DeleteCommand.create(domain, selection.getValue());
          }
          else
          {
            command = RemoveCommand.create(domain, input.getValue(), reference, selection.getValue());
          }

          execute(command);
        }
      }

      @Override
      protected boolean updateSelection(IStructuredSelection selection)
      {
        return super.updateSelection(selection) && SecurityUIUtil.isEditable(input.getValue());
      }

      @Override
      protected Class<EObject> getType()
      {
        return EObject.class;
      }
    };

    removeButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        if (removeAction.isEnabled())
        {
          removeAction.run();
        }
      }
    });

    viewer.addSelectionChangedListener(removeAction);

    new ActionBarsHelper(editorActionBars).addGlobalAction(ActionFactory.DELETE.getId(), removeAction).install(viewer);
  }

  public void setInput(IObservableValue input)
  {
    if (input != null)
    {
      Observables.pipe(input, this.input);
    }

    if (value != null)
    {
      if (viewer != null)
      {
        viewer.setInput(null);
      }

      value.dispose();
    }

    value = EMFEditObservables.observeDetailList(context.getValidationRealm(), domain, input,
        getConfiguration().getModelReference());

    if (viewer != null)
    {
      viewer.setInput(value);
      hookUnsupportedModelContentValidation(value);
    }
  }

  protected boolean execute(Command command)
  {
    boolean result = command.canExecute();

    if (result)
    {
      domain.getCommandStack().execute(command);
    }

    return result;
  }

  public void setNewObjectConfigurator(INewObjectConfigurator newObjectConfigurator)
  {
    this.newObjectConfigurator = newObjectConfigurator;
  }

  public INewObjectConfigurator getNewObjectConfigurator()
  {
    return newObjectConfigurator;
  }

  protected void configureColumns(TableViewer viewer, TableColumnLayout layout)
  {
    // Pass
  }

  private boolean canPresent(Object object)
  {
    IOneToManyConfiguration config = getConfiguration();
    boolean result = config.getItemType().isInstance(object);

    if (result && config.getItemFilter() != null)
    {
      result = config.getItemFilter().select(object);
    }

    if (result)
    {
      // Last check: cannot drop something from a different editing domain
      result = AdapterFactoryEditingDomain.getEditingDomainFor(object) == domain;
    }

    return result;
  }

  private boolean canPresentAll(ISelection selection)
  {
    boolean result = selection != null && !selection.isEmpty();

    if (result && selection instanceof IStructuredSelection)
    {
      for (Iterator<?> iter = ((IStructuredSelection)selection).iterator(); result && iter.hasNext();)
      {
        result = canPresent(iter.next());
      }
    }

    return result;
  }

  protected void configureDropSupport(final TableViewer viewer)
  {
    viewer.addDropSupport(DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY,
        new Transfer[] { LocalSelectionTransfer.getTransfer() }, new DropTargetAdapter()
        {
          @Override
          public void dragEnter(DropTargetEvent event)
          {
            if (!canDrop(event))
            {
              // Reject this drop
              event.detail = DND.DROP_NONE;
            }
            else if ((event.operations | DND.DROP_COPY) != 0)
            {
              event.detail = DND.DROP_COPY;
            }
          }

          private boolean canDrop(DropTargetEvent event)
          {
            boolean result = false;

            if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType))
            {
              result = canPresentAll(LocalSelectionTransfer.getTransfer().getSelection());
            }

            return result;
          }

          @Override
          public void dropAccept(DropTargetEvent event)
          {
            if (!canDrop(event))
            {
              // Reject this drop
              event.detail = DND.DROP_NONE;
            }
            else if ((event.operations | DND.DROP_COPY) != 0)
            {
              event.detail = DND.DROP_COPY;
            }
          }

          @Override
          public void drop(DropTargetEvent event)
          {
            if (canDrop(event))
            {
              IStructuredSelection selection = (IStructuredSelection)LocalSelectionTransfer.getTransfer()
                  .getSelection();
              Command command = AddCommand.create(domain, input.getValue(), getConfiguration().getModelReference(),
                  selection.toList());
              if (execute(command))
              {
                viewer.setSelection(selection);
                viewer.getControl().setFocus();
              }
            }
          }
        });
  }

  protected void hookUnsupportedModelContentValidation(IObservableList observableList)
  {
    // No need to hook a listener if there is no supported-content filter to check
    if (observableList != null && supportedContentFilter != null)
    {
      observableList.addChangeListener(new IChangeListener()
      {

        public void handleChange(ChangeEvent event)
        {
          checkUnsupportedModelContent((IObservableList)event.getObservable());
        }
      });

      // Initialize the validation state
      checkUnsupportedModelContent(observableList);
    }
  }

  protected void checkUnsupportedModelContent(IObservableList observableList)
  {
    // Anything not matching the supported-content filter?
    for (Object element : observableList)
    {
      if (!supportedContentFilter.select(element))
      {
        configuration.getManagedForm().getMessageManager().addMessage(this, Messages.TableSection_3, null,
            IStatus.WARNING, viewer.getControl());
        return;
      }
    }

    configuration.getManagedForm().getMessageManager().removeMessage(this, viewer.getControl());
  }

  /**
   * Specification of the configuration of a one-to-many block's contents.
   *
   * @author Christian W. Damus (CEA LIST)
   */
  public static interface IOneToManyConfiguration
  {
    public IManagedForm getManagedForm();

    public EReference getModelReference();

    public EClass getItemType();

    public IFilter getItemFilter();
  }

  /**
   * Default one-to-many block configuration implementation.
   *
   * @author Christian W. Damus (CEA LIST)
   */
  public static class OneToManyConfiguration implements IOneToManyConfiguration
  {
    private final IManagedForm managedForm;

    private final EReference reference;

    private final EClass itemType;

    private final IFilter filter;

    public OneToManyConfiguration(IManagedForm managedForm, EReference reference)
    {
      this(managedForm, reference, reference.getEReferenceType(),
          SecurityUIUtil.getSupportedElementFilter(reference.getEReferenceType()));
    }

    public OneToManyConfiguration(IManagedForm managedForm, EReference reference, EClass itemType)
    {
      this(managedForm, reference, itemType, SecurityUIUtil.getSupportedElementFilter(itemType));
    }

    public OneToManyConfiguration(IManagedForm managedForm, EReference reference, IFilter filter)
    {
      this(managedForm, reference, reference.getEReferenceType(), filter);
    }

    public OneToManyConfiguration(IManagedForm managedForm, EReference reference, EClass itemType, IFilter filter)
    {
      this.managedForm = managedForm;
      this.reference = reference;
      this.itemType = itemType;
      this.filter = filter;
    }

    public IManagedForm getManagedForm()
    {
      return managedForm;
    }

    public EReference getModelReference()
    {
      return reference;
    }

    public EClass getItemType()
    {
      return itemType;
    }

    public IFilter getItemFilter()
    {
      return filter;
    }
  }
}
