//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.gef.edit;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.epf.authoring.gef.commands.ChangeNameCommand;
import org.eclipse.epf.authoring.gef.figures.Colors;
import org.eclipse.epf.authoring.gef.figures.SelectableLabel;
import org.eclipse.epf.authoring.gef.figures.TextFigure;
import org.eclipse.epf.authoring.gef.util.TemplateConstants;
import org.eclipse.epf.diagram.model.ActivityDetailDiagram;
import org.eclipse.epf.diagram.model.ModelPackage;
import org.eclipse.epf.diagram.model.NamedNode;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.diagram.model.TaskNode;
import org.eclipse.epf.diagram.model.WorkBreakdownElementNode;
import org.eclipse.epf.diagram.model.WorkProductDescriptorNode;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.DirectEditPolicy;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.swt.graphics.Image;

import com.ibm.icu.text.BreakIterator;

/**
 * Diagram children should extend this NamedNodeEditPart in order to support name for figure.
 * NamedNodeEditPart provides instructure to handle the name wrapping and color. Support direct 
 * editing feedback.   
 *  
 * @author Phong Nguyen Le
 * @since 1.0
 */
public abstract class NamedNodeEditPart extends NodeEditPart {

	public NamedNodeEditPart(NamedNode model) {
		super(model);
	}

	protected IFigure createFigure() {
		Label l = new SelectableLabel();
		l.setLabelAlignment(PositionConstants.LEFT);
		if (getImage() != null) {
			l.setIcon(getImage());
		}
		l.setTextPlacement(PositionConstants.SOUTH);
		l.setFont(TemplateConstants.DEFAULT_FONT);
		setLabelForegroundColor(l);
		return l;
	}

	private void setLabelForegroundColor(Label l) {
		NamedNode node = (NamedNode) getModel();
		// Object e = node.getObject();
		// boolean suppressed = isSuppressed(e);
		boolean suppressed = node.isSuppressed();
		if (node.isReadOnly()) {
			if (!suppressed) {
				l.setForegroundColor(Colors.INHERITED_ELEMENT_LABEL);
			}
		} else {
			if (!suppressed) {
				l.setForegroundColor(ColorConstants.black);
			}
		}
		if (suppressed) {
			l.setForegroundColor(Colors.SUPRESSED_ELEMENT_LABEL);
		}
	}

	protected Image getImage() {
		return null;
	}

	protected void createEditPolicies() {
		super.createEditPolicies();
		if (!((Node) getModel()).isReadOnly()) {
			installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE,
					createDirectEditPolicy());
		}
	}

	protected DirectEditPolicy createDirectEditPolicy() {
		return new DirectEditPolicy() {
			protected Command getDirectEditCommand(DirectEditRequest request) {
				return new ChangeNameCommand((NamedNode) getModel(),
						(String) request.getCellEditor().getValue());
			}

			protected void showCurrentEditValue(DirectEditRequest request) {
				IFigure fig = getDirectEditFigure();
				String s = (String) request.getCellEditor().getValue();
				if (fig instanceof Label) {
					((Label) fig).setText(s);
				}
				else if (fig instanceof TextFigure) {
					((TextFigure) fig).setText(s);
				}
				fig.getUpdateManager().performUpdate();
			}
		};
	}

	protected void handlePropertyChanged(Notification msg) {
		switch (msg.getFeatureID(NamedNode.class)) {
		case ModelPackage.NAMED_NODE__NAME:
			refreshVisuals();
			return;
		}
		super.handlePropertyChanged(msg);
	}

	public void performRequest(Request request) {
		if (request.getType() == RequestConstants.REQ_DIRECT_EDIT
				&& !((Node) getModel()).isReadOnly()) {
			performDirectEdit();
		} else {
			super.performRequest(request);
		}
	}

	protected static final int WRAP_WIDTH = 12;

	protected static final int WORK_PRODUCT_WRAP_WIDTH = 3;

	protected void refreshVisuals() {
		super.refreshVisuals();
		IFigure fig = getDirectEditFigure();
		if (fig instanceof Label) {
			Label l = (Label) fig;
			setLabelForegroundColor(l);
			String text;
			// Below check is required for Extended Activity presentation name
			// should be used from base.
			if (getModel() instanceof WorkBreakdownElementNode) {
				WorkBreakdownElementNode node = (WorkBreakdownElementNode) getModel();
				Object wbelement = node.getObject();
				if (wbelement instanceof Activity
						&& ProcessUtil
								.isExtendingOrLocallyContributing((BreakdownElement) wbelement)) {
					text = ProcessUtil
							.getPresentationName((BreakdownElement) wbelement);
				} else {
					text = ((NamedNode) getModel()).getName();
				}
			} else {
				text = ((NamedNode) getModel()).getName();
			}
			try {
				if (getParent() instanceof ActivityDetailDiagramEditPart
						|| getParent().getParent() instanceof ActivityDetailDiagramEditPart) {
					int w = WRAP_WIDTH;
					if (this.getModel() instanceof WorkProductDescriptorNode)
						w = WORK_PRODUCT_WRAP_WIDTH;
					
					if(this.getModel() instanceof TaskNode && 
							GraphicalDataHelper.isAutoLayout(
							(ActivityDetailDiagram)getParent().getParent().getModel())){
						// Used 16 as min length for taskname, else add spaces to it.
						// TODO: find better solution for this.
						if(text.length() < 16){
							int gap = 16 - text.length();
							for(int i=0; i<gap/2; i++){
								text+=" ";
							}
							for(int i=0; i<gap/2; i++){
								text = " "+text;
							}
						}
					}
					text = wrap(text, w);
				}
			} catch (NullPointerException npe) {
			}
			l.setText(text);
		}
	}

	protected String wrap(String s, int wrapWidth) {
		String wrapped = ""; //$NON-NLS-1$
		BreakIterator bi = BreakIterator.getLineInstance();
		String remaining = s;
		while (true) {
			if (remaining.length() <= wrapWidth) {
				wrapped += remaining;
				break;
			} else {
				bi.setText(remaining);
				int pos = bi.following(wrapWidth);
				if (pos == BreakIterator.DONE) {
					wrapped += remaining;
					break;
				} else {
					if (pos >= remaining.length()) {
						wrapped += remaining;
						break;
					} else {
						wrapped += remaining.substring(0, pos) + "\n"; //$NON-NLS-1$
						remaining = remaining.substring(pos);
					}
				}
			}
		}
		return wrapped;
	}

}