/*******************************************************************************
 * 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.ui.internal.utility.swt;

import java.util.ArrayList;

import org.eclipse.jpt.ui.internal.listeners.SWTListChangeListenerWrapper;
import org.eclipse.jpt.utility.internal.ArrayTools;
import org.eclipse.jpt.utility.internal.StringConverter;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.model.event.ListAddEvent;
import org.eclipse.jpt.utility.model.event.ListChangeEvent;
import org.eclipse.jpt.utility.model.event.ListClearEvent;
import org.eclipse.jpt.utility.model.event.ListMoveEvent;
import org.eclipse.jpt.utility.model.event.ListRemoveEvent;
import org.eclipse.jpt.utility.model.event.ListReplaceEvent;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.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$
			}
		}

	}

}
