//------------------------------------------------------------------------------
// 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.ui.views;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.library.configuration.ElementDependencyError;
import org.eclipse.epf.library.configuration.ErrorInfo;
import org.eclipse.epf.library.services.ElementReference;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;


/**
 * The label provider for a Configuration error or warning message.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class MessageLabelProvider extends AdapterFactoryLabelProvider {

	public MessageLabelProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getImage(java.lang.Object)
	 */
	public Image getImage(Object object) {
		boolean is_error = false;
		boolean is_warning = false;
		if (object instanceof ElementDependencyError) {
			ElementDependencyError error = (ElementDependencyError) object;
			is_error = error.isError() || error.isChildError();
			is_warning = error.isWarning() || error.isChildWarning();
		} else if ((object instanceof ErrorInfo)) {
			ErrorInfo error = (ErrorInfo) object;
			String msg = error.getErrorMessage();
			if (msg != null && msg.length() > 0) {
				is_error = error.isError() || error.isChildError();
				is_warning = error.isWarning() || error.isChildWarning();
			}
		}

		if (is_error) {
			return PlatformUI.getWorkbench().getSharedImages().getImage(
					ISharedImages.IMG_OBJS_WARN_TSK);
		} else if (is_warning) {
			return PlatformUI.getWorkbench().getSharedImages().getImage(
					ISharedImages.IMG_OBJS_WARN_TSK);
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getImageFromObject(java.lang.Object)
	 */
	protected Image getImageFromObject(Object object) {
		return ExtendedImageRegistry.getInstance().getImage(object);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnImage(java.lang.Object, int)
	 */
	public Image getColumnImage(Object object, int columnIndex) {
		if (columnIndex == 0) {
			return this.getImage(object);
		}
		return null;
	}

	private String getString(Object element) {
		if (element instanceof MethodElement) {
			return getName((MethodElement) element);
		}

		String text = element.toString();
		int index = text.indexOf("("); //$NON-NLS-1$
		int index2 = text.lastIndexOf(")"); //$NON-NLS-1$
		if (index >= 0 && index2 > 0) {
			return text.substring(index, index2 + 1);
		} else {
			return text;
		}
	}

	private String getName(MethodElement e) {
		return (e == null) ? "" : e.getName(); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnText(java.lang.Object, int)
	 */
	public String getColumnText(Object object, int columnIndex) {
		String text = ""; //$NON-NLS-1$
		MethodElement element = null;

		if (object instanceof ElementDependencyError) {
			ElementDependencyError error = (ElementDependencyError) object;
			Object e = error.getErrorElement();
			Object[] refs = error.getCauseElements();
			if (columnIndex == MessageView.ERROR_ELEMENT_COLUMN) {
				text = getString(e);

			} else if (columnIndex == MessageView.CAUSE_ELEMENT_COLUMN) {
				if (refs != null) {
					StringBuffer b = new StringBuffer();
					for (int i = 0; i < refs.length; i++) {
						if (i > 0)
							b.append(", "); //$NON-NLS-1$
						b.append(getString(refs[i]));
					}
					text = b.toString();
				}
			} else {
				if (error.isError() || error.isWarning()) {
					text = AuthoringUIResources.bind(AuthoringUIResources.MessageLabelProvider_unselectedpackages, (new String[] { getString(e) }));
				} else if (error.isChildError() || error.isChildWarning()) {
					text = AuthoringUIResources.MessageLabelProvider_errchildpkgs; 
				}
			}
		}

		if (object instanceof ErrorInfo) {
			ErrorInfo error = (ErrorInfo) object;
			if (columnIndex == MessageView.ERROR_ELEMENT_COLUMN) {
				element = (MethodElement) error.getOwnerElement();

			} else if (columnIndex == MessageView.CAUSE_ELEMENT_COLUMN) {
				element = (MethodElement) error.getCauseElement();
			}

			if (element != null) {
				text = getName(element);
				if (columnIndex != MessageView.ERROR_MESSAGE_COLUMN
						&& !LibraryUtil.selectable(element)) {
					text = "      " + text; //$NON-NLS-1$
				}
			} else {
				text = error.getErrorMessage();
			}
		}

		else if (object instanceof ElementReference) {
			ElementReference ref = (ElementReference) object;
			if (columnIndex == MessageView.ERROR_ELEMENT_COLUMN) {
				element = (MethodElement) ref.getElement();
				text = "      " + getName(element); //$NON-NLS-1$
			} else if (columnIndex == MessageView.CAUSE_ELEMENT_COLUMN) {
				element = (MethodElement) ref.getRefElement();
				text = "      " + getName(element); //$NON-NLS-1$
			}

		}

		if (text == null) {
			text = ""; //$NON-NLS-1$
		}

		return text;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getText(java.lang.Object)
	 */
	public String getText(Object object) {
		return this.getColumnText(object, 0);
	}

	/**
	 * Since we won't ever generate these notifications, we can just ignore
	 * this.
	 */
	public void addListener(ILabelProviderListener listener) {
	}

	/**
	 * Since we won't ever add listeners, we can just ignore this.
	 */
	public void removeListener(ILabelProviderListener listener) {
	}

}
