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

import org.eclipse.emf.ecore.EObject;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.UmaUtil;


/**
 * @author Shilpa Toraskar
 * @since 1.0
 */
public class MethodElementUtil {

	/**
	 * Return method model of the object
	 * 
	 * @param obj
	 * @return
	 */
	public static MethodPlugin getMethodModel(Object obj) {
		return UmaUtil.getMethodPlugin((MethodElement) obj);
	}

	/**
	 * Returns list of models as specified.. 1. Method model of the object 2.
	 * Referenced models of the method model of the object (e.g. reference
	 * relationship)
	 * 
	 * @param object
	 * @return
	 */
	public static List getAllModels(Object object) {
		List allModels = new ArrayList();

		// get method model of the object
		MethodPlugin model = getMethodModel(object);

		if (model != null) {

			// get all base models
			//
			Misc.getAllBase(model, allModels);

			allModels.add(model);

			// // get base model of the method model
			// MethodPlugin baseModel = model.getBase();
			// if ( baseModel != null )
			// {
			// allModels.add(baseModel);
			// }
			//			
			// // get referenced model of the method model
			// List refModel = (List)model.getReferencedPlugin();
			// for (int i=0; i < refModel.size(); i++)
			// {
			// allModels.add(refModel.get(i));
			// }
		}

		return allModels;
	}

	/**
	 * Returns references guidances for the given object
	 * 
	 * @param object
	 * @return
	 */
	public static List getSelectedGuidances(EObject object) {
		List itemList = new ArrayList();

		List references = ((EObject) object).eCrossReferences();
		if (references != null && references.size() > 0) {
			for (Iterator it = references.iterator(); it.hasNext();) {
				Object obj = (Object) it.next();
				if (obj instanceof Guidance) {
					itemList.add(obj);
				}
			}
		}

		itemList
				.addAll(AssociationHelper.getPractices((ContentElement) object));

		return itemList;
	}

	// /**
	// * Return ToolMentors in the model, given particular object
	// * @param object
	// * @return
	// */
	// public static List getAllToolMentors(Object object)
	// {
	// List itemList = new ArrayList();
	// List pluginList = getAllModels(object);
	// for(int i =0; i<pluginList.size(); i++){
	//
	// Object object1 = pluginList.get(i);
	// TreeIterator iterator = ((EObject) object1).eAllContents();
	// while (iterator.hasNext()) {
	// Object obj = (Object) iterator.next();
	// if (obj instanceof Guidance) {
	// Guidance guidance = (Guidance) obj;
	// if(guidance.getType().getName().equals("ToolMentor")){
	// itemList.add(guidance);
	// }
	// }
	// }
	// }
	// return itemList;
	//        
	// }

