/*******************************************************************************
 *  Copyright (c) 2012-2014 SAP SE.
 *  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:
 *  SAP SE - initial API and implementation and/or initial documentation
 *
 *******************************************************************************/
package org.eclipse.ogee.designer.features;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IDeleteContext;
import org.eclipse.graphiti.features.context.IMultiDeleteInfo;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ogee.designer.Activator;
import org.eclipse.ogee.designer.contexts.LinkUsageContext;
import org.eclipse.ogee.designer.messages.Messages;
import org.eclipse.ogee.designer.providers.ODataFeatureProvider;
import org.eclipse.ogee.designer.utils.ArtifactUtil;
import org.eclipse.ogee.designer.utils.IODataEditorConstants;
import org.eclipse.ogee.designer.utils.ODataArtifactSelectionUtil;
import org.eclipse.ogee.designer.utils.ODataLayoutUtil;
import org.eclipse.ogee.designer.utils.ODataShapeUtil;
import org.eclipse.ogee.designer.utils.PropertyUtil;
import org.eclipse.ogee.model.odata.Annotation;
import org.eclipse.ogee.model.odata.Association;
import org.eclipse.ogee.model.odata.ComplexTypeUsage;
import org.eclipse.ogee.model.odata.EntityContainer;
import org.eclipse.ogee.model.odata.EntityType;
import org.eclipse.ogee.model.odata.EnumTypeUsage;
import org.eclipse.ogee.model.odata.IAnnotationTarget;
import org.eclipse.ogee.model.odata.Parameter;
import org.eclipse.ogee.model.odata.Property;
import org.eclipse.ogee.utils.logger.Logger;
import org.eclipse.ui.PlatformUI;

/**
 * Default delete feature is extended in order provided custom delete messages
 * and to support for linked artifact delete.
 * 
 */
public class ODataDeleteFeature extends DefaultDeleteFeature {

	/**
	 * String constant for DOT
	 */
	private static final String DOT = "."; //$NON-NLS-1$

	/**
	 * Entity Type Pictogram element.
	 */
	private PictogramElement mainPictogramElement;

	/**
	 * Rectangle (Properties/EntitySets/Navigation Properties)
	 */
	private PictogramElement parentPE;

	private int deleteItemIndex;

	/**
	 * Parent Object
	 */
	private EObject deletableParentObject;
	/**
	 * Feature provider
	 */
	public IFeatureProvider fp;

	private EObject affectedShowUsageObj;

	/**
	 * @param fp
	 */
	public ODataDeleteFeature(IFeatureProvider fp) {
		super(fp);
		this.fp = fp;
	}

