/*
 * 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;

import org.eclipse.emf.cdo.CDOElement;
import org.eclipse.emf.cdo.eresource.CDOResourceLeaf;
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.checkouts.CDOCheckoutManager;
import org.eclipse.emf.cdo.explorer.ui.ViewerUtil;
import org.eclipse.emf.cdo.explorer.ui.bundle.OM;
import org.eclipse.emf.cdo.internal.ui.editor.CDOEditor;
import org.eclipse.emf.cdo.ui.CDOEditorUtil;
import org.eclipse.emf.cdo.ui.CDOLabelDecorator;
import org.eclipse.emf.cdo.ui.CDOTreeExpansionAgent;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.ui.views.ContainerItemProvider;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider.ViewerRefresh;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;

import org.eclipse.core.commands.common.EventManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

/**
 * @author Eike Stepper
 */
public final class CDOCheckoutState
{
  private static final Image CHECKOUT_IMAGE = OM.getImage("icons/checkout.gif");

  private static final Image CHECKOUT_CLOSED_IMAGE = OM.getImage("icons/checkout_closed.gif");

  private static final Image FOLDER_IMAGE = OM.getImage("icons/CDOResourceFolder.gif");

  private static final Image ERROR_IMAGE = PlatformUI.getWorkbench().getSharedImages()
      .getImage(ISharedImages.IMG_OBJS_ERROR_TSK);

  private static final IEditorRegistry EDITOR_REGISTRY = PlatformUI.getWorkbench().getEditorRegistry();

  private final IListener checkoutManagerListener = new IListener()
  {
    public void notifyEvent(IEvent event)
    {
      if (event instanceof CDOCheckoutManager.CheckoutStateEvent)
      {
        CDOCheckoutManager.CheckoutStateEvent e = (CDOCheckoutManager.CheckoutStateEvent)event;
        if (e.getCheckout() == checkout)
        {
          CDOCheckout.State state = e.getNewState();
          if (state == CDOCheckout.State.Open)
          {
            initTreeExpansionAgent();
          }
          else if (state == CDOCheckout.State.Closed)
          {
            disposeTreeExpansionAgent();
          }
        }
      }
    }
  };

  private final EventBroker eventBroker = new EventBroker();

  private final CDOCheckoutStateManager stateManager;

  private final CDOCheckout checkout;

  private final ComposedAdapterFactory adapterFactory;

  private final ContentProvider contentProvider;

  private final LabelProvider labelProvider;

  private CDOTreeExpansionAgent treeExpansionAgent;

  CDOCheckoutState(CDOCheckoutStateManager stateManager, CDOCheckout checkout)
  {
    this.stateManager = stateManager;
    this.checkout = checkout;

    adapterFactory = CDOEditor.createAdapterFactory(true);
    ViewerRefresh viewerRefresh = stateManager.getViewerRefresh();

    CDOCheckoutContentProvider main = stateManager.getMainContentProvider();
    contentProvider = new ContentProvider(adapterFactory, viewerRefresh);
    contentProvider.inputChanged(main.getViewer(), null, main.getInput());

    ResourceManager resourceManager = stateManager.getResourceManager();
    labelProvider = new LabelProvider(adapterFactory, resourceManager);
    labelProvider.addListener(eventBroker);

    initTreeExpansionAgent();
    CDOExplorerUtil.getCheckoutManager().addListener(checkoutManagerListener);
  }

  void inputChanged(TreeViewer newTreeViewer, Object oldInput, Object newInput)
  {
    contentProvider.inputChanged(newTreeViewer, oldInput, newInput);

    if (treeExpansionAgent != null)
    {
      if (newTreeViewer != treeExpansionAgent.getViewer())
      {
        disposeTreeExpansionAgent();
      }
    }

    if (newTreeViewer != null)
    {
      initTreeExpansionAgent();
    }
  }

  public CDOCheckout getCheckout()
  {
    return checkout;
  }

  public ComposedAdapterFactory getAdapterFactory()
  {
    return adapterFactory;
  }

  public ContentProvider getContentProvider()
  {
    return contentProvider;
  }

  public LabelProvider getLabelProvider()
  {
    return labelProvider;
  }

  public void addListener(ILabelProviderListener listener)
  {
    eventBroker.addListener(listener);
  }

  public void removeListener(ILabelProviderListener listener)
  {
    eventBroker.removeListener(listener);
  }

  public void dispose()
  {
    CDOExplorerUtil.getCheckoutManager().removeListener(checkoutManagerListener);
    disposeTreeExpansionAgent();

    labelProvider.dispose();
    contentProvider.dispose();
    adapterFactory.dispose();
    eventBroker.dispose();
  }

  private void disposeTreeExpansionAgent()
  {
    if (treeExpansionAgent != null)
    {
      treeExpansionAgent.dispose();
      treeExpansionAgent = null;
    }
  }

