/*
 * Copyright (c) 2010-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:
 *     Martin Fluegge - initial API and implementation
 *
 */
package org.eclipse.emf.cdo.dawn.examples.acore.provider;

import org.eclipse.emf.cdo.dawn.examples.acore.util.AcoreAdapterFactory;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.edit.provider.ChangeNotifier;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;

import java.util.ArrayList;
import java.util.Collection;

/**
 * This is the factory that is used to provide the interfaces needed to support Viewers. The adapters generated by this
 * factory convert EMF adapter notifications into calls to {@link #fireNotifyChanged fireNotifyChanged}. The adapters
 * also support Eclipse property sheets. Note that most of the adapters are shared among multiple instances. <!--
 * begin-user-doc --> <!-- end-user-doc -->
 *
 * @generated
 */
public class AcoreItemProviderAdapterFactory extends AcoreAdapterFactory
    implements ComposeableAdapterFactory, IChangeNotifier, IDisposable
{
  /**
   * This keeps track of the root adapter factory that delegates to this adapter factory. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @generated
   */
  protected ComposedAdapterFactory parentAdapterFactory;

  /**
   * This is used to implement {@link org.eclipse.emf.edit.provider.IChangeNotifier}. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @generated
   */
  protected IChangeNotifier changeNotifier = new ChangeNotifier();

  /**
   * This keeps track of all the supported types checked by {@link #isFactoryForType isFactoryForType}. <!--
   * begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected Collection<Object> supportedTypes = new ArrayList<Object>();

  /**
   * This constructs an instance. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public AcoreItemProviderAdapterFactory()
  {
    supportedTypes.add(IEditingDomainItemProvider.class);
    supportedTypes.add(IStructuredItemContentProvider.class);
    supportedTypes.add(ITreeItemContentProvider.class);
    supportedTypes.add(IItemLabelProvider.class);
    supportedTypes.add(IItemPropertySource.class);
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AClass} instances.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AClassItemProvider aClassItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AClass}. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAClassAdapter()
  {
    if (aClassItemProvider == null)
    {
      aClassItemProvider = new AClassItemProvider(this);
    }

    return aClassItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AInterface}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AInterfaceItemProvider aInterfaceItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AInterface}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAInterfaceAdapter()
  {
    if (aInterfaceItemProvider == null)
    {
      aInterfaceItemProvider = new AInterfaceItemProvider(this);
    }

    return aInterfaceItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.ACoreRoot}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected ACoreRootItemProvider aCoreRootItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.ACoreRoot}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createACoreRootAdapter()
  {
    if (aCoreRootItemProvider == null)
    {
      aCoreRootItemProvider = new ACoreRootItemProvider(this);
    }

    return aCoreRootItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AAttribute}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AAttributeItemProvider aAttributeItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AAttribute}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAAttributeAdapter()
  {
    if (aAttributeItemProvider == null)
    {
      aAttributeItemProvider = new AAttributeItemProvider(this);
    }

    return aAttributeItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AOperation}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AOperationItemProvider aOperationItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AOperation}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAOperationAdapter()
  {
    if (aOperationItemProvider == null)
    {
      aOperationItemProvider = new AOperationItemProvider(this);
    }

    return aOperationItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.ABasicClass}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected ABasicClassItemProvider aBasicClassItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.ABasicClass}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createABasicClassAdapter()
  {
    if (aBasicClassItemProvider == null)
    {
      aBasicClassItemProvider = new ABasicClassItemProvider(this);
    }

    return aBasicClassItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AParameter}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AParameterItemProvider aParameterItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AParameter}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAParameterAdapter()
  {
    if (aParameterItemProvider == null)
    {
      aParameterItemProvider = new AParameterItemProvider(this);
    }

    return aParameterItemProvider;
  }

  /**
   * This keeps track of the one adapter used for all {@link org.eclipse.emf.cdo.dawn.examples.acore.AClassChild}
   * instances. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected AClassChildItemProvider aClassChildItemProvider;

  /**
   * This creates an adapter for a {@link org.eclipse.emf.cdo.dawn.examples.acore.AClassChild}. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter createAClassChildAdapter()
  {
    if (aClassChildItemProvider == null)
    {
      aClassChildItemProvider = new AClassChildItemProvider(this);
    }

    return aClassChildItemProvider;
  }

  /**
   * This returns the root adapter factory that contains this factory. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public ComposeableAdapterFactory getRootAdapterFactory()
  {
    return parentAdapterFactory == null ? this : parentAdapterFactory.getRootAdapterFactory();
  }

  /**
   * This sets the composed adapter factory that contains this factory. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public void setParentAdapterFactory(ComposedAdapterFactory parentAdapterFactory)
  {
    this.parentAdapterFactory = parentAdapterFactory;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public boolean isFactoryForType(Object type)
  {
    return supportedTypes.contains(type) || super.isFactoryForType(type);
  }

  /**
   * This implementation substitutes the factory itself as the key for the adapter. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @generated
   */
  @Override
  public Adapter adapt(Notifier notifier, Object type)
  {
    return super.adapt(notifier, this);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Object adapt(Object object, Object type)
  {
    if (isFactoryForType(type))
    {
      Object adapter = super.adapt(object, type);
      if (!(type instanceof Class<?>) || ((Class<?>)type).isInstance(adapter))
      {
        return adapter;
      }
    }

    return null;
  }

  /**
   * This adds a listener. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public void addListener(INotifyChangedListener notifyChangedListener)
  {
    changeNotifier.addListener(notifyChangedListener);
  }

  /**
   * This removes a listener. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public void removeListener(INotifyChangedListener notifyChangedListener)
  {
    changeNotifier.removeListener(notifyChangedListener);
  }

  /**
   * This delegates to {@link #changeNotifier} and to {@link #parentAdapterFactory}. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @generated
   */
  public void fireNotifyChanged(Notification notification)
  {
    changeNotifier.fireNotifyChanged(notification);

    if (parentAdapterFactory != null)
    {
      parentAdapterFactory.fireNotifyChanged(notification);
    }
  }

  /**
   * This disposes all of the item providers created by this factory. <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public void dispose()
  {
    if (aClassItemProvider != null)
    {
      aClassItemProvider.dispose();
    }
    if (aInterfaceItemProvider != null)
    {
      aInterfaceItemProvider.dispose();
    }
    if (aCoreRootItemProvider != null)
    {
      aCoreRootItemProvider.dispose();
    }
    if (aAttributeItemProvider != null)
    {
      aAttributeItemProvider.dispose();
    }
    if (aOperationItemProvider != null)
    {
      aOperationItemProvider.dispose();
    }
    if (aBasicClassItemProvider != null)
    {
      aBasicClassItemProvider.dispose();
    }
    if (aParameterItemProvider != null)
    {
      aParameterItemProvider.dispose();
    }
    if (aClassChildItemProvider != null)
    {
      aClassChildItemProvider.dispose();
    }
  }

}
