/*******************************************************************************
 * Copyright (c) 2005, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.ui.properties;

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

import org.eclipse.bpel.common.ui.details.ButtonIValue;
import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants;
import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment;
import org.eclipse.bpel.common.ui.flatui.FlatFormData;
import org.eclipse.bpel.model.Assign;
import org.eclipse.bpel.model.BPELFactory;
import org.eclipse.bpel.model.BPELPackage;
import org.eclipse.bpel.model.Copy;
import org.eclipse.bpel.model.From;
import org.eclipse.bpel.model.To;
import org.eclipse.bpel.ui.IHelpContextIds;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.commands.AddCopyCommand;
import org.eclipse.bpel.ui.commands.RemoveCopyCommand;
import org.eclipse.bpel.ui.commands.SwapCopyCommand;
import org.eclipse.bpel.ui.extensions.BPELUIRegistry;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.MultiObjectAdapter;
import org.eclipse.core.resources.IMarker;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PlatformUI;

/**
 * AssignImplDetails allows viewing and editing of the copy elements in an
 * Assign.
 * 
 * The input of this section is the Assign activity.
 * 
 * 
 * @author IBM Original Contribution
 * @author Michal Chmielewski (michal.chmielewski@oracle.com)
 * @date Jun 7, 2007
 * 
 */

@SuppressWarnings("nls")
public class AssignImplSection extends BPELPropertySection {

	static String CURRENT_INDEX_PROPERTY = "currentIndex";

	/** The to section */
	CategorySection fToSection = new CategorySection(this);

	/** The from section */
	CategorySection fFromSection = new CategorySection(this);

	/** The current copy rule being edited. */
	Copy fCurrentCopy;

	org.eclipse.swt.widgets.List fCopyList;

	Composite copySelectComposite;

	protected ListViewer fCopyListViewer;

	Button fDeleteCopy;
	Button fMoveUp;
	Button fMoveDown;

	Button fKeepSrcElement;
	Button fIgnoreMissingSourceData;

	EditController fKeepSrcElementController;
	EditController fIgnoreMissingSourceDataController;

	/**
	 * 
	 */

	public AssignImplSection() {
		super();

		List<IAssignCategory> fToAllowed = defaultToCategories();
		fToAllowed.addAll(BPELUIRegistry.getInstance()
				.getAdditionalAssignCategories());
		List<IAssignCategory> fFromAllowed = defaultFromCategories();
		fFromAllowed.addAll(BPELUIRegistry.getInstance()
				.getAdditionalAssignCategories());

		fToSection.fAllowed = fToAllowed.toArray(fToSection.fAllowed);
		fFromSection.fAllowed = fFromAllowed.toArray(fFromSection.fAllowed);
	}

	protected ArrayList<IAssignCategory> defaultToCategories() {
		return new ArrayList<IAssignCategory>(
				Arrays.asList(new IAssignCategory[] {
						new VariablePartAssignCategory(this),
						new ExpressionAssignCategory(this),
						new VariablePropertyAssignCategory(this),
						new PartnerRoleAssignCategory(this, false) }));
	}

	protected ArrayList<IAssignCategory> defaultFromCategories() {
		return new ArrayList<IAssignCategory>(
				Arrays.asList(new IAssignCategory[] {
						new VariablePartAssignCategory(this),
						new ExpressionAssignCategory(this),
						new LiteralAssignCategory(this),
						new VariablePropertyAssignCategory(this),
						new PartnerRoleAssignCategory(this, true),
						new EndpointReferenceAssignCategory(this),
						new OpaqueAssignCategory(this) }));
	}

	@Override
	protected MultiObjectAdapter[] createAdapters() {
		return new MultiObjectAdapter[] {
		/* model object */
		new MultiObjectAdapter() {

			@Override
			public void notify(Notification n) {

				adjustCopyRulesList();
				if (n.getFeature() == BPELPackage.eINSTANCE.getAssign_Copy()) {
					Copy copy = (Copy) n.getNewValue();
					Assign assign = getModel();
					if (copy != null) {
						selectCopyInList(assign.getCopy().indexOf(copy));
					}

				}

			}
		}, };
	}