  private void initTreeExpansionAgent()
  {
    if (treeExpansionAgent == null)
    {
      CDOView view = checkout.getView();
      if (view != null)
      {
        TreeViewer viewer = stateManager.getMainContentProvider().getViewer();
        if (viewer != null)
        {
          treeExpansionAgent = new CDOTreeExpansionAgent(view, viewer);
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class EventBroker extends EventManager implements ILabelProviderListener
  {
    public void addListener(ILabelProviderListener listener)
    {
      addListenerObject(listener);
    }

    public void removeListener(ILabelProviderListener listener)
    {
      removeListenerObject(listener);
    }

    public void labelProviderChanged(final LabelProviderChangedEvent event)
    {
      Object[] listeners = getListeners();
      for (int i = 0; i < listeners.length; ++i)
      {
        final ILabelProviderListener listener = (ILabelProviderListener)listeners[i];
        SafeRunnable.run(new SafeRunnable()
        {
          public void run()
          {
            listener.labelProviderChanged(event);
          }
        });
      }
    }

    public void dispose()
    {
      clearListeners();
    }
  }

  /**
   * @author Eike Stepper
   */
  public static final class ContentProvider extends AdapterFactoryContentProvider
  {
    public ContentProvider(AdapterFactory adapterFactory, ViewerRefresh viewerRefresh)
    {
      super(adapterFactory);
      this.viewerRefresh = viewerRefresh;
    }

    @Override
    public void notifyChanged(Notification notification)
    {
      Object notifier = notification.getNotifier();
      if (notifier instanceof EObject)
      {
        EObject eObject = (EObject)notifier;

        Object feature = notification.getFeature();
        if (feature instanceof EReference)
        {
          EReference reference = (EReference)feature;
          if (reference.isContainment())
          {
            Adapter adapter = EcoreUtil.getAdapter(eObject.eAdapters(), CDOCheckout.class);
            if (adapter instanceof CDOCheckout)
            {
              CDOCheckout checkout = (CDOCheckout)adapter;
              if (checkout.isOpen())
              {
                notification = new ViewerNotification(notification, checkout, true, true);
              }
            }
          }
        }
      }

      super.notifyChanged(notification);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static final class LabelProvider extends AdapterFactoryLabelProvider
      implements IColorProvider, IStyledLabelProvider
  {
    private final ResourceManager resourceManager;

    public LabelProvider(AdapterFactory adapterFactory, ResourceManager resourceManager)
    {
      super(adapterFactory);
      this.resourceManager = resourceManager;
    }

    @Override
    public Color getForeground(Object object)
    {
      if (object instanceof ViewerUtil.Pending)
      {
        return ContainerItemProvider.PENDING_COLOR;
      }

      return super.getForeground(object);
    }

    @Override
    public String getText(Object element)
    {
      try
      {
        if (element instanceof CDOCheckout)
        {
          CDOCheckout checkout = (CDOCheckout)element;
          return checkout.getLabel();
        }

        if (element instanceof CDOElement)
        {
          CDOElement checkoutElement = (CDOElement)element;
          return checkoutElement.toString();
        }

        if (element instanceof EObject)
        {
          CDOElement checkoutElement = (CDOElement)EcoreUtil.getExistingAdapter((Notifier)element, CDOElement.class);
          if (checkoutElement != null)
          {
            return checkoutElement.toString(element);
          }

          if (element instanceof CDOResourceNode)
          {
            CDOResourceNode resourceNode = (CDOResourceNode)element;

            String name = resourceNode.getName();
            if (name == null)
            {
              // This must be the root resource.
              return "";
            }

            return name;
          }
        }

        if (element instanceof ViewerUtil.Pending)
        {
          ViewerUtil.Pending pending = (ViewerUtil.Pending)element;
          return pending.getText();
        }

        return super.getText(element);
      }
      catch (Exception ex)
      {
        return ex.getMessage();
      }
    }

    @Override
    public Image getImage(Object element)
    {
      try
      {
        if (element instanceof CDOCheckout)
        {
          CDOCheckout checkout = (CDOCheckout)element;
          if (checkout.isOpen())
          {
            return CDOLabelDecorator.decorate(CHECKOUT_IMAGE, checkout.getRootObject());
          }

          return CHECKOUT_CLOSED_IMAGE;
        }

        if (element instanceof ViewerUtil.Pending)
        {
          return ContainerItemProvider.PENDING_IMAGE;
        }

        if (element instanceof CDOElement)
        {
          element = ((CDOElement)element).getDelegate();
          Image image = doGetImage(element);
          return CDOLabelDecorator.decorate(image, element);
        }

        return doGetImage(element);
      }
      catch (Exception ex)
      {
        return ERROR_IMAGE;
      }
    }

    private Image doGetImage(Object element)
    {
      if (element instanceof CDOResourceLeaf)
      {
        String name = ((CDOResourceLeaf)element).getName();
        if (name == null)
        {
          // This must be the root resource.
          return FOLDER_IMAGE;
        }

        IEditorDescriptor editorDescriptor = EDITOR_REGISTRY.getDefaultEditor(name);
        if (editorDescriptor != null && !CDOEditorUtil.TEXT_EDITOR_ID.equals(editorDescriptor.getId()))
        {
          Image image = getWorkbenchImage(name);
          if (image != null)
          {
            return image;
          }
        }
      }

      return super.getImage(element);
    }

    private Image getWorkbenchImage(String name)
    {
      ImageDescriptor imageDescriptor = EDITOR_REGISTRY.getImageDescriptor(name);
      if (imageDescriptor != null)
      {
        return (Image)resourceManager.get(imageDescriptor);
      }

      return null;
    }
  }
}
