/*******************************************************************************
 * Copyright (c) 2009, 2013 Oracle. 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/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.ui.internal.swt.bindings;

import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.jpt.common.ui.internal.swt.events.SelectionAdapter;
import org.eclipse.jpt.common.ui.internal.swt.listeners.SWTListenerTools;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.collection.CollectionTools;
import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent;
import org.eclipse.jpt.common.utility.model.listener.CollectionChangeAdapter;
import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiableCollectionValueModel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.List;

/**
 * This binding can be used to keep a list box's selection
 * synchronized with a model.
 * <p>
 * <strong>NB:</strong> This binding is bi-directional. As a result, we modify
 * our {@link #selectedItems cached list} <em>only</em> via
 * the {@link #selectedItemsModel model collection} change events;
 * and we {@link #listBoxSelectionChanged() simply pass through} the list box
 * selection events (by calling
 * {@link ModifiableCollectionValueModel#setValues(Iterable)},
 * which will loop back to us as a collection change event).
 * <p>
 * <strong>NB2:</strong> Changes to the underlying list model can imply changes
 * to the selection collection model. But these changes occur
 * <em>asynchronously</em> (as do their resulting events).
 * If the models are designed correctly, the selection model will be modified,
 * if necessary, whenever the underlying list model changes
 * (typically when elements are removed from the underlying list model).
 * But <em>all</em> changes to the underlying list model can cause changes to
 * the <em>indices</em> of the selected items; so all changes to the underlying
 * list model result in calls to {@link #listChanged()}.
 * Unfortunately, since the <em>selection</em> change event might not have
 * arrived yet, the selection item list can contain elements that are not in
 * the underlying list. So we must gracefully handle missing elements, even
 * though this may hide coding errors (i.e. something that should <em>not</em>
 * happen and should trigger an exception). Likewise, we can receive
 * <em>selection</em> change events before the underlying list model is updated,
 * resulting, again, in temporarily invalid state (which will be rectified once
 * the underlying list model is updated and the binding calls
 * {@link #listChanged()}).
 * 
 * @see ModifiableCollectionValueModel
 * @see List
 * @see SWTBindingTools
 */