	@Override
	protected void addAllAdapters() {
		super.addAllAdapters();
		EList<Copy> list = ((Assign) getInput()).getCopy();
		for (Copy copy : list) {
			fAdapters[0].addToObject(copy);
			if (copy.getFrom() != null)
				fAdapters[0].addToObject(copy.getFrom());
			if (copy.getTo() != null)
				fAdapters[0].addToObject(copy.getTo());
		}
	}

	protected void createCopySelectWidgets(Composite parent) {

		FlatFormData data;

		Composite c = copySelectComposite = createFlatFormComposite(parent);

		Button insertCopy = fWidgetFactory.createButton(c,
				Messages.AssignImplDetails_New__5, SWT.PUSH);
		fDeleteCopy = fWidgetFactory.createButton(c,
				Messages.AssignImplDetails_Delete__6, SWT.PUSH);
		fMoveUp = fWidgetFactory.createButton(c, "Move Up", SWT.PUSH);
		fMoveDown = fWidgetFactory.createButton(c, "Move Down", SWT.PUSH);

		fCopyList = fWidgetFactory.createList(c, SWT.BORDER | SWT.V_SCROLL
				| SWT.SINGLE);

		int preferredWidth = 200;

		data = new FlatFormData();
		data.left = new FlatFormAttachment(0, 0);
		data.right = new FlatFormAttachment(0, preferredWidth);
		data.top = new FlatFormAttachment(0, 0);
		data.bottom = new FlatFormAttachment(100, 0);
		c.setLayoutData(data);

		data = new FlatFormData();
		data.left = new FlatFormAttachment(0, 0);
		data.right = new FlatFormAttachment(100, 0);
		data.top = new FlatFormAttachment(0, 0);
		data.bottom = new FlatFormAttachment(insertCopy,
				-IDetailsAreaConstants.VSPACE);
		fCopyList.setLayoutData(data);

		data = new FlatFormData();
		data.left = new FlatFormAttachment(0, 0);
		data.right = new FlatFormAttachment(50, 0);
		data.bottom = new FlatFormAttachment(fMoveUp, 0);
		insertCopy.setLayoutData(data);

		data = new FlatFormData();
		data.left = new FlatFormAttachment(insertCopy, 0);
		data.right = new FlatFormAttachment(100, 0);
		data.bottom = new FlatFormAttachment(fMoveDown, 0);
		fDeleteCopy.setLayoutData(data);

		data = new FlatFormData();
		data.left = new FlatFormAttachment(0, 0);
		data.right = new FlatFormAttachment(50, 0);
		data.bottom = new FlatFormAttachment(100, 0);
		fMoveUp.setLayoutData(data);

		data = new FlatFormData();
		data.left = new FlatFormAttachment(fMoveUp, 0);
		data.right = new FlatFormAttachment(100, 0);
		data.bottom = new FlatFormAttachment(100, 0);
		fMoveDown.setLayoutData(data);

		insertCopy.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {

				Copy copy = BPELFactory.eINSTANCE.createCopy();

				getCommandFramework().execute(
						wrapInShowContextCommand(new AddCopyCommand(
								(Assign) getInput(), copy)));
				refreshAdapters();

			}

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

		fDeleteCopy.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				Assign assign = getModel();
				int index = fCopyList.getSelectionIndex();
				index = (index == assign.getCopy().size() - 1) ? index - 1
						: index;

				getCommandFramework().execute(
						wrapInShowContextCommand(new RemoveCopyCommand(
								(Assign) getInput(), fCurrentCopy)));
				selectCopyInList(index);
			}

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

