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

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

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
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.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.editors.ProcessEditor;
import org.eclipse.epf.authoring.ui.filters.ActivityVariabilityFilter;
import org.eclipse.epf.authoring.ui.forms.ProcessBreakdownStructureFormPage;
import org.eclipse.epf.authoring.ui.views.ProcessViewer;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.configuration.ProcessVariabilityConfigurator;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.command.ActivityVariabilityCommand;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.library.ui.dialogs.ConvertActivityDialog;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Iteration;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.Phase;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;

/**
 * The general tab section for Activity
 * 
 * @author Shilpa Toraskar
 * @author Phong Nguyen Le
 * @since 1.0
 * 
 */
public class ActivityGeneralSection extends WorkBreakdownElementGeneralSection {
	protected Activity element;

	private static final String NOT_APPLICABLE_TEXT = AuthoringUIResources.notApplicable_text; //$NON-NLS-1$

	private static final String CONTRIBUTES_TEXT = AuthoringUIResources.contributes_text; //$NON-NLS-1$

	private static final String EXTENDS_TEXT = AuthoringUIResources.extends_text; //$NON-NLS-1$

	private static final String REPLACES_TEXT = AuthoringUIResources.replaces_text; //$NON-NLS-1$

	private Text modelInfoText;

	private Label activityTypeLabel;

	private Text ctrl_type_text;

	private Button ctrl_type_button;

	private Combo ctrl_variability;

	private ComboViewer viewer_variability;

	private Text baseText;

	private Button selectButton;