final class ListBoxSelectionBinding<E>
	implements ListWidgetModelBinding.SelectionBinding
{
	// ***** model
	/**
	 * The underlying list (maintained by {@link ListWidgetModelBinding}).
	 */
	private final ArrayList<E> list;

	/**
	 * A modifiable value model on the underlying model selections.
	 */
	private final ModifiableCollectionValueModel<E> selectedItemsModel;

	/**
	 * Cache of model selections.
	 */
	private final ArrayList<E> selectedItems = new ArrayList<E>();

	/**
	 * A listener that allows us to synchronize the list box's selection with
	 * the model selections.
	 */
	private final CollectionChangeListener selectedItemsListener;

	// ***** UI
	/**
	 * The list box whose selection we keep synchronized
	 * with the model selections.
	 */
	private final List listBox;

	/**
	 * A listener that allows us to synchronize our selected items model
	 * with the list box's selection.
	 */
	private final SelectionListener listBoxSelectionListener;


	/**
	 * Constructor - all parameters are required.
	 */
	ListBoxSelectionBinding(
			ArrayList<E> list,
			ModifiableCollectionValueModel<E> selectedItemsModel,
			List listBox
	) {
		super();
		if ((list == null) || (selectedItemsModel == null) || (listBox == null)) {
			throw new NullPointerException();
		}
		this.list = list;
		this.selectedItemsModel = selectedItemsModel;
		this.listBox = listBox;

		this.selectedItemsListener = this.buildSelectedItemsListener();
		this.selectedItemsModel.addCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsListener);

		this.listBoxSelectionListener = this.buildListBoxSelectionListener();
		this.listBox.addSelectionListener(this.listBoxSelectionListener);

		this.selectedItems.ensureCapacity(this.selectedItemsModel.size());
		CollectionTools.addAll(this.selectedItems, this.selectedItemsModel);
	}


	// ********** initialization **********

	private CollectionChangeListener buildSelectedItemsListener() {
		return SWTListenerTools.wrap(new SelectedItemsListener(), this.listBox);
	}

	/* CU private */ class SelectedItemsListener
		extends CollectionChangeAdapter
	{
		@Override
		public void itemsAdded(CollectionAddEvent event) {
			ListBoxSelectionBinding.this.selectedItemsAdded(event);
		}
		@Override
		public void itemsRemoved(CollectionRemoveEvent event) {
			ListBoxSelectionBinding.this.selectedItemsRemoved(event);
		}
		@Override
		public void collectionCleared(CollectionClearEvent event) {
			ListBoxSelectionBinding.this.selectedItemsCleared();
		}
		@Override
		public void collectionChanged(CollectionChangeEvent event) {
			ListBoxSelectionBinding.this.selectedItemsChanged(event);
		}
	}

	private SelectionListener buildListBoxSelectionListener() {
		return new ListBoxSelectionListener();
	}

	/* CU private */ class ListBoxSelectionListener
		extends SelectionAdapter
	{
		@Override
		public void widgetSelected(SelectionEvent event) {
			ListBoxSelectionBinding.this.listBoxSelectionChanged();
		}
		@Override
		public void widgetDefaultSelected(SelectionEvent event) {
			ListBoxSelectionBinding.this.listBoxDoubleClicked();
		}
	}


	// ********** ListWidgetModelBinding.SelectionBinding implementation **********

	/**
	 * <strong>NB:</strong> The elements in the selection model may be out of
	 * sync with the underlying list model. (See the class comment.)
	 * <p>
	 * Modifying the list box's selected items programmatically does not
	 * trigger a {@link SelectionEvent}.
	 * <p>
	 * Pre-condition: The list-box is not disposed.
	 */
	public void listChanged() {
		this.setListSelection();
	}

	private void setListSelection() {
		int selectedItemsSize = this.selectedItems.size();
		int[] select = ArrayTools.EMPTY_INT_ARRAY;
		if (selectedItemsSize > 0) {
			select = new int[selectedItemsSize];
			int i = 0;
			for (E item : this.selectedItems) {
				select[i++] = this.indexOf(item);
			}
		}

		int listSize = this.list.size();
		int[] deselect = ArrayTools.EMPTY_INT_ARRAY;
		if (listSize > 0) {
			deselect = ArrayTools.fill(new int[listSize], -1);
			int i = 0;
			for (int j = 0; j < listSize; j++) {
				if ( ! ArrayTools.contains(select, j)) {
					deselect[i++] = j;
				}
			}
		}

		int[] old = ArrayTools.sort(this.listBox.getSelectionIndices());
		select = ArrayTools.sort(select);
		if ( ! Arrays.equals(select, old)) {
			this.listBox.deselect(deselect);
			this.listBox.select(select);
		}
	}

	public void dispose() {
		this.listBox.removeSelectionListener(this.listBoxSelectionListener);
		this.selectedItemsModel.removeCollectionChangeListener(CollectionValueModel.VALUES, this.selectedItemsListener);
		this.selectedItems.clear();
	}


	// ********** selected items **********

	/* CU private */ void selectedItemsAdded(CollectionAddEvent event) {
		if ( ! this.listBox.isDisposed()) {
			this.selectedItemsAdded_(event);
		}
	}

	/**
	 * Modifying the list box's selected items programmatically does not
	 * trigger a {@link SelectionEvent}.
	 */
	private void selectedItemsAdded_(CollectionAddEvent event) {
		@SuppressWarnings("unchecked")
		Iterable<E> items = (Iterable<E>) event.getItems();
		this.selectedItems.ensureCapacity(this.selectedItems.size() + event.getItemsSize());
		CollectionTools.addAll(this.selectedItems, items);

		int[] indices = new int[event.getItemsSize()];
		int i = 0;
		for (E item : items) {
			indices[i++] = this.indexOf(item);
		}
		this.listBox.select(indices);
	}

	/* CU private */ void selectedItemsRemoved(CollectionRemoveEvent event) {
		if ( ! this.listBox.isDisposed()) {
			this.selectedItemsRemoved_(event);
		}
	}

	/**
	 * Modifying the list box's selected items programmatically does not
	 * trigger a {@link SelectionEvent}.
	 */
	private void selectedItemsRemoved_(CollectionRemoveEvent event) {
		@SuppressWarnings("unchecked")
		Iterable<E> items = (Iterable<E>) event.getItems();
		CollectionTools.removeAll(this.selectedItems, items);

		int[] indices = new int[event.getItemsSize()];
		int i = 0;
		for (E item : items) {
			indices[i++] = this.indexOf(item);
		}
		this.listBox.deselect(indices);
	}

	/* CU private */ void selectedItemsCleared() {
		if ( ! this.listBox.isDisposed()) {
			this.selectedItemsCleared_();
		}
	}

	/**
	 * Modifying the list box's selected items programmatically does not
	 * trigger a {@link SelectionEvent}.
	 */
	private void selectedItemsCleared_() {
		this.selectedItems.clear();
		this.listBox.deselectAll();
	}

	/* CU private */ void selectedItemsChanged(CollectionChangeEvent event) {
		if ( ! this.listBox.isDisposed()) {
			this.selectedItemsChanged_(event);
		}
	}

	private void selectedItemsChanged_(CollectionChangeEvent event) {
		this.selectedItems.clear();
		this.selectedItems.ensureCapacity(event.getCollectionSize());
		@SuppressWarnings("unchecked")
		Iterable<E> eventCollection = (Iterable<E>) event.getCollection();
		CollectionTools.addAll(this.selectedItems, eventCollection);
		this.setListSelection();
	}

	/**
	 * <strong>NB:</strong> an index of <code>-1</code> is ignored by
	 * {@link List} (lucky for us).
	 */
	private int indexOf(E item) {
		int i = 0;
		for (E each : this.list) {
			if (ObjectTools.equals(each, item)) {
				return i;
			}
			i++;
		}
		return -1;
	}


	// ********** list box events **********

	/* CU private */ void listBoxSelectionChanged() {
		this.selectedItemsModel.setValues(this.getListBoxSelectedItems());
	}

	/* CU private */ void listBoxDoubleClicked() {
		this.listBoxSelectionChanged();
	}

	private Iterable<E> getListBoxSelectedItems() {
		ArrayList<E> lbSelectedItems = new ArrayList<E>(this.listBox.getSelectionCount());
		for (int selectionIndex : this.listBox.getSelectionIndices()) {
			lbSelectedItems.add(this.list.get(selectionIndex));
		}
		return lbSelectedItems;
	}


	// ********** misc **********

	@Override
	public String toString() {
		return ObjectTools.toString(this, this.selectedItems);
	}
}
