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

import java.util.ArrayList;

import org.eclipse.jpt.common.ui.internal.listeners.SWTListChangeListenerWrapper;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.StringConverter;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.model.event.ListAddEvent;
import org.eclipse.jpt.common.utility.model.event.ListChangeEvent;
import org.eclipse.jpt.common.utility.model.event.ListClearEvent;
import org.eclipse.jpt.common.utility.model.event.ListMoveEvent;
import org.eclipse.jpt.common.utility.model.event.ListRemoveEvent;
import org.eclipse.jpt.common.utility.model.event.ListReplaceEvent;
import org.eclipse.jpt.common.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;

/**
 * This binding can be used to keep a list widget's contents
 * synchronized with a model. The list widget never alters
 * its contents directly; all changes are driven by the model.
 * 
 * @see ListValueModel
 * @see StringConverter
 * @see ListWidget
 * @see SelectionBinding
 * @see SWTTools
 */
@SuppressWarnings("nls")
final class ListWidgetModelBinding<E> {

	// ***** model
	/**
	 * The underlying list model.
	 */
	private final ListValueModel<E> listModel;

	/**
	 * A listener that allows us to synchronize the list widget's contents with
	 * the model list.
	 */
	private final ListChangeListener listChangeListener;

	/**
	 * A converter that converts items in the model list
	 * to strings that can be put in the list widget.
	 */
	private final StringConverter<E> stringConverter;

	// ***** UI
	/**
	 * An adapter on the list widget we keep synchronized with the model list.
	 */
	private final ListWidget listWidget;

	/**
	 * A listener that allows us to stop listening to stuff when the list widget
	 * is disposed. (Critical for preventing memory leaks.)
	 */
	private final DisposeListener listWidgetDisposeListener;

	// ***** selection
	/**
	 * Widget-specific selection binding.
	 */
	private final SelectionBinding selectionBinding;


	// ********** constructor **********

	/**
	 * Constructor - all parameters are required.
	 */
	ListWidgetModelBinding(
			ListValueModel<E> listModel,
			ListWidget listWidget,
			StringConverter<E> stringConverter,
			SelectionBinding selectionBinding
	) {
		super();
		if ((listModel == null) || (listWidget == null) || (stringConverter == null) || (selectionBinding == null)) {
			throw new NullPointerException();
		}
		this.listModel = listModel;
		this.listWidget = listWidget;
		this.stringConverter = stringConverter;
		this.selectionBinding = selectionBinding;

		this.listChangeListener = this.buildListChangeListener();
		this.listModel.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);

		this.listWidgetDisposeListener = this.buildListWidgetDisposeListener();
		this.listWidget.addDisposeListener(this.listWidgetDisposeListener);

