/*******************************************************************************
 * Copyright (c) 2007, 2009 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.utility.internal.model.value.swing;

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

import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTListChangeListenerWrapper;
import org.eclipse.jpt.common.utility.internal.model.listener.awt.AWTPropertyChangeListenerWrapper;
import org.eclipse.jpt.common.utility.internal.model.value.CollectionListValueModelAdapter;
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.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.CollectionValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;

/**
 * This TableModel can be used to keep a TableModelListener (e.g. a JTable)
 * in synch with a ListValueModel that holds a collection of model objects,
 * each of which corresponds to a row in the table.
 * Typically, each column of the table will be bound to a different aspect
 * of the contained model objects.
 * 
 * For example, a MWTable has an attribute 'databaseFields' that holds
 * a collection of MWDatabaseFields that would correspond to the rows of
 * a JTable; and each MWDatabaseField has a number
 * of attributes (e.g. name, type, size) that can be bound to the columns of
 * a row in the JTable. As these database fields are added, removed, and
 * changed, this model will keep the listeners aware of the changes.
 * 
 * An instance of this TableModel must be supplied with a
 * list holder (e.g. the 'databaseFields'), which is a value
 * model on the bound collection This is required - the
 * collection itself can be null, but the list value model that
 * holds it is required. Typically this list will be sorted (@see
 * SortedListValueModelAdapter).
 * 
 * This TableModel must also be supplied with a ColumnAdapter that
 * will be used to configure the headers, renderers, editors, and contents
 * of the various columns.
 * 
 * Design decision:
 * Cell listener options (from low space/high time to high space/low time):
 * 	- 1 cell listener listening to every cell (this is the current implementation)
 * 	- 1 cell listener per row
 * 	- 1 cell listener per cell
 */