	// public static Discipline setDiscipline(Task task, Discipline discipline)
	// {
	// return (Discipline) addToCategory(discipline, task,
	// UmaPackage.eINSTANCE.getDiscipline_Tasks(),
	// ModelStructure.DEFAULT.disciplineDefinitionPath, false);
	// }
	//    
	// public static Domain setDomain(WorkProduct wp, Domain domain) {
	// return (Domain) addToCategory(domain, wp,
	// UmaPackage.eINSTANCE.getDomain_WorkProducts(),
	// ModelStructure.DEFAULT.domainPath, false);
	// }
	//    
	// public static WorkProductType addToWorkProductType(WorkProductType
	// wpType, WorkProduct wp) {
	// return (WorkProductType) addToCategory(wpType, wp,
	// UmaPackage.eINSTANCE.getWorkProductType_WorkProducts(),
	// ModelStructure.DEFAULT.workProductTypePath, false);
	// }
	//    
	// public static UserDefinedCategory
	// addToUserDefinedCategory(UserDefinedCategory userDefinedCategory,
	// MethodElement element) {
	// if(element instanceof ContentElement) {
	// return (UserDefinedCategory) addToCategory(userDefinedCategory, element,
	// UmaPackage.eINSTANCE.getUserDefinedCategory_ContentElements(),
	// ModelStructure.DEFAULT.customCategoryPath, false);
	// }
	// else if(element instanceof ContentCategory) {
	// return (UserDefinedCategory) addToCategory(userDefinedCategory, element,
	// UmaPackage.eINSTANCE.getUserDefinedCategory_SubCategories(),
	// ModelStructure.DEFAULT.customCategoryPath, false);
	// }
	// return null;
	// }
	//    
	// public static Tool addToTool(Tool tool, ToolMentor toolMentor) {
	// return (Tool) addToCategory(tool, toolMentor,
	// UmaPackage.eINSTANCE.getTool_ToolMentors(),
	// ModelStructure.DEFAULT.toolPath, false);
	// }
	//    
	// public static RoleSet addToRoleSet(RoleSet roleSet, Role role) {
	// return (RoleSet) addToCategory(roleSet, role,
	// UmaPackage.eINSTANCE.getRoleSet_Roles(),
	// ModelStructure.DEFAULT.roleSetPath, false);
	// }
	//    
	// public static ContentCategory addToCategory(ContentCategory category,
	// MethodElement element, EStructuralFeature feature, String[]
	// categoryPkgPath, boolean checkForExistingContributor) {
	// // create contributor for category if it is not in the same plugin with
	// the element
	// //
	// MethodPlugin elementPlugin = UmaUtil.getMethodPlugin(element);
	// MethodPlugin categoryPlugin = UmaUtil.getMethodPlugin(category);
	// ContentCategory usedCategory = null;
	// boolean created = false;
	// if(categoryPlugin != elementPlugin) {
	// if(category.getVariabilityBasedOnElement() != null) {
	// throw new IllegalArgumentException("Could not add element to an extended
	// category that is in different plugin: " + category);
	// }
	// if(!Misc.isBaseOf(categoryPlugin, elementPlugin)) {
	// throw new IllegalArgumentException("Inaccesible category: " + category);
	// }
	// ContentPackage categoryPkg = UmaUtil.findContentPackage(elementPlugin,
	// categoryPkgPath);
	// ContentCategory contrib = null;
	// if(checkForExistingContributor) {
	// // look for the existing contributor for the category
	// //
	// for (Iterator iter = categoryPkg.getContentElements().iterator();
	// iter.hasNext();) {
	// ContentCategory cat = (ContentCategory) iter.next();
	// if(cat.getVariabilityBasedOnElement() == category) {
	// contrib = cat;
	// break;
	// }
	// }
	// }
	//    		
	// if(contrib == null) {
	// contrib = (ContentCategory)
	// UmaFactory.eINSTANCE.create(category.eClass());
	// contrib.setName(category.getName());
	// contrib.setVariabilityBasedOnElement(category);
	// contrib.setVariabilityType(VariabilityType.CONTRIBUTES_LITERAL);
	// categoryPkg.getContentElements().add(contrib);
	// created = true;
	// }
	// usedCategory = contrib;
	// }
	// else {
	// usedCategory = category;
	// }
	//    	
	// OppositeFeature oppositeFeature =
	// MultiResourceEObject.getOppositeFeature(feature);
	// MultiResourceEObject mrEObj = (MultiResourceEObject)element;
	// Object oppositeFeatureValue =
	// mrEObj.getOppositeFeatureMap().get(oppositeFeature);
	// if(feature.isMany()) {
	// Collection collection = (Collection) usedCategory.eGet(feature);
	// if(oppositeFeatureValue != null && !oppositeFeature.isMany()) {
	// if(oppositeFeatureValue != usedCategory) {
	// ((Collection)((EObject)oppositeFeatureValue).eGet(feature)).remove(element);
	// collection.add(element);
	// }
	// }
	// if(!collection.contains(element)) {
	// collection.add(element);
	// }
	// }
	// else {
	// Object val = usedCategory.eGet(feature);
	// if(oppositeFeatureValue != null && !oppositeFeature.isMany()) {
	// if(oppositeFeatureValue != usedCategory) {
	// ((EObject)oppositeFeatureValue).eSet(feature, null);
	// }
	// }
	// if(usedCategory != oppositeFeatureValue) {
	// usedCategory.eSet(feature, element);
	// }
	// }
	//    	
	// return usedCategory;
	// }
}