	protected ILabelProvider variabilityLabelProvider = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getText(Object object) {
			VariabilityType varObject = (VariabilityType) object;
			if (varObject == VariabilityType.NA_LITERAL)
				return NOT_APPLICABLE_TEXT;
			if (varObject == VariabilityType.CONTRIBUTES_LITERAL)
				return CONTRIBUTES_TEXT;
			if (varObject == VariabilityType.EXTENDS_LITERAL)
				return EXTENDS_TEXT;
			if (varObject == VariabilityType.REPLACES_LITERAL)
				return REPLACES_TEXT;
			return null;
		}
	};

	private IContentProvider variabilityContentProvider = new AdapterFactoryContentProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public Object[] getElements(Object object) {
			List variabilityTypesList = new ArrayList();
			variabilityTypesList.add(VariabilityType.NA_LITERAL);
			variabilityTypesList.add(VariabilityType.CONTRIBUTES_LITERAL);
			variabilityTypesList.add(VariabilityType.EXTENDS_LITERAL);
			variabilityTypesList.add(VariabilityType.REPLACES_LITERAL);
			return variabilityTypesList.toArray();
		}
	};

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.WorkBreakdownElementGeneralSection#init()
	 */
	protected void init() {
		super.init();
		// get activity object
		element = (Activity) getElement();
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.properties.WorkBreakdownElementGeneralSection#createGeneralSection(org.eclipse.swt.widgets.Composite)
	 */
	protected void createGeneralSection(Composite composite) {
		super.createGeneralSection(composite);

		// Model Info
		FormUI.createLabel(toolkit, generalComposite,
				PropertiesResources.Activity_ModelInfo); //$NON-NLS-1$

		modelInfoText = FormUI.createText(toolkit, generalComposite,
				SWT.DEFAULT, horizontalSpan);
		modelInfoText.setEnabled(false);
		modelInfoText.setText(getModelInfo());

		// Type of an Activity
		activityTypeLabel = FormUI.createLabel(toolkit, generalComposite,
				PropertiesResources.Activity_Type);
		
		ctrl_type_text = toolkit.createText(generalComposite, "", SWT.READ_ONLY); //$NON-NLS-1$
		{
			GridData gridData = new GridData(GridData.BEGINNING | GridData.FILL_HORIZONTAL);
			gridData.horizontalSpan = 1;
			ctrl_type_text.setLayoutData(gridData);
		}
		ctrl_type_button = toolkit.createButton(generalComposite,
				AuthoringUIText.CHANGE_TYPE_BUTTON_TEXT, SWT.PUSH);
		{
			GridData gridData = new GridData(GridData.BEGINNING);
			gridData.horizontalSpan = 1;
			ctrl_type_button.setLayoutData(gridData);
		}
		if (ConvertActivityDialog.getValidNewActivityTypes(element) == null) {
			ctrl_type_button.setVisible(false);
		}

		FormUI.createLabel(toolkit, generalComposite, ""); //$NON-NLS-1$

		// Variability Type
		FormUI.createLabel(toolkit, generalComposite,
				AuthoringUIText.VARIABILITY_TYPE_TEXT);

		ctrl_variability = FormUI.createCombo(toolkit, generalComposite, 2);
		{
			GridData gridData = new GridData(GridData.BEGINNING);
			gridData.horizontalSpan = 1;
			ctrl_variability.setLayoutData(gridData);
		}

		viewer_variability = new ComboViewer(ctrl_variability);
		viewer_variability.getCombo().setLayoutData(new GridData(1));
		viewer_variability.setContentProvider(variabilityContentProvider);
		viewer_variability.setLabelProvider(variabilityLabelProvider);
		viewer_variability.setInput(element);

		Label blankLabel = FormUI.createLabel(toolkit, generalComposite, ""); //$NON-NLS-1$
		{
			GridData gridData = new GridData(GridData.BEGINNING);
			gridData.horizontalSpan = 2;
			blankLabel.setLayoutData(gridData);
		}

		// Base elements
		FormUI.createLabel(toolkit, generalComposite,
				AuthoringUIText.BASE_ELEMENT_TEXT);

		baseText = FormUI.createText(toolkit, generalComposite);
		{
			GridData gd = new GridData(GridData.BEGINNING
					| GridData.FILL_HORIZONTAL);
			gd.horizontalSpan = 2;
			baseText.setLayoutData(gd);
		}
		baseText.setEnabled(false);

		// Button to select
		selectButton = FormUI.createButton(toolkit, generalComposite,
				AuthoringUIText.SELECT_BUTTON_TEXT);
	}

	/**
	 * add listeners
	 */
	protected void addListeners() {
		super.addListeners();
		ctrl_type_button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final ProcessEditor editor = (ProcessEditor) getEditor();
				if (editor.isDirty()) {
					String title = AuthoringUIResources.changeActivityTypeWarningDialog_title; //$NON-NLS-1$
					String message = AuthoringUIResources.descriptionTabGuidanceWarningDialog_message1; //$NON-NLS-1$
					AuthoringUIPlugin.getDefault().getMsgDialog()
							.displayWarning(title, message);
				} else  {
					nameText.removeListener(SWT.Deactivate,
							nameDeactivateListener);
					presentationNameText.removeListener(SWT.Deactivate,
							presentationNameDeactivateListener);

					Activity newActivity = ConvertActivityDialog
					.queryUserAndConvert((Activity) element, null, null);
					if (newActivity != null) {
						IStructuredSelection sel = new StructuredSelection(
								newActivity);
						// deal with property sheet directly.
						getPropertySheetPage().selectionChanged(getPart(),
								sel);
						// getEditor().setSelection(sel);
						refresh();
						((ProcessViewer) ((ProcessBreakdownStructureFormPage) getEditor()
								.getActivePageInstance()).getViewer())
								.expandToLevel(newActivity, 3);
					}
					nameText.addListener(SWT.Deactivate,
							nameDeactivateListener);
					presentationNameText.addListener(SWT.Deactivate,
							presentationNameDeactivateListener);

				}
			}

			public void widgetDefaultSelected(SelectionEvent e) {
			}
		});

		ctrl_variability.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				IStructuredSelection selection = (IStructuredSelection) viewer_variability
						.getSelection();

				VariabilityElement ve = element.getVariabilityBasedOnElement();
				VariabilityType type = (VariabilityType) selection
						.getFirstElement();

				if (ve != null & ve instanceof Activity) {
//					if(type.equals(VariabilityType.REPLACES_LITERAL)
//							&& ve instanceof Process){
//						Object[] args = { element.getName() };
//						String message = AuthoringUIResources
//						.bind(
//								AuthoringUIResources.activity_variability_error_msg1,
//								args);
//
//						String title = AuthoringUIResources.activity_variability_error_title;
//						AuthoringUIPlugin.getDefault().getMsgDialog()
//							.displayError(title, message, ""); //$NON-NLS-1$
//						VariabilityType vtype = element.getVariabilityType();
//						if(vtype != null){
//							IStructuredSelection sel = new StructuredSelection(vtype);
//							viewer_variability.setSelection(sel);
//						}
//						return;
//					}
//					if (ProcessUtil.hasContributorOrReplacer((Activity) ve)
//							&& type.equals(VariabilityType.EXTENDS_LITERAL)) {
//						Object[] args = { element.getName(),
//								((Activity) ve).getName() };
//						String message = AuthoringUIResources
//								.bind(
//										AuthoringUIResources.activity_variability_error_msg,
//										args);
//
//						String title = AuthoringUIResources.activity_variability_error_title;
//						AuthoringUIPlugin.getDefault().getMsgDialog()
//								.displayError(title, message, ""); //$NON-NLS-1$
//
//						VariabilityType variabilityType = element
//								.getVariabilityType();
//						IStructuredSelection newVariabilitySelection = new StructuredSelection(
//								variabilityType);
//						viewer_variability.setSelection(
//								newVariabilitySelection, true);
//
//						return;
//					}
					
					if(type != VariabilityType.NA_LITERAL) {
						IStatus state = DependencyChecker.checkCircularDependencyAfterFilterSelection(element, (Activity) ve, type);
						if(!state.isOK()) {
							String title = AuthoringUIResources.activity_variability_error_title;
							AuthoringUIPlugin.getDefault().getMsgDialog().displayError(title, state.getMessage());
							
							// set variability to back whatever it was for UI
							VariabilityType variabilityType = element.getVariabilityType();
							IStructuredSelection newVariabilitySelection = new StructuredSelection(
									variabilityType);
							viewer_variability.setSelection(newVariabilitySelection, true);
							return;
						}
					}
					boolean status = actionMgr.doAction(IActionManager.SET,
							element, UmaPackage.eINSTANCE
									.getVariabilityElement_VariabilityType(),
							type, -1);
					if (!status) {
						if (element.getPresentationName() == null
								|| element.getPresentationName().equals("")) {
							if (type.equals(VariabilityType.NA_LITERAL))
								element.setPresentationName(element.getName());
						}
						return;
					}
					if (element.getPresentationName() == null
							|| element.getPresentationName().equals("")) {
						if (type.equals(VariabilityType.CONTRIBUTES_LITERAL)
								|| type.equals(VariabilityType.REPLACES_LITERAL)
								|| type.equals(VariabilityType.NA_LITERAL))
							element.setPresentationName(element.getName());
					}
				}

				if (type == VariabilityType.NA_LITERAL) {
					if (ve != null) {
						boolean status = actionMgr
								.doAction(
										IActionManager.SET,
										element,
										UmaPackage.eINSTANCE
												.getVariabilityElement_VariabilityBasedOnElement(),
										null, -1);

						if (!status) {
							return;
						}
					}
					selectButton.setEnabled(false);
					baseText.setText(""); //$NON-NLS-1$
				} else {
					List selectionBaseList = new ArrayList();
					VariabilityElement base = element
							.getVariabilityBasedOnElement();
					selectionBaseList.add(base);
					selectButton.setEnabled(true);

				}
				// setFormTextWithVariableInfo();
			}
		});

		selectButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				MethodConfiguration config = getConfiguration();
				String tabName = FilterConstants.PROCESSES;

				VariabilityType type = (VariabilityType) ((IStructuredSelection) viewer_variability
						.getSelection()).getFirstElement();

				IFilter filter = new ActivityVariabilityFilter(config, null,
						tabName, element);

				ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						filter, tabName, null, config);
				fd.setBlockOnOpen(true);
				fd.setViewerSelectionSingle(true);
				fd.setTitle(tabName);
				fd.open();

				List selectedItems = fd.getSelectedItems();

				if (selectedItems != null && !selectedItems.isEmpty()) {
					Object o = selectedItems.get(0);
					if (o instanceof Activity) {
//						Activity act = (Activity) o;
//						if (isDirectParent(act)
//								|| ((act instanceof Process) && type.equals(VariabilityType.REPLACES_LITERAL)
//										&& !(element instanceof Process))) 
//						{
//							Object[] args = { element.getName() };
//							String message = AuthoringUIResources
//									.bind(
//											AuthoringUIResources.activity_variability_error_msg1,
//											args);
//
//							String title = AuthoringUIResources.activity_variability_error_title;
//							AuthoringUIPlugin.getDefault().getMsgDialog()
//									.displayError(title, message, ""); //$NON-NLS-1$
//
//							return;
//						}
//						if (isCircularDependency(act)) {
//							Object[] args = { element.getName(), act.getName() };
//							String message = AuthoringUIResources
//									.bind(
//											AuthoringUIResources.activity_variability_error_msg2,
//											args);
//
//							String title = AuthoringUIResources.activity_variability_error_title;
//							AuthoringUIPlugin.getDefault().getMsgDialog()
//									.displayError(title, message, ""); //$NON-NLS-1$
//
//							return;
//						}
//						// block for children
//						if (ProcessUtil.hasContributorOrReplacer(act)
//								&& type.equals(VariabilityType.EXTENDS_LITERAL)) {
//							Object[] args = { element.getName(), act.getName() };
//							String message = AuthoringUIResources
//									.bind(
//											AuthoringUIResources.activity_variability_error_msg,
//											args);
//
//							String title = AuthoringUIResources.activity_variability_error_title;
//							AuthoringUIPlugin.getDefault().getMsgDialog()
//									.displayError(title, message, ""); //$NON-NLS-1$
//
//							return;
//						}
						
						IStatus status = DependencyChecker.checkCircularDependencyAfterFilterSelection(element, (Activity) o, type);
						if(!status.isOK()) {
							String title = AuthoringUIResources.activity_variability_error_title;
							AuthoringUIPlugin.getDefault().getMsgDialog().displayError(title, status.getMessage());						
							return;
						}
					}
					if (o instanceof VariabilityElement) {
						VariabilityElement ve = (VariabilityElement) o;

						IConfigurator configurator = new ProcessVariabilityConfigurator(
								getDefaultConfiguration(), null);
						ActivityVariabilityCommand cmd = new ActivityVariabilityCommand(
								element, ve, type, configurator);
						boolean status = actionMgr.execute(cmd);

						if (!status) {
							return;
						}

						baseText.setText(TngUtil.getLabelWithPath(ve));
					}
				}
			}
		});

	}

	/**
	 * Get model information for the activity
	 * @return
	 * 			model info string
	 */
	private String getModelInfo() {
		String info = null;

		try {
			Object o = getAdapter();
			if (o instanceof IBSItemProvider) {
				IBSItemProvider adapter = (IBSItemProvider) o;
				info = adapter.getAttribute(element,
						IBSItemProvider.COL_MODEL_INFO);
			}
		} catch (Exception e) {
			// print exception
		}
		if (!(StrUtil.isBlank(info)))
			return info;
		else
			return PropertiesResources.Process_None;
	}


	/**
	 * @see org.eclipse.epf.authoring.ui.properties.WorkBreakdownElementGeneralSection#updateControls()
	 */
	protected void updateControls() {
		super.updateControls();

		ctrl_type_button.setEnabled(editable);
		ctrl_variability.setEnabled(editable);
		selectButton.setEnabled(editable);

		ctrl_variability.setEnabled(editable);
		if (((IStructuredSelection) viewer_variability.getSelection())
				.getFirstElement() == VariabilityType.NA_LITERAL) {
			selectButton.setEnabled(false);
		}
	}


	/**
	 * @see org.eclipse.epf.authoring.ui.properties.WorkBreakdownElementGeneralSection#refresh()
	 */
	public void refresh() {
		try {
			if (getElement() instanceof Activity) {
				super.refresh();

				element = (Activity) getElement();

				modelInfoText.setText(getModelInfo());

				ctrl_type_text.setText(PropertiesUtil.getType(element));

				// hide/show combo
				if ((element instanceof org.eclipse.epf.uma.Process)
						&& (element.getSuperActivities() == null || element
								.getSuperActivities() == null)) {
					activityTypeLabel.setVisible(false);
					ctrl_type_text.setVisible(false);
					ctrl_type_button.setVisible(false);
				} else {
					activityTypeLabel.setVisible(true);
					ctrl_type_text.setVisible(true);
					ctrl_type_button.setVisible(true);
				}

				VariabilityType variabilityType = element.getVariabilityType();
				IStructuredSelection newVariabilitySelection = new StructuredSelection(
						variabilityType);
				viewer_variability.setSelection(newVariabilitySelection, true);

				if (element.getVariabilityBasedOnElement() != null)
					baseText.setText(TngUtil.getLabelWithPath(element
							.getVariabilityBasedOnElement()));
				else
					baseText.setText(""); //$NON-NLS-1$
			}
		} catch (Exception ex) {
			logger
					.logError(
							"Error refreshing Activity general section : " + element, ex); //$NON-NLS-1$
		}
	}

	
	/**
	 * @see org.eclipse.epf.authoring.ui.properties.WorkBreakdownElementGeneralSection#getNamePrefix()
	 */
	public String getNamePrefix() {
		if (element instanceof CapabilityPattern) {
			return LibraryUIText.TEXT_CAPABILITY_PATTERN + ": "; //$NON-NLS-1$
		} else if (element instanceof DeliveryProcess) {
			return LibraryUIText.TEXT_DELIVERY_PROCESS + ": "; //$NON-NLS-1$
		} else if (element instanceof Phase) {
			return LibraryUIText.TEXT_PHASE + ": "; //$NON-NLS-1$
		} else if (element instanceof Iteration) {
			return LibraryUIText.TEXT_ITERATION + ": "; //$NON-NLS-1$
		} else
			return LibraryUIText.TEXT_ACTIVITY + ": "; //$NON-NLS-1$
	}

}
