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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.editors.BreakdownElementEditorInput;
import org.eclipse.epf.authoring.ui.editors.EditorChooser;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.diagram.core.part.AbstractDiagramEditor;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.DiagramEditorInputProxy;
import org.eclipse.epf.diagram.ui.service.DiagramEditorHelper;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.util.MethodElementUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.internal.ContentElementNameValidator;
import org.eclipse.epf.library.edit.validation.internal.ValidatorFactory;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;


/**
 * Helper Utility class for UI
 * 
 * @author Shilpa Toraskar
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class UIHelper {

	/**
	 * Setting items in a table
	 * 
	 * @param table
	 * @param items
	 */
	public static void setItems(Table table, ArrayList items) {
		table.removeAll();
		for (int i = 0; i < items.size(); i++) {
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText((String) items.get(i));
		}
	}

	/**
	 * Create list on the given composite with given style
	 * @param toolkit
	 * @param parent
	 * @param style
	 */
	public static List createList(FormToolkit toolkit, Composite parent,
			int style) {
		List list = new List(parent, style | SWT.NULL);
		toolkit.adapt(list, true, true);
		return list;
	}

	/*
	 * Method will return Object[] of guidance excluding Practice.
	 * MethodElementUtil#getSelectedGuidances(EObject) calculates all guidance.
	 */
	public static Object[] getSelectedGuidances(ContentElement contentElement) {
		java.util.List list = MethodElementUtil
				.getSelectedGuidances(contentElement);
		for (Iterator it = list.iterator(); it.hasNext();) {
			Object obj = it.next();
			if (obj instanceof Practice)
				it.remove();
		}
		return list.toArray();
	}

	private static String getFormPageTitlePrefixFor(MethodElement methodElement) {
		String elementLabel = LibraryUIText.getUIText(methodElement);
		if (methodElement instanceof WorkProduct) {
			return LibraryUIText.TEXT_WORK_PRODUCT + " (" + elementLabel + ")"; //$NON-NLS-1$ //$NON-NLS-2$
		} else if (methodElement instanceof Guidance) {
			return LibraryUIText.TEXT_GUIDANCE + " (" + elementLabel + ")"; //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			return elementLabel;
		}
	}

	/**
	 * Sets text for the given form based on the given element, including variable information of the element
	 * if there is any.
	 * 
	 * @param form
	 * @param element
	 */
	public static void setFormText(ScrolledForm form, MethodElement element) {
		if (form != null && !form.isDisposed()) {
			StringBuffer str = new StringBuffer();
			str.append(getFormPageTitlePrefixFor(element));
			str.append(AuthoringUIResources.editor_title_colon_with_spaces);
			
			if(element instanceof VariabilityElement) {
				str.append(TngUtil.getLabel((VariabilityElement) element,
						"", true)); //$NON-NLS-1$
			}
			else if(element.getName() != null){
				str.append(element.getName());
			}
			form.setText(str.toString());
		}
	}

	/**
	 * Check whether given deliverables leads to circular dependency
	 * @param toBePart
	 * @param deliverable
	 * @return
	 * 			Boolean value to indicate whether cicular dependency is detected
	 * @deprecated moved to {@link DependencyChecker#checkCircularDeliverables(Deliverable, Deliverable)}
	 */
	public static boolean checkCircularDeliverables(Deliverable toBePart,
			Deliverable deliverable) {
		return DependencyChecker.checkCircularDeliverables(toBePart, deliverable);
	}

	/**
	 * Check whether deliverable parts are in chain
	 * 
	 * @param e
	 * @param roots
	 */
	public static void deliverablePartsChain(Deliverable e, java.util.List roots) {
		java.util.List list = e.getDeliveredWorkProducts();
		if (list != null && list.size() > 0) {
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				Object obj = iterator.next();
				if (obj instanceof Deliverable) {
					roots.add(obj);
					deliverablePartsChain((Deliverable) obj, roots);
				}
			}
		}
	}
	

	/**
	 * Resolve content element name conflicts
	 * @param container
	 * @param element
	 * @param reference
	 */
	public static String resolveContentElementNameConflict(EObject container, MethodElement element, EReference
			reference) {

		final IValidator validator = new ContentElementNameValidator(container
				, reference,
				(ContentElement) element, new ValidatorFactory.TypeFilter(element));
		
		String msg = validator.isValid(element.getName());
		
		if (msg != null) {
			String featureTxt = TngUtil.getFeatureText(UmaPackage.eINSTANCE
					.getNamedElement_Name());
			String title = LibraryEditResources.resolveNameConflictDialog_title; 
			String dlgMsg = NLS.bind(
					LibraryEditResources.resolveNameConflictDialog_text,
					StrUtil.toLower(featureTxt), element.getName());
			String currentValue = (String) element.eGet(UmaPackage.eINSTANCE
					.getNamedElement_Name());

			IInputValidator inputValidator = new IInputValidator() {
				public String isValid(String newText) {
					return validator.isValid(newText);
				}
			};

			InputDialog inputDlg = new InputDialog(
					MsgBox.getDefaultShell(), title, dlgMsg, currentValue,
					inputValidator);
			if (inputDlg.open() == Window.CANCEL) {
				throw new OperationCanceledException();
			}
			return inputDlg.getValue();
		}
		return null;
	}
	
	
	/**
	 * Diagram editors of object itself will be closed. And Parent diagram editors 
	 * will be refreshed.  
	 *  @deprecated  (see:  {@link DiagramEditorHelper} - refreshParentDiagramEditors())
	 */
	public static void refreshOpenDiagramEditorsOfParent(Object refreshElement, java.util.List openEditorRefs) {
		openEditorRefs = new ArrayList();
		// Now refresh object's parent's diagrams.
		IWorkbenchPage workbenchPage = AuthoringUIPlugin.getDefault()
				.getWorkbench().getActiveWorkbenchWindow()
				.getActivePage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor != null) {
				IEditorInput input = editor.getEditorInput();
				Object element = null;
				if (input instanceof BreakdownElementEditorInput) {
					BreakdownElementEditorInput binput = (BreakdownElementEditorInput)input;
					if (binput.getWrapper() != null) {
						element = binput.getWrapper();
						if(element instanceof BreakdownElementWrapperItemProvider){
							Object parent = ((BreakdownElementWrapperItemProvider)element).getParent(null);
							if(parent instanceof BreakdownElementWrapperItemProvider){
								if(element.equals(refreshElement))
									refreshOpenDiagramEditorsOfParent(parent, openEditorRefs);
							}
						}
					} else {
						element = binput.getMethodElement();
					}
				} 
				else if (input instanceof DiagramEditorInputProxy) {
					DiagramEditorInput diagramInput = ((DiagramEditorInputProxy) input).getDiagramEditorInput();
					if (diagramInput != null) {
						element = diagramInput.getMethodElement();
					}
				}
				if (element != null)
				{
					if(element instanceof Activity){
						if(((Activity)element).getBreakdownElements().contains(refreshElement))
							openEditorRefs.add(reference);
						else if(refreshElement instanceof BreakdownElementWrapperItemProvider){
							Object localRefreshElement = refreshElement;
							while((localRefreshElement instanceof BreakdownElementWrapperItemProvider)
									&& ((BreakdownElementWrapperItemProvider)localRefreshElement).getOwner()!= null){
								if(((BreakdownElementWrapperItemProvider)localRefreshElement).getOwner()
										.equals(element)){
									openEditorRefs.add(reference);
								}
								localRefreshElement = ((BreakdownElementWrapperItemProvider)localRefreshElement).getOwner();
							}
						}
					}else if(element instanceof BreakdownElementWrapperItemProvider){
						Collection c = ((BreakdownElementWrapperItemProvider)element).getChildren(element);
						if(c != null && c.contains(refreshElement)){
							openEditorRefs.add(reference);
						}
					}
					
				}
			}
		}
		int size = openEditorRefs.size();
		//IEditorReference[] references = new IEditorReference[size];
		for (int i = 0; i < size; i++) {
			IEditorReference reference = (IEditorReference) openEditorRefs.get(i);
			IEditorPart editor = reference.getEditor(true);
			if(editor instanceof AbstractDiagramEditor ){
				((AbstractDiagramEditor)editor).refreshDiagram();
			}
		}
	}
	
	/**
	 * Close diagram editors including parent editors
	 * @param closeElement
	 * @param closeEditorRefs
	 * @deprecated
	 */
	public static void closeDiagramEditorsIncludingParent(Object closeElement, java.util.List closeEditorRefs) {
		closeEditorRefs = new ArrayList();
		IWorkbenchPage workbenchPage = AuthoringUIPlugin.getDefault()
				.getWorkbench().getActiveWorkbenchWindow()
				.getActivePage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor != null) {
				IEditorInput input = editor.getEditorInput();
				Object element = null;
				if (input instanceof BreakdownElementEditorInput) {
					BreakdownElementEditorInput binput = (BreakdownElementEditorInput)input;
					if (binput.getWrapper() != null) {
						element = binput.getWrapper();
						if(element instanceof BreakdownElementWrapperItemProvider){
							Object parent = ((BreakdownElementWrapperItemProvider)element).getParent(null);
							if(parent instanceof BreakdownElementWrapperItemProvider){
								if(element.equals(closeElement))
									closeDiagramEditorsIncludingParent(parent, closeEditorRefs);
							}
						}
					} else {
						element = binput.getMethodElement();
					}
				} 
				else if (input instanceof DiagramEditorInputProxy) {
					DiagramEditorInput diagramInput = ((DiagramEditorInputProxy) input).getDiagramEditorInput();
					if (diagramInput != null) {
						element = diagramInput.getMethodElement();
					}
				}
				if (element != null)
				{
						//closeEditorRefs.add(reference);
					if(element instanceof Activity){
						if(element.equals(closeElement))
							closeEditorRefs.add(reference);
						
						if(((Activity)element).getBreakdownElements().contains(closeElement))
							closeEditorRefs.add(reference);
						else if(closeElement instanceof BreakdownElementWrapperItemProvider){
							if(((BreakdownElementWrapperItemProvider)closeElement).getOwner()
									!= null)
								if(((BreakdownElementWrapperItemProvider)closeElement).getOwner()
									.equals(element)){
									closeEditorRefs.add(reference);
								if(((BreakdownElementWrapperItemProvider)closeElement).getOwner()
									instanceof BreakdownElementWrapperItemProvider){
									if(((BreakdownElementWrapperItemProvider)((BreakdownElementWrapperItemProvider)
											closeElement).getOwner()).getOwner().equals(element))
										closeEditorRefs.add(reference);
								}
							}
						}
					}else if(element instanceof BreakdownElementWrapperItemProvider){
						Collection c = ((BreakdownElementWrapperItemProvider)element).getChildren(element);
						if(c != null && c.contains(closeElement)){
							closeEditorRefs.add(reference);
						}
					}
				}
			}
		}
		int size = closeEditorRefs.size();
		IEditorReference[] references = new IEditorReference[size];
		for (int i = 0; i < size; i++) {
			references[i] = (IEditorReference) closeEditorRefs.get(i);
		}
		workbenchPage.closeEditors(references, false);
	}
	
	/**
	 * Get base activity for the given activity
	 * @param activity
	 * @return
	 * 			Base activity
	 */
	public static VariabilityElement getBaseActivity(Activity activity){
		while (!activity.getVariabilityType().equals(
				VariabilityType.NA_LITERAL)) {

			VariabilityElement ve = activity
					.getVariabilityBasedOnElement();
			if ((ve != null) && (ve instanceof Activity)) {
				activity = (Activity) ve;
			} else {
				break;
			}
		}
		return activity;
	}
	
	/**
	 * Close diagram editors
	 * 
	 * @param closeElement
	 * @param closeEditorRefs
	 *  @deprecated (see:  {@link DiagramEditorHelper})
	 *  
	 */
	public static void closeDiagramEditors(Object closeElement, java.util.List closeEditorRefs) {
		closeEditorRefs = new ArrayList();
		IWorkbenchPage workbenchPage = AuthoringUIPlugin.getDefault()
				.getWorkbench().getActiveWorkbenchWindow()
				.getActivePage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor != null) {
				IEditorInput input = editor.getEditorInput();
				Object element = null;
				if (input instanceof BreakdownElementEditorInput) {
					BreakdownElementEditorInput binput = (BreakdownElementEditorInput)input;
					if (binput.getWrapper() != null) {
						element = binput.getWrapper();
						if(element instanceof BreakdownElementWrapperItemProvider){
							Object parent = ((BreakdownElementWrapperItemProvider)element).getParent(element);
							if(parent instanceof BreakdownElementWrapperItemProvider){
								if(element.equals(closeElement))
									closeDiagramEditors(parent, closeEditorRefs);
							}
						}
					} else {
						element = binput.getMethodElement();
					}
				} 
				else if (input instanceof DiagramEditorInputProxy) {
					DiagramEditorInput diagramInput = ((DiagramEditorInputProxy) input).getDiagramEditorInput();
					if (diagramInput != null) {
						element = diagramInput.getMethodElement();
					}
				}
				if (element != null) {
					if (element.equals(closeElement)) {
						closeEditorRefs.add(reference);
					} else {
						// check whether element is child of closeElement
						// directly/indirectly
						if (closeElement instanceof Activity) {
							Collection collection = new ArrayList();
							ProcessUtil.getChildElements(
									(Activity) closeElement, Activity.class,
									collection);
							if (collection.contains(element)) {
								closeEditorRefs.add(reference);
							}
						}
					}
				}
			}
		}
		int size = closeEditorRefs.size();
		IEditorReference[] references = new IEditorReference[size];
		for (int i = 0; i < size; i++) {
			references[i] = (IEditorReference) closeEditorRefs.get(i);
		}
		workbenchPage.closeEditors(references, false);
		references = null;
	}
	
	/**
	 * Diagram editors of object itself will be closed. And Parent diagram editors 
	 * will be refreshed.  code not tested use refreshOpenDiagramEditors method.
	 * Not used currently
	 * @param object
	 */
	public static void syncDiagramEditors(Object object) {
		java.util.List closeEditors = new ArrayList();
		java.util.List refreshEditors = new ArrayList();
		
		IWorkbenchPage workbenchPage = AuthoringUIPlugin.getDefault()
				.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor != null) {
				IEditorInput input = editor.getEditorInput();
				Object editorElement = null;
				if (input instanceof BreakdownElementEditorInput) {
					BreakdownElementEditorInput binput = (BreakdownElementEditorInput)input;
					if(binput.getWrapper() != null){
						editorElement = binput.getWrapper();
					}else{
						editorElement = binput.getMethodElement();
					}
				}
				else if (input instanceof DiagramEditorInputProxy) {
					DiagramEditorInput diagramInput = ((DiagramEditorInputProxy) input).getDiagramEditorInput();
					if (diagramInput != null) {
						editorElement = diagramInput.getMethodElement();
					}
				}
				if(editorElement != null){
					if(editorElement.equals(object)){
						closeEditors.add(reference);
					}else{
						if(editorElement instanceof Activity){
							if(((Activity)editorElement).getBreakdownElements().contains(object))
								refreshEditors.add(reference);
							else if(object instanceof BreakdownElementWrapperItemProvider){
								Object local = object;
								while((local instanceof BreakdownElementWrapperItemProvider)
										&& ((BreakdownElementWrapperItemProvider)local).getOwner()!= null){
									if(((BreakdownElementWrapperItemProvider)local).getOwner()
											.equals(editorElement)){
										refreshEditors.add(reference);
									}
									local = ((BreakdownElementWrapperItemProvider)local).getOwner();
								}
							}
						}else if(editorElement instanceof BreakdownElementWrapperItemProvider){
							Collection c = ((BreakdownElementWrapperItemProvider)editorElement).getChildren(editorElement);
							if(c != null && c.contains(object)){
								refreshEditors.add(reference);
							}
						}
					}
				}
			}
		}
		// Close editor references and refresh editors.
		int size = closeEditors.size();
		IEditorReference[] references = new IEditorReference[size];
		for (int i = 0; i < size; i++) {
			references[i] = (IEditorReference) closeEditors.get(i);
		}
		workbenchPage.closeEditors(references, false);
		references = null;
		
		size = refreshEditors.size();
		//IEditorReference[] references = new IEditorReference[size];
		for (int i = 0; i < size; i++) {
			IEditorReference reference = (IEditorReference) refreshEditors.get(i);
			IEditorPart editor = reference.getEditor(true);
			if(editor instanceof AbstractDiagramEditor ){
				((AbstractDiagramEditor)editor).refreshDiagram();
			}
		}
		
	}
	
	public static void showProblemsView() {
 		SafeUpdateController
		.asyncExec(new Runnable() {
			public void run() {
				try {
					if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null &&
							PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
						IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
						IViewPart view = page.findView(IPageLayout.ID_PROBLEM_VIEW);
						if (view == null) {
							page.showView(IPageLayout.ID_PROBLEM_VIEW, null, IWorkbenchPage.VIEW_VISIBLE);
						}
					}
				} catch (Exception e) {
					// couldn't open the
					// problem view, too
					// bad..
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		});
	}
}
