/******************************************************************************
 * Copyright (c) 2002, 2008 IBM Corporation 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:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.diagram.ui.actions.internal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.actions.CustomContributionItem;
import org.eclipse.gmf.runtime.diagram.ui.requests.ChangePropertyValueRequest;
import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
import org.eclipse.ui.IWorkbenchPage;

/**
 * An abstract implementation of a custom toolbar contribution item for reflecting
 * and changing properties of the selected objects in a workbench part
 * 
 * @author melaasar
 */
public abstract class PropertyChangeContributionItem
	extends CustomContributionItem {

	// id of the property this action will change
	private String propertyId = null;

	// name of the property this action will change
	private String propertyName = null;

	/**
	 * Constructs a new property change contribution item
	 * 
	 * @param partService The part service
	 * @param id The contribution id
	 * @param propertyId The property id
	 * @param propertyName The property name
	 */
	public PropertyChangeContributionItem(
		IWorkbenchPage workbenchPage,
		String id,
		String propertyId,
		String propertyName) {
		super(workbenchPage, id);
		Assert.isNotNull(propertyId);
		Assert.isNotNull(propertyName);
		setPropertyId(propertyId);
		setPropertyName(propertyName);
	}

	/**
	 * Returns the propertyId.
	 * @return - property id
	 */
	protected String getPropertyId() {
		return propertyId;
	}

	/**
	 * Sets the propertyId.
	 * @param - The propertyId to set
	 */
	protected void setPropertyId(String propertyId) {
		this.propertyId = propertyId;
	}

	/**
	 * Returns the propertyName.
	 * @return - property name
	 */
	protected String getPropertyName() {
		return propertyName;
	}

	/**
	 * Sets the propertyName.
	 * @param - The propertyName to set
	 */
	protected void setPropertyName(String string) {
		propertyName = string;
	}

	/**
	 * Creates a new target request
	 * 
	 * @return the new target request
	 */
	protected Request createTargetRequest() {
		return new ChangePropertyValueRequest(
			getPropertyName(),
			getPropertyId());
	}

	/**
	 * updates the target request. 
	 * Clients should call this method whenever the request 
	 * is expected to be changed
	 */
	protected void updateTargetRequest() {
		ChangePropertyValueRequest request =
			(ChangePropertyValueRequest) getTargetRequest();
		request.setValue(getNewPropertyValue());
	}

	/**
	 * Returns the property value of the given property id of the current operation set's
	 * 
	 * The default implementation returns the current property value of the 
	 * primary object in the operation set if not empty and <code>null</code> otherwise
	 *  
	 * @see org.eclipse.gmf.runtime.diagram.ui.internal.actions.PropertyChangeAction#getNewPropertyValue()
	 */
	protected Object getOperationSetPropertyValue(String id) {
		List set = getOperationSet();
		if (!set.isEmpty()) {
			IGraphicalEditPart primaryEditPart =
				(IGraphicalEditPart) set.get(set.size() - 1);
			return getPropertyValue(primaryEditPart, id);
		}
		return null;
	}
    
    /**
     * Returns the property value of the given property id of the current operation set's
     * 
     * The default implementation returns the current property value of the 
     * primary object in the operation set if not empty and <code>null</code> otherwise
     *  
     * @see org.eclipse.gmf.runtime.diagram.ui.internal.actions.PropertyChangeAction#getNewPropertyValue()
     */
    protected Object getOperationSetPropertyValue(String id,boolean useReadExeclusive) {
        List set = getOperationSet();
        if (!set.isEmpty()) {
            IGraphicalEditPart primaryEditPart =
                (IGraphicalEditPart) set.get(set.size() - 1);
            return getPropertyValue(primaryEditPart, id,useReadExeclusive);
        }
        return null;
    }

	/**
	 * A utility method to return the value of a given property for a given editpart
	 * 
	 * @param editPart The editpart
	 * @return The current value of the editpart's given property
	 */
	protected Object getPropertyValue(
		final IGraphicalEditPart editPart,
		final String thePropertyId) {

		try {
			return editPart.getEditingDomain().runExclusive(
				new RunnableWithResult.Impl() {

					public void run() {
						setResult(getStructuralFeatureValue(editPart, thePropertyId));
					}
				});
		} catch (InterruptedException e) {
			Trace.catching(DiagramActionsPlugin.getInstance(),
				DiagramActionsDebugOptions.EXCEPTIONS_CATCHING, getClass(),
				"getPropertyValue", e); //$NON-NLS-1$
			Log.error(DiagramActionsPlugin.getInstance(),
				DiagramActionsStatusCodes.IGNORED_EXCEPTION_WARNING,
				"getPropertyValue", e); //$NON-NLS-1$
			return null;
		}
	}
    
    /**
     * A utility method to return the value of a given property for a given editpart
     * 
     * @param  editPart The editpart
     * @param  useExclusiveRead indicates if the read process willl be run in a read execlusive 
     *         operation or not
     * @return The current value of the editpart's given property
     */
    protected Object getPropertyValue(
        final IGraphicalEditPart editPart,
        final String thePropertyId, boolean useExclusiveRead) {
        if (useExclusiveRead){
            return getPropertyValue(editPart,thePropertyId);
        }
        else {
             return getStructuralFeatureValue(editPart, thePropertyId);
        }
    }

	/**
	 * Gets the new property value (usualy from the item's control)
	 * 
	 * @return the new property value
	 */
	protected abstract Object getNewPropertyValue();

	/**
	 * @see org.eclipse.gmf.runtime.common.ui.action.AbstractContributionItem#isSelectionListener()
	 */
	protected boolean isSelectionListener() {
		return true;
	}
	
    /**
     * Override to return true to have this property action work on the shapes
     * in a <code>GroupEditPart</code> as if the shapes were multi-selected.
     * 
     * @return true if this property action is to dig into the shapes of groups
     */
    protected boolean digIntoGroups() {
        return false;
    }
    
    /**
     * Gets the structural feature value of the property id on the editpart
     * passed in or one of the children if the editpart is a group and
     * {@link #digIntoGroups()} returns true.
     * 
     * @param editpart
     *            the editpart
     * @param thePropertyId
     *            the property id
     */
    private Object getStructuralFeatureValue(IGraphicalEditPart editpart,
            final String thePropertyId) {
        ENamedElement element = PackageUtil.getElement(thePropertyId);
        if (element instanceof EStructuralFeature) {
            if (digIntoGroups() && editpart instanceof GroupEditPart) {
                editpart = (IGraphicalEditPart) editpart.getChildren().get(0);
            }
            return editpart
                .getStructuralFeatureValue((EStructuralFeature) element);
        }
        return null;
    }

    protected List getTargetEditParts(EditPart editpart) {
        if (digIntoGroups() && editpart instanceof GroupEditPart) {
            List targetEPs = new ArrayList();
            for (Iterator iterator = ((GroupEditPart) editpart)
                .getShapeChildren().iterator(); iterator.hasNext();) {
                EditPart childEP = (EditPart) iterator.next();
                targetEPs.addAll(super.getTargetEditParts(childEP));
            }
            return targetEPs;
        }
        return super.getTargetEditParts(editpart);
    }
    
    

}
