//------------------------------------------------------------------------------
// 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.forms;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.authoring.ui.actions.LibraryViewDeleteAction;
import org.eclipse.epf.authoring.ui.filters.AllFilter;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.MoveInCategoryCommand;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIManager;
import org.eclipse.epf.library.util.LibraryManager;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.TermDefinition;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.MessageException;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.editor.FormEditor;


/**
 * The Assign page in the Custom Category editor.
 * 
 * @author Shashidhar Kannoori
 * @author Kelvin Low
 * @since 1.0
 */
public class CustomCategoryAssignPage extends AssociationFormPage {

	private static final String FORM_PAGE_ID = "customCategoryAssignPage"; //$NON-NLS-1$

	private CustomCategory category;

	/**
	 * Creates a new instance.
	 */
	public CustomCategoryAssignPage(FormEditor editor) {
		super(editor, FORM_PAGE_ID, AuthoringUIText.ASSIGN_PAGE_TITLE);
	}

	/**
	 * @see org.eclipse.ui.forms.editor.init(IEditorSite, IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
		category = (CustomCategory) contentElement;
		setUseCategory2(false);
		setUseCategory3(false);
		setAllowChange1(true);
		setIsUpAndDownButtonsRequired1(true);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#initContentProviderSelected()
	 */
	protected void initContentProviderSelected() {
		contentProviderSelected = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				List list = new ArrayList();
				list.addAll(category.getCategorizedElements());
				return list.toArray();
			}
		};
		viewer_selected.setContentProvider(contentProviderSelected);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#addItemsToModel1(ArrayList)
	 */
	protected void addItemsToModel1(ArrayList addItems) {
		List ancestors = getAncestors(category);
		if (!addItems.isEmpty()) {
			for (Iterator it = addItems.iterator(); it.hasNext();) {
				MethodElement customCategory = (MethodElement) it.next();
				if (customCategory instanceof CustomCategory
						&& TngUtil
								.isRootCustomCategory((CustomCategory) customCategory)) {
				} else if (ancestors.contains(customCategory)) {
				} else {
					if (customCategory instanceof ProcessComponent) {
						MethodElement object = ((ProcessComponent) customCategory)
								.getProcess();
						LibraryManager.getInstance().addToCustomCategory(
								getActionManager(), category, object);
					} else {
						LibraryManager.getInstance().addToCustomCategory(
								getActionManager(), category, customCategory);
					}
				}
			}
			setDirty(true);
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#removeItemsFromModel1(ArrayList)
	 */
	protected void removeItemsFromModel1(ArrayList rmItems) {
		if (!rmItems.isEmpty()) {
			ArrayList customCategoriesToDelete = new ArrayList();
			for (Iterator it = rmItems.iterator(); it.hasNext();) {
				MethodElement e = (MethodElement) it.next();
				if (e instanceof CustomCategory) {
					Adapter adapter = TngAdapterFactory.INSTANCE
							.getNavigatorView_ComposedAdapterFactory().adapt(
									category, ITreeItemContentProvider.class);
					if (adapter != null
							&& adapter instanceof ItemProviderAdapter) {
						for (Iterator iter = ((ItemProviderAdapter) adapter)
								.getChildren(category).iterator(); iter
								.hasNext();) {
							Object o = iter.next();
							if (TngUtil.unwrap(o) == e) {
								customCategoriesToDelete.add(o);
							}
						}
					}
					continue;
				}
				LibraryManager.getInstance().removeFromCustomCategory(
						getActionManager(), category, e);
			}

			if (customCategoriesToDelete.size() > 0) {
				LibraryViewDeleteAction deleteAction = new LibraryViewDeleteAction() {
					public void run() {
						String title = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorTitle; //$NON-NLS-1$				
						try {
							super.run();
						} catch (MessageException e) {
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayError(title, e.getMessage());
						} catch (Exception e) {
							String details = TngUtil.toStackTraceString(e);
							String message = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorMessage; //$NON-NLS-1$		
							String reason = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorReason; //$NON-NLS-1$
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayError(title, message, reason,
											details, e);
						}
					}

					protected void deleteFailed() {
						// library need to be reloaded
						//
						String libDir = LibraryService.getInstance()
								.getCurrentMethodLibraryPath();
						LibraryUIManager.getInstance().openLibrary(libDir);
					}
				};
				deleteAction.setEditingDomain(LibraryView.getView()
						.getEditingDomain());
				deleteAction.selectionChanged(new StructuredSelection(
						customCategoriesToDelete));
				deleteAction.run();
			}
			setDirty(true);
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#moveUpItemsInSelectedItems1(ArrayList)
	 */
	protected void moveUpItemsInSelectedItems1(ArrayList moveUpItems) {
		if (!moveUpItems.isEmpty()) {
			EStructuralFeature feature = UmaPackage.eINSTANCE
					.getCustomCategory_CategorizedElements();
			MoveInCategoryCommand cmd = new MoveInCategoryCommand(category,
					moveUpItems, feature,
					ModelStructure.DEFAULT.customCategoryPath, true, 1);
			getActionManager().execute(cmd);
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.AssociationFormPage#moveDownItemsInSelectedItems1(ArrayList)
	 */
	protected void moveDownItemsInSelectedItems1(ArrayList moveDownItems) {
		if (!moveDownItems.isEmpty()) {
			EStructuralFeature feature = UmaPackage.eINSTANCE
					.getCustomCategory_CategorizedElements();
			MoveInCategoryCommand cmd = new MoveInCategoryCommand(category,
					moveDownItems, feature,
					ModelStructure.DEFAULT.customCategoryPath, true, 0);
			getActionManager().execute(cmd);
		}
	}

	/**
	 * Returns the ancestors for the given Custom Category.
	 */
	private List getAncestors(CustomCategory methodObject) {
		List ancestorList = new ArrayList();
		List objList = new ArrayList();
		objList.add(methodObject);
		getAncestors(ancestorList, objList);
		return ancestorList;
	}

	private List getAncestors(List ancestorList, List methodObjectList) {
		if (methodObjectList.isEmpty())
			return ancestorList;

		List allParentCustCats = new ArrayList();

		for (Iterator iter = methodObjectList.iterator(); iter.hasNext();) {
			CustomCategory element = (CustomCategory) iter.next();
			List parentList = AssociationHelper.getCustomCategories(element);
			allParentCustCats.addAll(parentList);
		}

		ancestorList.addAll(methodObjectList);
		List nextCheckList = new ArrayList();
		for (Iterator iter = allParentCustCats.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (!ancestorList.contains(element)) {
				nextCheckList.add(element);
			}
		}

		return getAncestors(ancestorList, nextCheckList);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getContentElement()
	 */
	protected Object getContentElement() {
		return category;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getTabString()
	 */
	protected String getTabString() {
		return FilterConstants.ALL_ELEMENTS;
	}

	private class CustomCategoryAssignFilter extends AllFilter {
		protected boolean childAccept(Object obj) {
			if (obj instanceof ProcessPackage)
				return true;
			if (obj instanceof Process)
				return true;
			if (obj instanceof CustomCategory) {
				if (TngUtil.isRootCustomCategory((CustomCategory) obj)) {
					return !(((CustomCategory) obj).getCategorizedElements()
							.isEmpty());
				}
			}
			if (obj instanceof TermDefinition)
				return false;
			if (obj instanceof ContentElement) {
				// if (obj instanceof Discipline){
				// return
				// AssociationHelper.getDisciplineGroups((Discipline)obj).isEmpty();
				// }
				// if (obj instanceof RoleSet){
				// return
				// AssociationHelper.getRoleSetGroups((RoleSet)obj).isEmpty();
				// }
				return !(getHelper().isContributor((ContentElement) obj));
			}
			return false;
		}
	};

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.DescriptionFormPage#getFilter()
	 */
	protected IFilter getFilter() {
		return filter = new CustomCategoryAssignFilter();
	}
	protected String getMultipleSelectDescription(int count) {
		return super.getMultipleSelectDescription(count, AuthoringUIResources.customCategoryAssignPage_multipleSelectDescription);
	}
	
	protected String getSectionDescription() {
		return AuthoringUIResources.customCategoryAssignPage_sectionDescription;
	}

	protected String getSectionName() {
		return AuthoringUIResources.customCategoryAssignPage_sectionName;
	}

	protected String getSelectedLabel() {
		return AuthoringUIResources.customCategoryAssignPage_selectedLabel;
	}
	
	protected String getSelectedLabel2() {
		return null;
	}
	
	protected String getSelectedLabel3() {
		return null;
	}


}
