/**
 *                                                                            
 *  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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  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.Collections;
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.BindingPackage;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YElement;

/**
 * This is the item provider adapter for a {@link org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelListBindingEndpoint} object.
 * <!-- begin-user-doc --> <!-- end-user-doc -->
 * @generated
 */
public class YECViewModelListBindingEndpointItemProvider extends
		YListBindingEndpointItemProvider {
	/**
	 * This constructs an instance from a factory and a notifier. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public YECViewModelListBindingEndpointItemProvider(
			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);

			addElementPropertyDescriptor(object);
			addFeaturesPropertyDescriptor(object);
			addPropertyPathPropertyDescriptor(object);
			addTypePropertyDescriptor(object);
			addTypeQualifiedNamePropertyDescriptor(object);
			addEmfNsURIPropertyDescriptor(object);
		}
		return itemPropertyDescriptors;
	}

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

	/**
	 * 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_YECViewModelListBindingEndpoint_features_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YECViewModelListBindingEndpoint_features_feature", "_UI_YECViewModelListBindingEndpoint_type"),
				 BindingPackage.Literals.YEC_VIEW_MODEL_LIST_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_YECViewModelListBindingEndpoint_propertyPath_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YECViewModelListBindingEndpoint_propertyPath_feature", "_UI_YECViewModelListBindingEndpoint_type"),
				 BindingPackage.Literals.YEC_VIEW_MODEL_LIST_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_YECViewModelListBindingEndpoint_type_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_YECViewModelListBindingEndpoint_type_feature", "_UI_YECViewModelListBindingEndpoint_type"),
				 BindingPackage.Literals.YEC_VIEW_MODEL_LIST_BINDING_ENDPOINT__TYPE,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.GENERIC_VALUE_IMAGE,
				 null,
				 null));
	}

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

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

	/**
	 * This returns YECViewModelListBindingEndpoint.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) {
		YECViewModelListBindingEndpoint ep = (YECViewModelListBindingEndpoint) object;
		IItemLabelProvider rootProvider = (IItemLabelProvider) getRootAdapterFactory()
				.adapt(ep.getElement(), IItemLabelProvider.class);
		return rootProvider.getText(ep.getElement()) + "#"
				+ ep.getPropertyPath()
				+ getTextPrefix((YListBindingEndpoint) object);
	}

	@Override
	public EObject getBoundElement(YBindingEndpoint ep) {
		YECViewModelListBindingEndpoint temp = (YECViewModelListBindingEndpoint) ep;
		return temp.getElement();
	}

	@Override
	public EStructuralFeature getFirstBoundFeature(YBindingEndpoint object) {
		YECViewModelListBindingEndpoint ep = (YECViewModelListBindingEndpoint) object;
		if (!ep.getFeatures().isEmpty()) {
			return ep.getFeatures().get(0);
		}
		if (ep.getPropertyPath() != null && !ep.getPropertyPath().equals("")) {
			YElement element = (YElement) getBoundElement(object);
			if (element != null) {
				String[] tokens = ep.getPropertyPath().split("\\.");
				if (tokens.length > 0) {
					return element.eClass().getEStructuralFeature(tokens[0]);
				}
			}
		}
		return null;
	}

	@Override
	public List<EStructuralFeature> getBoundFeatureList(YBindingEndpoint object) {
		YECViewModelListBindingEndpoint ep = (YECViewModelListBindingEndpoint) object;
		if (!ep.getFeatures().isEmpty()) {
			return Collections.unmodifiableList(ep.getFeatures());
		}
		YElement element = (YElement) getBoundElement(object);
		if (element != null) {
			return resolveFeatureChain(element.eClass(), ep.getPropertyPath());
		}
		return Collections.emptyList();
	}
	
	/**
	 * 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(YECViewModelListBindingEndpoint.class)) {
			case BindingPackage.YEC_VIEW_MODEL_LIST_BINDING_ENDPOINT__PROPERTY_PATH:
			case BindingPackage.YEC_VIEW_MODEL_LIST_BINDING_ENDPOINT__TYPE:
			case BindingPackage.YEC_VIEW_MODEL_LIST_BINDING_ENDPOINT__TYPE_QUALIFIED_NAME:
			case BindingPackage.YEC_VIEW_MODEL_LIST_BINDING_ENDPOINT__EMF_NS_URI:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
				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);
	}

}
