//------------------------------------------------------------------------------
// 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.library.edit.util;

import java.util.Comparator;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;


/**
 * Collection of comparators
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public final class Comparators {

	public static final Comparator DEFAULT_COMPARATOR = new Comparator() {

		public int compare(Object o1, Object o2) {
			if (o1 == o2)
				return 0;
			if (o1 instanceof MethodElement && o2 instanceof MethodElement) {
				return ((MethodElement) o1).getName().compareToIgnoreCase(
						((MethodElement) o2).getName());
			}
			Object o1unwrap = TngUtil.unwrap(o1);
			Object o2unwrap = TngUtil.unwrap(o2);
			if (o1unwrap instanceof MethodElement
					&& o2unwrap instanceof MethodElement) {
				return ((MethodElement) o1unwrap).getName()
						.compareToIgnoreCase(
								((MethodElement) o2unwrap).getName());
			}
			return 0;
		}

	};

	public static abstract class TypeComparator implements Comparator {
		protected Comparator getDefaultComparator() {
			return DEFAULT_COMPARATOR;
		}
		
		protected abstract int getOrderId(Object obj);

		public int compare(Object o1, Object o2) {
			if (o1 == o2)
				return 0;
			int ret = 0;
			ret = getOrderId((EObject) o1) - getOrderId((EObject) o2);
			if (ret == 0) {
				return getDefaultComparator().compare(o1, o2);
			}
			return ret;
		}

	}

	private static int comparePresentationName(DescribableElement e1, DescribableElement e2) {
		String name1 = e1 instanceof BreakdownElement ? ProcessUtil.getPresentationName((BreakdownElement)e1)
				: e1.getPresentationName();
		String name2 = e2 instanceof BreakdownElement ? ProcessUtil.getPresentationName((BreakdownElement)e2)
				: e2.getPresentationName();
		return name1.compareToIgnoreCase(name2);
	}

	public static final Comparator PRESENTATION_NAME_COMPARATOR = new Comparator() {
		
		public int compare(Object o1, Object o2) {
			if (o1 == o2)
				return 0;
			if(!(o1 instanceof DescribableElement)) {
				o1 = TngUtil.unwrap(o1);
				if(!(o1 instanceof DescribableElement)) {
					return 0;
				}
			}
			if(!(o2 instanceof DescribableElement)) {
				o2 = TngUtil.unwrap(o2);
				if(!(o2 instanceof DescribableElement)) {
					return 0;
				}
			}
			return comparePresentationName((DescribableElement) o1, (DescribableElement) o2);
		}

	};
	
}
