//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.PresentationContext;
import org.eclipse.epf.library.edit.util.model.OrderInfo;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProductType;

/**
 * Helper class to handle sorting of Category elements
 * @author Jeff Hardy
 *
 */
public class CategorySortHelper {
	
	public static final String KEY_CATEGORY_ELEMENTS__SORT_TYPE = "CategoryElementsSortType"; //$NON-NLS-1$
	public static final String V_CATEGORY_ELEMENTS__SORT_TYPE_ALPHA = "Alphabetic"; //$NON-NLS-1$
	public static final String V_CATEGORY_ELEMENTS__SORT_TYPE_REVERSE_ALPHA = "ReverseAlphabetic"; //$NON-NLS-1$
	public static final String V_CATEGORY_ELEMENTS__SORT_TYPE_METHOD_TYPE = "MethodType"; //$NON-NLS-1$
	public static final String V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL = "Manual"; //$NON-NLS-1$

	/**
	 * Creates a new MethodElementProperty to store the Category sort type
	 * @param sortType
	 * @return
	 */
	public static MethodElementProperty createNewSortProperty(String sortType) {
		MethodElementProperty prop = UmaFactory.eINSTANCE.createMethodElementProperty();
		prop.setName(KEY_CATEGORY_ELEMENTS__SORT_TYPE);
		if (sortType != null) {
			prop.setValue(sortType);
		}
		return prop;
	}
	
	/**
	 * Return category sort property for method element
	 * @param element
	 * @return
	 * 		 property if found, else null
	 */
	public static MethodElementProperty getCategorySortProperty(MethodElement element) {
		List props = element.getMethodElementProperty();
		for (Iterator it = props.iterator(); it.hasNext();) {
			MethodElementProperty prop = (MethodElementProperty) it.next();
			if (KEY_CATEGORY_ELEMENTS__SORT_TYPE.equals(prop.getName())) {
				return prop;
			}
		}
		return null;
	}
	