public class TableModelAdapter<E>
	extends AbstractTableModel
{
	/**
	 * a list of user objects that are converted to
	 * rows via the column adapter
	 */
	private ListValueModel<? extends E> listHolder;
	private final ListChangeListener listChangeListener;

	/**
	 * each row is an array of cell models
	 */
	// declare as ArrayList so we can use #ensureCapacity(int)
	private final ArrayList<WritablePropertyValueModel<Object>[]> rows;

	/**
	 * client-supplied adapter that provides with the various column
	 * settings and converts the objects in the LVM
	 * into an array of cell models
	 */
	private final ColumnAdapter columnAdapter;

	/**
	 * the single listener that listens to every cell's model
	 */
	private final PropertyChangeListener cellListener;


	// ********** constructors **********

	/**
	 * Construct a table model adapter for the specified objects
	 * and adapter.
	 */
	public TableModelAdapter(ListValueModel<? extends E> listHolder, ColumnAdapter columnAdapter) {
		super();
		if (listHolder == null) {
			throw new NullPointerException();
		}
		this.listHolder = listHolder;
		this.columnAdapter = columnAdapter;
		this.listChangeListener = this.buildListChangeListener();
		this.rows = new ArrayList<WritablePropertyValueModel<Object>[]>();
		this.cellListener = this.buildCellListener();
	}

	/**
	 * Construct a table model adapter for the specified objects
	 * and adapter.
	 */
	public TableModelAdapter(CollectionValueModel<? extends E> collectionHolder, ColumnAdapter columnAdapter) {
		this(new CollectionListValueModelAdapter<E>(collectionHolder), columnAdapter);
	}


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

	protected ListChangeListener buildListChangeListener() {
		return new AWTListChangeListenerWrapper(this.buildListChangeListener_());
	}

	protected ListChangeListener buildListChangeListener_() {
		return new ListChangeListener() {
			public void itemsAdded(ListAddEvent event) {
				TableModelAdapter.this.addRows(event.getIndex(), event.getItemsSize(), this.getItems(event));
			}
			public void itemsRemoved(ListRemoveEvent event) {
				TableModelAdapter.this.removeRows(event.getIndex(), event.getItemsSize());
			}
			public void itemsReplaced(ListReplaceEvent event) {
				TableModelAdapter.this.replaceRows(event.getIndex(), this.getNewItems(event));
			}
			public void itemsMoved(ListMoveEvent event) {
				TableModelAdapter.this.moveRows(event.getTargetIndex(), event.getSourceIndex(), event.getLength());
			}
			public void listCleared(ListClearEvent event) {
				TableModelAdapter.this.clearTable();
			}
			public void listChanged(ListChangeEvent event) {
				TableModelAdapter.this.rebuildTable();
			}
			// minimized scope of suppressed warnings
			@SuppressWarnings("unchecked")
			protected Iterable<Object> getItems(ListAddEvent event) {
				return (Iterable<Object>) event.getItems();
			}
			// minimized scope of suppressed warnings
			@SuppressWarnings("unchecked")
			protected Iterable<Object> getNewItems(ListReplaceEvent event) {
				return (Iterable<Object>) event.getNewItems();
			}
			@Override
			public String toString() {
				return "list listener"; //$NON-NLS-1$
			}
		};
	}


	protected PropertyChangeListener buildCellListener() {
		return new AWTPropertyChangeListenerWrapper(this.buildCellListener_());
	}

	protected PropertyChangeListener buildCellListener_() {
		return new PropertyChangeListener() {
			@SuppressWarnings("unchecked")
			public void propertyChanged(PropertyChangeEvent event) {
				TableModelAdapter.this.cellChanged((WritablePropertyValueModel<Object>) event.getSource());
			}
			@Override
			public String toString() {
				return "cell listener"; //$NON-NLS-1$
			}
		};
	}


	// ********** TableModel implementation **********

	public int getColumnCount() {
		return this.columnAdapter.columnCount();
	}

	public int getRowCount() {
		return this.rows.size();
	}

    @Override
	public String getColumnName(int column) {
		return this.columnAdapter.columnName(column);
	}

    @Override
	public Class<?> getColumnClass(int columnIndex) {
		return this.columnAdapter.columnClass(columnIndex);
	}

    @Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return this.columnAdapter.columnIsEditable(columnIndex);
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex);
		return row[columnIndex].getValue();
	}

	@Override
	public void setValueAt(Object value, int rowIndex, int columnIndex) {
		WritablePropertyValueModel<Object>[] row = this.rows.get(rowIndex);
		row[columnIndex].setValue(value);
	}

	/**
	 * Extend to start listening to the underlying model if necessary.
	 */
    @Override
	public void addTableModelListener(TableModelListener l) {
		if (this.hasNoTableModelListeners()) {
			this.engageModel();
		}
		super.addTableModelListener(l);
	}

	/**
	 * Extend to stop listening to the underlying model if necessary.
	 */
    @Override
	public void removeTableModelListener(TableModelListener l) {
		super.removeTableModelListener(l);
		if (this.hasNoTableModelListeners()) {
			this.disengageModel();
		}
	}


	// ********** public API **********

	/**
	 * Return the underlying list model.
	 */
	public ListValueModel<? extends E> getModel() {
		return this.listHolder;
	}

	/**
	 * Set the underlying list model.
	 */
	public void setModel(ListValueModel<E> listHolder) {
		if (listHolder == null) {
			throw new NullPointerException();
		}
		boolean hasListeners = this.hasTableModelListeners();
		if (hasListeners) {
			this.disengageModel();
		}
		this.listHolder = listHolder;
		if (hasListeners) {
			this.engageModel();
			this.fireTableDataChanged();
		}
	}

	/**
	 * Set the underlying collection model.
	 */
	public void setModel(CollectionValueModel<E> collectionHolder) {
		this.setModel(new CollectionListValueModelAdapter<E>(collectionHolder));
	}


	// ********** queries **********

	/**
	 * Return whether this model has no listeners.
	 */
	protected boolean hasNoTableModelListeners() {
		return this.listenerList.getListenerCount(TableModelListener.class) == 0;
	}

	/**
	 * Return whether this model has any listeners.
	 */
	protected boolean hasTableModelListeners() {
		return ! this.hasNoTableModelListeners();
	}


	// ********** behavior **********

	/**
	 * Start listening to the list of objects and the various aspects
	 * of the objects that make up the rows.
	 */
	private void engageModel() {
		this.listHolder.addListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
		this.engageAllCells();
	}

	/**
	 * Convert the objects into rows and listen to the cells.
	 */
	private void engageAllCells() {
		this.rows.ensureCapacity(this.listHolder.size());
		for (Iterator<? extends E> stream = this.listHolder.iterator(); stream.hasNext(); ) {
			WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(stream.next());
			this.engageRow(row);
			this.rows.add(row);
		}
	}

	/**
	 * Listen to the cells in the specified row.
	 */
	private void engageRow(WritablePropertyValueModel<Object>[] row) {
		for (int i = row.length; i-- > 0; ) {
			row[i].addPropertyChangeListener(PropertyValueModel.VALUE, this.cellListener);
		}
	}

	/**
	 * Stop listening.
	 */
	private void disengageModel() {
		this.disengageAllCells();
		this.listHolder.removeListChangeListener(ListValueModel.LIST_VALUES, this.listChangeListener);
	}

	private void disengageAllCells() {
		for (WritablePropertyValueModel<Object>[] row : this.rows) {
			this.disengageRow(row);
		}
		this.rows.clear();
	}

	private void disengageRow(WritablePropertyValueModel<Object>[] row) {
		for (int i = row.length; i-- > 0; ) {
			row[i].removePropertyChangeListener(PropertyValueModel.VALUE, this.cellListener);
		}
	}

	/**
	 * brute-force search for the cell(s) that changed...
	 */
	void cellChanged(WritablePropertyValueModel<Object> cellHolder) {
		for (int i = this.rows.size(); i-- > 0; ) {
			WritablePropertyValueModel<Object>[] row = this.rows.get(i);
			for (int j = row.length; j-- > 0; ) {
				if (row[j] == cellHolder) {
					this.fireTableCellUpdated(i, j);
				}
			}
		}
	}

	/**
	 * convert the items to rows
	 */
	void addRows(int index, int size, Iterable<Object> items) {
		List<WritablePropertyValueModel<Object>[]> newRows = new ArrayList<WritablePropertyValueModel<Object>[]>(size);
		for (Object item : items) {
			WritablePropertyValueModel<Object>[] row = this.columnAdapter.cellModels(item);
			this.engageRow(row);
			newRows.add(row);
		}
		this.rows.addAll(index, newRows);
		this.fireTableRowsInserted(index, index + size - 1);
	}

	void removeRows(int index, int size) {
		for (int i = 0; i < size; i++) {
			this.disengageRow(this.rows.remove(index));
		}
		this.fireTableRowsDeleted(index, index + size - 1);
	}

	void replaceRows(int index, Iterable<Object> items) {
		int i = index;
		for (Object item : items) {
			WritablePropertyValueModel<Object>[] row = this.rows.get(i);
			this.disengageRow(row);
			row = this.columnAdapter.cellModels(item);
			this.engageRow(row);
			this.rows.set(i, row);
			i++;
		}
		this.fireTableRowsUpdated(index, i - 1);
	}

	void moveRows(int targetIndex, int sourceIndex, int length) {
		ArrayList<WritablePropertyValueModel<Object>[]> temp = new ArrayList<WritablePropertyValueModel<Object>[]>(length);
		for (int i = 0; i < length; i++) {
			temp.add(this.rows.remove(sourceIndex));
		}
		this.rows.addAll(targetIndex, temp);

		int start = Math.min(targetIndex, sourceIndex);
		int end = Math.max(targetIndex, sourceIndex) + length - 1;
		this.fireTableRowsUpdated(start, end);
	}

	void clearTable() {
		this.disengageAllCells();
		this.fireTableDataChanged();
	}

	void rebuildTable() {
		this.disengageAllCells();
		this.engageAllCells();
		this.fireTableDataChanged();
	}

}