	@Override
	public String getDescription() {
		return Messages.DEFAULTDELETEFEATURE_DEFAULT_MESSAGE;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.graphiti.ui.features.DefaultDeleteFeature#preDelete(org.eclipse
	 * .graphiti.features.context.IDeleteContext)
	 */
	/**
	 * Deletes EntitySet and Associations on Entity Delete.
	 * 
	 * Deletes AssociationSet and Navigation Properties ON ASSOCIATION Delete.
	 * 
	 */
	@Override
	public void preDelete(IDeleteContext context) {

		this.mainPictogramElement = null;
		this.parentPE = null;
		this.deletableParentObject = null;
		PictogramElement pe = context.getPictogramElement();
		if (PropertyUtil.isTypeIdentifier(pe)) {
			EObject parentContainer = pe.eContainer();
			if (parentContainer instanceof PictogramElement
					&& PropertyUtil
							.isInvisibleRectangle((PictogramElement) parentContainer)) {
				EObject mainContainer = parentContainer.eContainer();
				if (mainContainer instanceof PictogramElement
						&& PropertyUtil
								.isTopContainer((PictogramElement) mainContainer)) {
					this.mainPictogramElement = (PictogramElement) mainContainer;

					this.parentPE = ((PictogramElement) parentContainer);
					this.deleteItemIndex = ((ContainerShape) this.parentPE)
							.getChildren().indexOf(pe);
				}
			}

		}

		// Get the object which is selected
		Object currentObject = getBusinessObjectForPictogramElement(context
				.getPictogramElement());
		if (currentObject != null) {

			if (ArtifactUtil.isEntityType(currentObject)) {
				ODataShapeUtil.deleteEntity(context.getPictogramElement(),
						getFeatureProvider());
			} else if (ArtifactUtil.isAssociation(currentObject)) {
				ODataShapeUtil.deleteAssociation(currentObject,
						getFeatureProvider());
			} else if (ArtifactUtil.isComplexTypeProperty(currentObject)) {

				Property delCmplxProp = (Property) currentObject;
				ComplexTypeUsage propertyUsage = (ComplexTypeUsage) delCmplxProp
						.getType();
				affectedShowUsageObj = propertyUsage.getComplexType();

			} else if (ArtifactUtil.isEnumTypeProperty(currentObject)) {

				Property delEnumProp = (Property) currentObject;
				EnumTypeUsage propertyUsage = (EnumTypeUsage) delEnumProp
						.getType();
				affectedShowUsageObj = propertyUsage.getEnumType();

			} else if (ArtifactUtil.isFunctionImportReturnType(currentObject)) {

				affectedShowUsageObj = ArtifactUtil
						.getObjectFromTypeUsage((EObject) currentObject);

			} else if (ArtifactUtil.isParameter(currentObject)) {

				Parameter delProp = (Parameter) currentObject;
				EObject propType = delProp.getType();
				affectedShowUsageObj = ArtifactUtil
						.getObjectFromTypeUsage(propType);

			}

			EObject parentObject = ((EObject) currentObject).eContainer();
			if (parentObject instanceof EntityContainer) {
				this.deletableParentObject = parentObject;
			}
			// this is to update referred PictogramElements.
			ODataShapeUtil.updateReferedShapes((EObject) currentObject,
					getFeatureProvider(), true);
			// this is to update referred PictogramElements.
			EObject businessObject = (EObject) currentObject;
			ODataArtifactSelectionUtil.notifyRegisteredSubscribers(context
						.getPictogramElement(), businessObject , ODataArtifactSelectionUtil.SelectionStatus.DELETED);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.graphiti.ui.features.DefaultDeleteFeature#postDelete(org.
	 * eclipse.graphiti.features.context.IDeleteContext)
	 */
	/**
	 * updates the layout in case EntitySet, Property and Navigation Property
	 * delete.
	 */
	@Override
	public void postDelete(IDeleteContext context) {
		// default entity container shouldn't be deleted
		/*
		 * if (this.deletableParentObject instanceof EntityContainer) {
		 * deleteParentObject(); }
		 */

		if (this.mainPictogramElement != null) {
			if (this.parentPE != null) {
				ODataLayoutUtil
						.updateContainerHeightsOnDelete((ContainerShape) this.parentPE);
				ODataShapeUtil.updateSelOnDelete(getFeatureProvider(),
						this.mainPictogramElement, this.parentPE,
						this.deleteItemIndex);

			}
			ODataShapeUtil.layoutPictogramElement(this.mainPictogramElement,
					getFeatureProvider());

		}

		if (affectedShowUsageObj != null) {

			ODataShapeUtil.updateShowUsageLinks(this.fp, null,
					affectedShowUsageObj);
		}

	}

	/**
	 * This method is responsible to delete the Object which do not have
	 * children. This is called only for EntityContainer Object.
	 */
	private void deleteParentObject() {
		EList<EReference> eReferences = this.deletableParentObject.eClass()
				.getEReferences();
		boolean noChildren = true;
		for (EReference eReference : eReferences) {
			if (eReference.isContainment() && eReference.isMany()) {
				Object childElements = this.deletableParentObject
						.eGet(eReference);
				if (childElements instanceof List
						&& ((List<?>) childElements).size() > 0) {
					noChildren = false;
					break;
				}
			}
		}

		if (noChildren) {
			deleteBusinessObject(this.deletableParentObject);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.graphiti.ui.features.DefaultDeleteFeature#getDeleteName(org
	 * .eclipse.graphiti.features.context.IDeleteContext)
	 */
	@Override
	protected String getDeleteName(IDeleteContext context) {
		PictogramElement pe = context.getPictogramElement();
		Object ObjectForPE = getBusinessObjectForPictogramElement(pe);
		if (ObjectForPE instanceof EObject) {
			EObject businessObject = (EObject) ObjectForPE;
			String className = businessObject.eClass().getInstanceTypeName();
			if (className != null) {
				String totalName = className;
				StringTokenizer st = new StringTokenizer(totalName, DOT);
				while (st.hasMoreElements()) {
					className = (String) st.nextElement();
				}
				return className;

			}
		}

		return super.getDeleteName(context);
	}

	/**
	 * Shows a dialog which asks the user to confirm the deletion of one or more
	 * elements.
	 * 
	 * @param context
	 *            delete context
	 * @return <code>true</code> to delete element(s); <code>false</code> to
	 *         cancel delete
	 */
	@Override
	protected boolean getUserDecision(IDeleteContext context) {
		String msg;
		IMultiDeleteInfo multiDeleteInfo = context.getMultiDeleteInfo();
		if (multiDeleteInfo != null) {
			msg = MessageFormat.format(Messages.DEFAULTDELETEFEATURE_2_XMSG,
					Integer.valueOf(multiDeleteInfo.getNumber()));
		} else {

			PictogramElement pe = context.getPictogramElement();
			Object ObjectForPE = getBusinessObjectForPictogramElement(pe);

			msg = ObjectForPE != null ? ArtifactUtil
					.getDeleteMessage(ObjectForPE) : null;

			if (msg == null) {
				String deleteName = getDeleteName(context);
				if (deleteName != null && deleteName.length() > 0) {
					msg = MessageFormat.format(
							Messages.DEFAULTDELETEFEATURE_3_XMSG, deleteName);
				} else {
					msg = Messages.DEFAULTDELETEFEATURE_4_XMSG;
				}
			}

		}
		return MessageDialog.openQuestion(PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow().getShell(),
				Messages.DEFAULTDELETEFEATURE_5_XFLD, msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.graphiti.ui.features.DefaultDeleteFeature#canDelete(org.eclipse
	 * .graphiti.features.context.IDeleteContext)
	 */
	@Override
	public boolean canDelete(IDeleteContext context) {
		boolean canDelete = false;
		if (context instanceof LinkUsageContext) {
			LinkUsageContext lc = (LinkUsageContext) context;
			if (lc.isDeletable()) {
				canDelete = true;
			}
		} else if (this.fp instanceof ODataFeatureProvider
				&& ((ODataFeatureProvider) this.fp).isReadOnlyModel()) {
			canDelete = false;
		} else if (!PropertyUtil.isDeletableShape(context)
				|| PropertyUtil.isLinkConnection(context.getPictogramElement())) {
			canDelete = false;
		} else {
			canDelete = super.canDelete(context);
		}

		return canDelete;
	}

	/**
	 * Overridden for referenced entity types where we don't need to delete the
	 * original business object.
	 * 
	 * @see org.eclipse.graphiti.ui.features.DefaultDeleteFeature#deleteBusinessObject(java.lang.Object)
	 */
	@Override
	protected void deleteBusinessObject(Object bo) {
		// Should not delete the business object
		// if this is a referenced entity or
		// which does not have referenced edmx set
		PictogramElement pe = getFeatureProvider()
				.getPictogramElementForBusinessObject(bo);
			final IMarker[] markers = this.findMarkers((EObject)bo);
			if (!(markers.length == 0)) {
				for (int i = 0; i < markers.length; i++) {
					String markerSourceId = null;
					try {
						markerSourceId = (String) markers[i]
								.getAttribute(IMarker.SOURCE_ID);
					} catch (CoreException e) {
						// Nothing to log
					}
					if (this.isValidMarker((EObject)bo, markerSourceId, pe)){
						try {
							markers[i].delete();
						} catch (CoreException e) {
							//Nothing to log
						}
					}
				}
			}
			
		if (bo instanceof EntityType) {
			try {
				if (ArtifactUtil.isReferencedEntityType(bo)) {
					return;
				}
			} catch (NullPointerException e) {
				return;
			}
		}

		deleteAnnotations(bo);

		super.deleteBusinessObject(bo);

	}

	/**
	 * this method is responsible to delete the annotations.
	 * 
	 * @param bo
	 */
	private void deleteAnnotations(Object bo) {
		// Added code to delete the annotations
		List<EObject> collection = new ArrayList<EObject>();
		collection.add((EObject) bo);
		TreeIterator<Object> allContents = EcoreUtil.getAllContents(collection);
		while (allContents.hasNext()) {
			Object object = allContents.next();
			// Added code to delete the annotations
			if (object instanceof IAnnotationTarget) {
				EList<Annotation> annotations = ((IAnnotationTarget) object)
						.getAnnotations();
				List<Annotation> tempList = new ArrayList<Annotation>();
				tempList.addAll(annotations);
				for (Annotation annotation : tempList) {
					super.deleteBusinessObject(annotation);
				}
			}
		}
	}
	
	private IMarker[] findMarkers(final EObject o) {

		IMarker[] markers = null;

		final IResource resource = ResourcesPlugin.getWorkspace().getRoot()
				.findMember(o.eResource().getURI().toPlatformString(true));
		try {
			markers = resource.findMarkers(
					IODataEditorConstants.PROBLEM_MARKER_ID, true,
					IResource.DEPTH_INFINITE);
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
			e.printStackTrace();
		}

		return markers;
	}
	
	private boolean isValidMarker(final EObject pictogramObj,
			final String markerSourceId, final PictogramElement pe) {

		boolean isValidMarker = false;

		final URI uri = URI.createURI(markerSourceId);
		final EObject markerObj = pictogramObj.eResource().getResourceSet()
				.getEObject(uri, true);
		// get the selectable domain object for the current marker
		final EObject selectableMarkerObj = ArtifactUtil
				.getSelectableObject(markerObj);
		// For domain object Association do not check for isTypeIdentifier.
		if (selectableMarkerObj instanceof Association) {
			isValidMarker = pictogramObj.equals(selectableMarkerObj)
					&& !(PropertyUtil.isTitle(pe));
		} else {
			isValidMarker = pictogramObj.equals(selectableMarkerObj);
		}

		return isValidMarker;
	}

}
