/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  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:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
 package org.eclipse.osbp.ecview.core.common.model.binding.provider;

import java.util.Collection;
import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingPackage;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YDetailValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.util.IBoundElementItemProvider;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelFactory;

/**
 * This is the item provider adapter for a {@link org.eclipse.osbp.ecview.core.common.model.binding.YDetailValueBindingEndpoint} object.
 * <!-- begin-user-doc --> <!-- end-user-doc -->
 * @generated
 */
public class YDetailValueBindingEndpointItemProvider extends
		YValueBindingEndpointItemProvider {
	/**
	 * This constructs an instance from a factory and a notifier. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public YDetailValueBindingEndpointItemProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/**
	 * This returns the property descriptors for the adapted class. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
		if (itemPropertyDescriptors == null) {
			super.getPropertyDescriptors(object);

			addFeaturesPropertyDescriptor(object);
			addPropertyPathPropertyDescriptor(object);
			addTypePropertyDescriptor(object);
		}
		return itemPropertyDescriptors;
	}

	/**
	 * This adds a property descriptor for the Features feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addFeaturesPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_YDetailValueBindingEndpoint_features_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YDetailValueBindingEndpoint_features_feature", "_UI_YDetailValueBindingEndpoint_type"),
				 BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__FEATURES,
				 true,
				 false,
				 true,
				 null,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Property Path feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addPropertyPathPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_YDetailValueBindingEndpoint_propertyPath_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YDetailValueBindingEndpoint_propertyPath_feature", "_UI_YDetailValueBindingEndpoint_type"),
				 BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__PROPERTY_PATH,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.GENERIC_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Type feature.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	protected void addTypePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_YDetailValueBindingEndpoint_type_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YDetailValueBindingEndpoint_type_feature", "_UI_YDetailValueBindingEndpoint_type"),
				 BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__TYPE,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.GENERIC_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an
	 * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or
	 * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Collection<? extends EStructuralFeature> getChildrenFeatures(
			Object object) {
		if (childrenFeatures == null) {
			super.getChildrenFeatures(object);
			childrenFeatures.add(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE);
		}
		return childrenFeatures;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EStructuralFeature getChildFeature(Object object, Object child) {
		// Check the type of the specified child object and return the proper feature to use for
		// adding (see {@link AddCommand}) it as a child.

		return super.getChildFeature(object, child);
	}

	/**
	 * This returns YDetailValueBindingEndpoint.gif. <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	@Override
	public Object getImage(Object object) {
		return overlayImage(object,
				getResourceLocator()
						.getImage("full/obj16/YBindingEndpoint.png"));
	}

	/**
	 * This returns the label text for the adapted class. <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 */
	@Override
	public String getText(Object object) {
		YDetailValueBindingEndpoint ep = (YDetailValueBindingEndpoint) object;
		YValueBindingEndpoint masterEP = ep.getMasterObservable();

		BindingItemProviderAdapterFactory adapterFactory = (BindingItemProviderAdapterFactory) getAdapterFactory();
		IItemLabelProvider masterLabelProvider = (IItemLabelProvider) adapterFactory
				.getRootAdapterFactory().adapt(masterEP,
						IItemLabelProvider.class);
		return masterLabelProvider.getText(masterEP) + "#"
				+ ep.getPropertyPath() + getTextPrefix((YValueBindingEndpoint) object);
	}
	
	@Override
	public EObject getBoundElement(YBindingEndpoint object) {
		YDetailValueBindingEndpoint ep = (YDetailValueBindingEndpoint) object;
		YValueBindingEndpoint masterEP = ep.getMasterObservable();
		
		BindingItemProviderAdapterFactory adapterFactory = (BindingItemProviderAdapterFactory) getAdapterFactory();
		IBoundElementItemProvider masterLabelProvider = (IBoundElementItemProvider) adapterFactory
				.getRootAdapterFactory().adapt(masterEP,
						IBoundElementItemProvider.class);
		return masterLabelProvider.getBoundElement(masterEP);
	}

	/**
	 * This handles model notifications by calling {@link #updateChildren} to update any cached
	 * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @generated
	 */
	@Override
	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		switch (notification.getFeatureID(YDetailValueBindingEndpoint.class)) {
			case BindingPackage.YDETAIL_VALUE_BINDING_ENDPOINT__PROPERTY_PATH:
			case BindingPackage.YDETAIL_VALUE_BINDING_ENDPOINT__TYPE:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
				return;
			case BindingPackage.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
				return;
		}
		super.notifyChanged(notification);
	}

	/**
	 * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s
	 * describing the children that can be created under this object. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	protected void collectNewChildDescriptors(
			Collection<Object> newChildDescriptors, Object object) {
		super.collectNewChildDescriptors(newChildDescriptors, object);

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 BindingFactory.eINSTANCE.createYBeanValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 BindingFactory.eINSTANCE.createYDetailValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 BindingFactory.eINSTANCE.createYECViewModelValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 BindingFactory.eINSTANCE.createYVisibilityProcessorValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 BindingFactory.eINSTANCE.createYNoOpValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 CoreModelFactory.eINSTANCE.createYContextValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 CoreModelFactory.eINSTANCE.createYBeanSlotValueBindingEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 CoreModelFactory.eINSTANCE.createYEmbeddableValueEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 CoreModelFactory.eINSTANCE.createYEmbeddableSelectionEndpoint()));

		newChildDescriptors.add
			(createChildParameter
				(BindingPackage.Literals.YDETAIL_VALUE_BINDING_ENDPOINT__MASTER_OBSERVABLE,
				 CoreModelFactory.eINSTANCE.createYActivatedEndpoint()));
	}

}