		this.synchronizeListWidget();
	}


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

	private ListChangeListener buildListChangeListener() {
		return new SWTListChangeListenerWrapper(this.buildListChangeListener_());
	}

	private ListChangeListener buildListChangeListener_() {
		return new ListChangeListener() {
			public void itemsAdded(ListAddEvent event) {
				ListWidgetModelBinding.this.listItemsAdded(event);
			}
			public void itemsRemoved(ListRemoveEvent event) {
				ListWidgetModelBinding.this.listItemsRemoved(event);
			}
			public void itemsMoved(ListMoveEvent event) {
				ListWidgetModelBinding.this.listItemsMoved(event);
			}
			public void itemsReplaced(ListReplaceEvent event) {
				ListWidgetModelBinding.this.listItemsReplaced(event);
			}
			public void listCleared(ListClearEvent event) {
				ListWidgetModelBinding.this.listCleared(event);
			}
			public void listChanged(ListChangeEvent event) {
				ListWidgetModelBinding.this.listChanged(event);
			}
			@Override
			public String toString() {
				return "list listener";
			}
		};
	}

	private DisposeListener buildListWidgetDisposeListener() {
		return new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				ListWidgetModelBinding.this.listWidgetDisposed(event);
			}
			@Override
			public String toString() {
				return "list widget dispose listener";
			}
		};
	}


	// ********** list **********

	/**
	 * Brute force synchronization of list widget with the model list.
	 */
	private void synchronizeListWidget() {
		if ( ! this.listWidget.isDisposed()) {
			this.synchronizeListWidget_();
		}
	}

	private void synchronizeListWidget_() {
		ArrayList<String> items = new ArrayList<String>(this.listModel.size());
		for (E item : this.listModel) {
			items.add(this.convert(item));
		}
		this.listWidget.setItems(items.toArray(new String[items.size()]));

		// now that the list has changed, we need to synch the selection
		this.selectionBinding.synchronizeListWidgetSelection();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listItemsAdded(ListAddEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listItemsAdded_(event);
		}
	}

	private void listItemsAdded_(ListAddEvent event) {
		int i = event.getIndex();
		for (E item : this.getItems(event)) {
			this.listWidget.add(this.convert(item), i++);
		}

		// now that the list has changed, we need to synch the selection
		this.selectionBinding.synchronizeListWidgetSelection();
	}

	// minimized scope of suppressed warnings
	@SuppressWarnings("unchecked")
	private Iterable<E> getItems(ListAddEvent event) {
		return (Iterable<E>) event.getItems();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listItemsRemoved(ListRemoveEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listItemsRemoved_(event);
		}
	}

	private void listItemsRemoved_(ListRemoveEvent event) {
		this.listWidget.remove(event.getIndex(), event.getIndex() + event.getItemsSize() - 1);

		// now that the list has changed, we need to synch the selection
		this.selectionBinding.synchronizeListWidgetSelection();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listItemsMoved(ListMoveEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listItemsMoved_(event);
		}
	}

	private void listItemsMoved_(ListMoveEvent event) {
		int target = event.getTargetIndex();
		int source = event.getSourceIndex();
		int len = event.getLength();
		int loStart = Math.min(target, source);
		int hiStart = Math.max(target, source);
		// make a copy of the affected items...
		String[] subArray = ArrayTools.subArray(this.listWidget.getItems(), loStart, hiStart + len);
		// ...move them around...
		subArray = ArrayTools.move(subArray, target - loStart, source - loStart, len);
		// ...and then put them back
		int i = loStart;
		for (String item : subArray) {
			this.listWidget.setItem(i++, item);
		}

		// now that the list has changed, we need to synch the selection
		this.selectionBinding.synchronizeListWidgetSelection();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listItemsReplaced(ListReplaceEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listItemsReplaced_(event);
		}
	}

	private void listItemsReplaced_(ListReplaceEvent event) {
		int i = event.getIndex();
		for (E item : this.getNewItems(event)) {
			this.listWidget.setItem(i++, this.convert(item));
		}

		// now that the list has changed, we need to synch the selection
		this.selectionBinding.synchronizeListWidgetSelection();
	}

	// minimized scope of suppressed warnings
	@SuppressWarnings("unchecked")
	private Iterable<E> getNewItems(ListReplaceEvent event) {
		return (Iterable<E>) event.getNewItems();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listCleared(ListClearEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listCleared_(event);
		}
	}

	private void listCleared_(@SuppressWarnings("unused") ListClearEvent event) {
		this.listWidget.removeAll();
	}

	/**
	 * The model has changed - synchronize the list widget.
	 */
	void listChanged(ListChangeEvent event) {
		if ( ! this.listWidget.isDisposed()) {
			this.listChanged_(event);
		}
	}

	private void listChanged_(@SuppressWarnings("unused") ListChangeEvent event) {
		this.synchronizeListWidget_();
	}

	/**
	 * Use the string converter to convert the specified item to a
	 * string that can be added to the list widget.
	 */
	private String convert(E item) {
		return this.stringConverter.convertToString(item);
	}


	// ********** list widget events **********

	void listWidgetDisposed(@SuppressWarnings("unused") DisposeEvent event) {
		// the list widget is not yet "disposed" when we receive this event
		// so we can still remove our listeners
		this.listWidget.removeDisposeListener(this.listWidgetDisposeListener);
		this.listModel.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
		this.selectionBinding.dispose();
	}


	// ********** standard methods **********

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.listModel);
	}


	// ********** adapter interfaces **********

	/**
	 * Adapter used by the list widget model binding to query and manipulate
	 * the widget.
	 */
	interface ListWidget {

		/**
		 * Return whether the list widget is "disposed".
		 */
		boolean isDisposed();

		/**
		 * Add the specified dispose listener to the list widget.
		 */
		void addDisposeListener(DisposeListener listener);

		/**
		 * Remove the specified dispose listener from the list widget.
		 */
		void removeDisposeListener(DisposeListener listener);

		/**
		 * Return the list widget's items.
		 */
		String[] getItems();

		/**
		 * Set the list widget's item at the specified index to the specified item.
		 */
		void setItem(int index, String item);

		/**
		 * Set the list widget's items.
		 */
		void setItems(String[] items);

		/**
		 * Add the specified item to the list widget's items at the specified index.
		 */
		void add(String item, int index);

		/**
		 * Remove the specified range of items from the list widget's items.
		 */
		void remove(int start, int end);

		/**
		 * Remove all the items from the list widget.
		 */
		void removeAll();

	}


	/**
	 * Widget-specific selection binding that is controlled by the list widget
	 * model binding.
	 */
	interface SelectionBinding {

		/**
		 * Synchronize the selection binding's widget with the selection model.
		 * <p>
		 * Pre-condition: The widget is not disposed.
		 */
		void synchronizeListWidgetSelection();

		/**
		 * The widget has been disposed; dispose the selection binding.
		 */
		void dispose();


		/**
		 * Useful for list boxes that ignore the selection.
		 */
		final class Null implements SelectionBinding {
			public static final SelectionBinding INSTANCE = new Null();
			public static SelectionBinding instance() {
				return INSTANCE;
			}
			// ensure single instance
			private Null() {
				super();
			}
			public void synchronizeListWidgetSelection() {
				// do nothing
			}
			public void dispose() {
				// do nothing
			}
			@Override
			public String toString() {
				return "SelectionBinding.Null"; //$NON-NLS-1$
			}
		}

	}

}