	/**
	 * return true iff the category sort-type is set to manual
	 * @param element
	 * @return
	 * 		 property if found, else null
	 */
	public static boolean isManualCategorySort(MethodElement element) {
		String sortType = getCategorySortValue(element);
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL.equals(sortType))
			return true;
		return false;
	}

	/**
	 * Returns the sort-type for the given MethodElement.
	 * If none is set, will return Alphabetic sort (V_CATEGORY_ELEMENTS__SORT_TYPE_ALPHA) as a default
	 * @param element
	 * @return
	 */
	public static String getCategorySortValue(MethodElement element) {
		MethodElementProperty prop = getCategorySortProperty(element);
		if (prop == null)
			return V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL;
		return prop.getValue();
	}

	public static List<String> getCategorySortTypes() {
		List<String> returnList = Arrays.<String>asList(
				V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL,
				V_CATEGORY_ELEMENTS__SORT_TYPE_ALPHA,
				V_CATEGORY_ELEMENTS__SORT_TYPE_REVERSE_ALPHA,
				V_CATEGORY_ELEMENTS__SORT_TYPE_METHOD_TYPE);
		return returnList;
	}

	public static String getSortTypeDisplayName(String sortType) {
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_ALPHA.equals(sortType)) {
			return LibraryEditResources.SortType_Alphabetic;
		}
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_REVERSE_ALPHA.equals(sortType)) {
			return LibraryEditResources.SortType_ReverseAlphabetic;
		}
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_METHOD_TYPE.equals(sortType)) {
			return LibraryEditResources.SortType_MethodType;
		}
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL.equals(sortType)) {
			return LibraryEditResources.SortType_Manual;
		}
		return ""; //$NON-NLS-1$
	}
	
	/**
	 * Returns a sorted category element list based on the category's sort type
	 * Respects the Name/PresName toggle
	 * @param element 
	 * @param elements array to sort
	 * @return
	 */
	public static List<Object> sortCategoryElements(MethodElement element, Object[] elements) {
		return sortCategoryElements(element, elements, false);
	}

	/**
	 * Returns a sorted category element list based on the category's sort type
	 * @param element 
	 * @param elements array to sort
	 * @param forcePresNameSort true to always sort by presName. false will respect the toggle
	 * @return
	 */
	public static List<Object> sortCategoryElements(MethodElement element, Object[] elements, boolean forcePresNameSort) {
		/*
		 * TODO: can't use generics here because EMF doesn't use them yet - the elements param
		 * usually comes from ContentElementsOrderList class which extends EMF's BasicEList and so
		 * the toArray() method will only return Object[]
		 */
		List<Object> returnList = new ArrayList<Object>(Arrays.<Object>asList(elements));
		String sortType = getCategorySortValue(element);
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL.equals(sortType)) {
			if (element instanceof ContentCategory) {
				return findManualSortOrderInContributors((ContentCategory)element, returnList);
			}
			return returnList;
		} else if (V_CATEGORY_ELEMENTS__SORT_TYPE_ALPHA.equals(sortType)) {
			Comparator comparator = PresentationContext.INSTANCE.getComparator();
			if (forcePresNameSort)
				comparator = PresentationContext.INSTANCE.getPresNameComparator();
			Collections.<Object>sort(returnList, comparator);
		} else if (V_CATEGORY_ELEMENTS__SORT_TYPE_REVERSE_ALPHA.equals(sortType)) {
			Comparator comparator = PresentationContext.INSTANCE.getReverseComparator();
			if (forcePresNameSort)
				comparator = PresentationContext.INSTANCE.getPresNameReverseComparator();
			Collections.<Object>sort(returnList, comparator);
		} else if (V_CATEGORY_ELEMENTS__SORT_TYPE_METHOD_TYPE.equals(sortType)) {
			Comparator comparator = PresentationContext.INSTANCE.getMethodElementTypeComparator();
			if (forcePresNameSort)
				comparator = PresentationContext.INSTANCE.getPresNameMethodElementTypeComparator();
			Collections.<Object>sort(returnList, comparator);
		}
		return returnList;
	}
	
	private static List<Object> findManualSortOrderInContributors(ContentCategory cc, List<Object> elementList) {
		OrderInfo latestInfo = null;
		Map<String, MethodElement> guidMap = new HashMap<String, MethodElement>();

		String sortType = getCategorySortValue(cc);
		if (V_CATEGORY_ELEMENTS__SORT_TYPE_MANUAL.equals(sortType)) {
			// set up GUID map
			for (Iterator iterator = elementList.iterator(); iterator.hasNext();) {
				Object o = iterator.next();
				if (o instanceof MethodElement) {
					guidMap.put(((MethodElement)o).getGuid(),
							(MethodElement)o);
				}
			}
			for (Iterator iter = TngUtil.getContributors(cc);iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof ContentCategory) {
					ContentCategory contributor = (ContentCategory)obj;
					OrderInfo orderInfo = TngUtil.getOrderInfo(contributor, ContentElementOrderList.ORDER_INFO_NAME);
					if (orderInfo == null) {
						continue;
					}
					// find latest OrderInfo that contains all these elements
					if (latestInfo == null || orderInfo.getTimestamp() > latestInfo.getTimestamp()) {
						latestInfo = orderInfo;
					}
				}
			}
			if (latestInfo != null) {
				List<Object> returnList = new ArrayList<Object>();
				// sort list according to orderInfo
				int size = latestInfo.getGUIDs().size();
				for (int i = 0; i < size; i++) {
					String guid = (String)latestInfo.getGUIDs().get(i);
					Object element = guidMap.get(guid);
					if (element != null) {
						returnList.add(element);
						guidMap.remove(guid);
					} else {
						// try to find element in the guidMap that has a generalizer with "guid"
						MethodElement me = findElementInGeneralizerList(guidMap, guid);
						if (me != null) {
							returnList.add(me);
							guidMap.remove(guid);
						} else {
							// could not locate, will return original list
						}
					}
				}
				if (elementList.size() == returnList.size())
					return returnList;
			}
		}
		return elementList;
	}
	
	private static MethodElement findElementInGeneralizerList(Map<String, MethodElement> guidMap, String guid) {
		for (Iterator<MethodElement> iter = guidMap.values().iterator();iter.hasNext();) {
			MethodElement value = iter.next();
			if (value instanceof VariabilityElement) {
				for (Iterator genIter = TngUtil.getGeneralizers((VariabilityElement)value);genIter.hasNext();) {
					Object generalizer = genIter.next();
					if (generalizer instanceof MethodElement) {
						if (((MethodElement)generalizer).getGuid().equals(guid)) {
							return (MethodElement)generalizer;
						}
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * @param cc
	 * @param feature
	 * @return
	 */
	public static boolean needToSort(MethodElement element, EStructuralFeature feature) {
		if (! (element instanceof ContentCategory)) {
			return false;
		}
		if (element instanceof CustomCategory && 
				feature == UmaPackage.eINSTANCE.getCustomCategory_CategorizedElements()) {
			return true;
		}
		if (element instanceof Discipline && 
				feature == UmaPackage.eINSTANCE.getDiscipline_Tasks()) {
			return true;
		}
		if (element instanceof Domain && 
				feature == UmaPackage.eINSTANCE.getDomain_WorkProducts()) {
			return true;
		}
		if (element instanceof RoleSet && 
				feature == UmaPackage.eINSTANCE.getRoleSet_Roles()) {
			return true;
		}
		if (element instanceof Tool && 
				feature == UmaPackage.eINSTANCE.getTool_ToolMentors()) {
			return true;
		}
		if (element instanceof WorkProductType && 
				feature == UmaPackage.eINSTANCE.getWorkProductType_WorkProducts()) {
			return true;
		}

		return false;
	}
}