		fCopyList.addSelectionListener(new SelectionListener() {

			public void widgetSelected(SelectionEvent e) {
				int index = fCopyList.getSelectionIndex();
				selectCopyInList(index);
			}

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

		fMoveUp.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				Assign assign = getModel();
				int index = fCopyList.getSelectionIndex();
				getCommandFramework().execute(
						wrapInShowContextCommand(new SwapCopyCommand(assign,
								index, index - 1)));
				selectCopyInList(index - 1);
			}

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

		fMoveDown.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				Assign assign = getModel();
				int index = fCopyList.getSelectionIndex();
				getCommandFramework().execute(
						wrapInShowContextCommand(new SwapCopyCommand(assign,
								index, index + 1)));
				selectCopyInList(index + 1);
			}

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

	}

	protected void createCategorySectionWidgets(Composite composite,
			final CategorySection section, boolean isFrom) {

		FlatFormData data;

		section.fLabel = fWidgetFactory.createLabel(composite,
				isFrom ? Messages.AssignImplDetails_From__1
						: Messages.AssignImplDetails_To__2);
		section.fCombo = new Combo(composite, SWT.FLAT | SWT.BORDER
				| SWT.READ_ONLY);
		data = new FlatFormData();

		if (isFrom) {
			data.left = new FlatFormAttachment(0, BPELUtil.calculateLabelWidth(
					section.fLabel, STANDARD_LABEL_WIDTH_SM));
			data.right = new FlatFormAttachment(50,
					-IDetailsAreaConstants.CENTER_SPACE);
		} else {
			data.left = new FlatFormAttachment(50,
					IDetailsAreaConstants.CENTER_SPACE
							+ BPELUtil.calculateLabelWidth(section.fLabel,
									STANDARD_LABEL_WIDTH_SM));
			data.right = new FlatFormAttachment(100, 0);
		}

		data.top = new FlatFormAttachment(0, 0);
		section.fCombo.setLayoutData(data);

		data = new FlatFormData();
		if (isFrom) {
			data.left = new FlatFormAttachment(0, 0);
		} else {
			data.left = new FlatFormAttachment(50,
					IDetailsAreaConstants.CENTER_SPACE);
		}
		data.right = new FlatFormAttachment(section.fCombo,
				-IDetailsAreaConstants.CENTER_SPACE);
		data.top = new FlatFormAttachment(section.fCombo, 0, SWT.CENTER);
		section.fLabel.setLayoutData(data);

		for (IAssignCategory category : section.fAllowed) {
			if (category.getName() != null) {
				section.fCombo.add(category.getName());
			}
		}

		section.fCombo.addSelectionListener(new SelectionListener() {

			public void widgetSelected(SelectionEvent e) {
				int index = section.fCombo.getSelectionIndex();

				updateCategorySelection(section, index, true);

			}

			// TODO: is this correct?
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
		});

		section.fOuterComposite = createFlatFormComposite(composite);
		data = new FlatFormData();
		data.left = new FlatFormAttachment(section.fLabel, 0, SWT.LEFT);
		data.right = new FlatFormAttachment(section.fCombo, 0, SWT.RIGHT);
		data.top = new FlatFormAttachment(section.fCombo,
				IDetailsAreaConstants.VSPACE);
		data.bottom = new FlatFormAttachment(100, -25);
		section.fOuterComposite.setLayoutData(data);

		// Create the keepSrcElement check box button
		if (isFrom) {
			fIgnoreMissingSourceData = fWidgetFactory.createButton(composite,
					Messages.AssignImplDetails_IgnoreMissingSourceData,
					SWT.CHECK);
			data = new FlatFormData();
			data.right = new FlatFormAttachment(50,
					-IDetailsAreaConstants.HSPACE);
			data.bottom = new FlatFormAttachment(100, 0);
			fIgnoreMissingSourceData.setLayoutData(data);

			fIgnoreMissingSourceDataController = createEditController();
			fIgnoreMissingSourceDataController.setFeature(BPELPackage.eINSTANCE
					.getCopy_IgnoreMissingFromData());
			fIgnoreMissingSourceDataController.setViewIValue(new ButtonIValue(
					fIgnoreMissingSourceData));
			fIgnoreMissingSourceDataController
					.startListeningTo(fIgnoreMissingSourceData);

		} else {

			fKeepSrcElement = fWidgetFactory.createButton(composite,
					Messages.AssignImplDetails_KeepSrcElementName, SWT.CHECK);
			data = new FlatFormData();
			data.right = new FlatFormAttachment(100,
					-IDetailsAreaConstants.HSPACE);
			data.bottom = new FlatFormAttachment(100, 0);
			fKeepSrcElement.setLayoutData(data);

			fKeepSrcElementController = createEditController();
			fKeepSrcElementController.setFeature(BPELPackage.eINSTANCE
					.getCopy_KeepSrcElementName());
			fKeepSrcElementController.setViewIValue(new ButtonIValue(
					fKeepSrcElement));
			fKeepSrcElementController.startListeningTo(fKeepSrcElement);

		}

	}

	/**
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#shouldUseExtraSpace()
	 */
	@Override
	public boolean shouldUseExtraSpace() {
		return true;
	}

	@Override
	protected void createClient(Composite parent) {

		Composite composite = createFlatFormComposite(parent);
		createCopySelectWidgets(composite);
		Composite mainComposite = createFlatFormComposite(composite);
		FlatFormData data = new FlatFormData();
		data.left = new FlatFormAttachment(copySelectComposite,
				IDetailsAreaConstants.HSPACE);
		data.top = new FlatFormAttachment(0, 0);
		data.right = new FlatFormAttachment(100, 0);
		data.bottom = new FlatFormAttachment(100, 0);
		mainComposite.setLayoutData(data);

		createCategorySectionWidgets(mainComposite, fFromSection, true);
		createCategorySectionWidgets(mainComposite, fToSection, false);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.PROPERTY_PAGE_ASSIGN);
	}

	// Total Hack until we have Copy objects in graphical editor
	@Override
	protected void basicSetInput(EObject newInput) {

		saveUserContextToInput();

		super.basicSetInput(newInput);
		adjustCopyRulesList();

		restoreUserContextFromInput();

		if (fToSection.fCurrent != null) {
			fToSection.fCurrent.refresh();
		}
		if (fFromSection.fCurrent != null) {
			fFromSection.fCurrent.refresh();
		}

	}

	/**
	 * Called when the copy rule changes or is created.
	 * 
	 */
	@SuppressWarnings("boxing")
	protected void selectCategoriesForInput() {

		fKeepSrcElementController.setInput(fCurrentCopy);
		fIgnoreMissingSourceDataController.setInput(fCurrentCopy);

		if (fCurrentCopy == null) {
			fToSection.hideCurrent();
			fFromSection.hideCurrent();
			fKeepSrcElement.setEnabled(false);
			fIgnoreMissingSourceData.setEnabled(false);
			return;
		}

		fKeepSrcElement.setEnabled(true);
		fIgnoreMissingSourceData.setEnabled(true);

		// Find the proper copy-from category
		boolean bFound = false;
		for (IAssignCategory category : fFromSection.fAllowed) {
			if (category.isCategoryForModel(fCurrentCopy.getFrom())) {
				updateCategorySelection(fFromSection, category, false);
				bFound = true;
				break;
			}
		}

		/** In case we can't find the appropriate one, just display the first one */
		if (bFound == false || fFromSection.fCurrent == null) {
			updateCategorySelection(fFromSection, 0, false);
		}

		// Find the proper copy-to category
		bFound = false;
		for (IAssignCategory category : fToSection.fAllowed) {
			if (category.isCategoryForModel(fCurrentCopy.getTo())) {
				updateCategorySelection(fToSection, category, false);
				bFound = true;
				break;
			}
		}

		/** In case we can't find the appropriate one, just display the first one */
		if (bFound == false || fToSection.fCurrent == null) {
			updateCategorySelection(fToSection, 0, false);
		}
	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#refresh()
	 */
	@Override
	public void refresh() {
		super.refresh();
	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#aboutToBeHidden()
	 */
	@Override
	public void aboutToBeHidden() {
		super.aboutToBeHidden();

		if (fToSection.fCurrent != null) {
			fToSection.fCurrent.aboutToBeHidden();
		}
		if (fFromSection.fCurrent != null) {
			fFromSection.fCurrent.aboutToBeHidden();
		}

	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#aboutToBeShown()
	 */
	@Override
	public void aboutToBeShown() {
		super.aboutToBeShown();
		if (fToSection.fCurrent != null) {
			fToSection.fCurrent.aboutToBeShown();
		}
		if (fFromSection.fCurrent != null) {
			fFromSection.fCurrent.aboutToBeShown();
		}
	}

	protected void adjustCopyRulesList() {
		Assign assign = getModel();
		EList<Copy> copyList = assign.getCopy();
		int sz = copyList.size();
		int idx = fCopyList.getSelectionIndex();
		String[] items = new String[sz];
		for (int i = 0; i < sz; i++) {
			Copy copy = copyList.get(i);
			items[i] = asText(copy.getFrom()) + " to " + asText(copy.getTo());
		}
		fCopyList.setItems(items);
		if (idx != -1) {
			fCopyList.setSelection(idx);
		}
		fDeleteCopy.setEnabled(sz > 0);
		fToSection.fCombo.setEnabled(sz > 0);
		fFromSection.fCombo.setEnabled(sz > 0);
	}

	private String asText(From from) {
		for (IAssignCategory category : fFromSection.fAllowed) {
			if (category.isCategoryForModel(from)) {
				return category.getName();
			}
		}
		return "?";
	}

	private String asText(To to) {
		for (IAssignCategory category : fToSection.fAllowed) {
			if (category.isCategoryForModel(to)) {
				return category.getName();
			}
		}
		return "?";
	}

	void updateCategorySelection(CategorySection section, int index,
			boolean bVisual) {
		updateCategorySelection(section, section.fAllowed[index], bVisual);
	}

	void updateCategorySelection(CategorySection section,
			IAssignCategory newCurrent, boolean bVisual) {

		/** Hide current */
		section.hideCurrent();

		/** Update current to the one that picked from */
		section.fCurrent = newCurrent;
		section.ensureCategoryCompositeCreated();

		if (bVisual == false) {
			section.updateCombo();
		}

		if (section == fToSection) {
			if (bVisual || fCurrentCopy.getTo() == null) {
				fCurrentCopy.setTo(BPELFactory.eINSTANCE.createTo());
			}
			section.fCurrent.setInput(fCurrentCopy.getTo());

		} else {

			if (bVisual || fCurrentCopy.getFrom() == null) {
				fCurrentCopy.setFrom(BPELFactory.eINSTANCE.createFrom());
			}
			section.fCurrent.setInput(fCurrentCopy.getFrom());
	        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=330813
			// https://jira.jboss.org/browse/JBIDE-7351
			// construct an initializer if From is empty
			if (section.fCurrent instanceof LiteralAssignCategory)
				VariableInitializationSection.createDefaultInitializer(getBPELEditor(), fCurrentCopy.getFrom(), fCurrentCopy.getTo());
		}

		section.showCurrent();
		section.fCurrent.refresh();
		refreshAdapters();

		// TODO: should the categories only store when a widget change is
		// committed?
		// Cons of that idea:
		// - Changing the category in the combo, but *not* changing anything
		// else,
		// then clicking elsewhere and back, would cause the combo to revert.
		// - The OpaqueAssignCategory doesn't have any widgets..
	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#getUserContext()
	 */
	@SuppressWarnings("boxing")
	@Override
	public Object getUserContext() {
		Assign assign = getModel();
		if (assign == null) {
			return -1;
		}
		return assign.getCopy().indexOf(fCurrentCopy);
	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#restoreUserContext(java.lang.Object)
	 */
	@SuppressWarnings("boxing")
	@Override
	public void restoreUserContext(Object userContext) {

		int idx = 0;
		if (userContext instanceof Number) {
			Number num = (Number) userContext;
			idx = num.intValue();
		}

		selectCopyInList(idx);
	}

	/**
	 * @see org.eclipse.bpel.ui.properties.BPELPropertySection#gotoMarker(org.eclipse.core.resources.IMarker)
	 */
	@Override
	public void gotoMarker(IMarker marker) {
		// TODO: This code do nothing and sometime causes NPE (from==null), so
		// temporary disabled (Oleg)
		// String uriFragment =
		// marker.getAttribute(IBPELUIConstants.MARKER_ATT_FROM, EMPTY_STRING);
		// EObject from = fModelObject.eResource().getEObject(uriFragment);
		// EObject copy = from.eContainer();
		// currentCopyIndex = ((Assign)getModel()).getCopy().indexOf(copy);
		refresh();
	}

	/*
	 * Select copy, refresh buttons & categories
	 */
	private void selectCopyInList(int index) {
		EList<Copy> list = ((Assign) getModel()).getCopy();
		if (index < 0 || index >= list.size()) {
			fCurrentCopy = null;
			fMoveUp.setEnabled(false);
			fMoveDown.setEnabled(false);
		} else {
			fCurrentCopy = list.get(index);
			fCopyList.select(index);
			fMoveUp.setEnabled(index > 0);
			fMoveDown.setEnabled(index < fCopyList.getItemCount() - 1);
		}
		selectCategoriesForInput();
	}
}
