//------------------------------------------------------------------------------
// 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 java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.epf.library.configuration.ConfigurationClosure;
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.services.PackageDependency;
import org.eclipse.epf.library.services.PackageReference;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

/**
 * The content provider for a Configuration error or warning message.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class MessageContentProvider implements ITreeContentProvider {

	private ConfigurationClosure closure;

	public MessageContentProvider(ConfigurationClosure closure) {
		this.closure = closure;
	}

	public Object[] getElements(Object inputElement) {
		if (closure == null) {
			return new Object[0];
		}

		if (inputElement instanceof ConfigurationClosure) {
			return ((ConfigurationClosure) inputElement).getDependencyErrors();
		} else if (inputElement instanceof ElementDependencyError) {
			List errors = ((ElementDependencyError) inputElement).getAll();
			if (errors != null) {
				return errors.toArray();
			}
			return null;
		} else if (inputElement instanceof ErrorInfo) {
			ErrorInfo info = (ErrorInfo) inputElement;
			int relation = info.getRelation();
			MethodElement ownerElement = (MethodElement) info.getOwnerElement();
			MethodElement causeElement = (MethodElement) info.getCauseElement();
			PackageDependency dep;
			PackageReference pkgRef = null;

			if (relation == ErrorInfo.REFERENCE_TO) {
				dep = closure.getConfigurationManager().getDependencyManager()
						.getDependency(ownerElement);
				pkgRef = dep.getReference(causeElement, false);
			} else if (relation == ErrorInfo.REFERENCED_BY) {
				dep = closure.getConfigurationManager().getDependencyManager()
						.getDependency(causeElement);
				pkgRef = dep.getReference(ownerElement, false);
			}

			if (pkgRef != null) {
				List refErrors = new ArrayList();
				for (Iterator it = pkgRef.getReferences().iterator(); it
						.hasNext();) {
					ElementReference ref = (ElementReference) it.next();

					// Don't show the entry if the reference can be ignored.
					if (ref.canIgnore()) {
						continue;
					}
					ErrorInfo elementError;
					if (relation == ErrorInfo.REFERENCE_TO) {
						elementError = new ErrorInfo(
								info.getErrorType(),
								"", ref.getElement(), ref.getRefElement(), relation); //$NON-NLS-1$
					} else {
						elementError = new ErrorInfo(
								info.getErrorType(),
								"", ref.getRefElement(), ref.getElement(), relation); //$NON-NLS-1$
					}

					refErrors.add(elementError);
				}

				return refErrors.toArray();
			}

		}

		return new Object[] {};
	}

	public void dispose() {

	}

	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
	}

	public Object[] getChildren(Object parentElement) {
		return getElements(parentElement);
	}

	public Object getParent(Object element) {
		if (element instanceof ConfigurationClosure) {
			return null;
		} else if (element instanceof ErrorInfo) {
			return this.closure;
		} else {
			return null;
		}
	}

	public boolean hasChildren(Object element) {
		if (element instanceof ConfigurationClosure) {
			return true;
		} else if (element instanceof ElementDependencyError) {
			return ((ElementDependencyError) element).size() > 0;
		} else if (element instanceof ErrorInfo) {
			if (((ErrorInfo) element).getErrorMessage().length() > 0) {
				return true;
			}
		}
		return false;
	}

}
