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

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

import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.model.event.ListChangeEvent;
import org.eclipse.jpt.utility.model.listener.ListChangeListener;
import org.eclipse.jpt.utility.model.value.ListValueModel;

/**
 * Helper class that keeps an internal list in synch with the
 * list held by a list value model.
 */
public class CoordinatedList<E> implements List<E>, ListChangeListener, ListDataListener {
	private List<E> list = new ArrayList<E>();

	public CoordinatedList(ListValueModel<E> listValueModel) {
		listValueModel.addListChangeListener(ListValueModel.LIST_VALUES, this);
		for (Iterator<E> stream = listValueModel.iterator(); stream.hasNext(); ) {
			this.add(stream.next());
		}
	}

	public CoordinatedList(ListModel listModel) {
		listModel.addListDataListener(this);
		for (int i = 0; i < listModel.getSize(); i++) {
			this.add(i, this.getElementAt(listModel, i));
		}
	}


	// ********** List implementation **********

	public void add(int index, E element) {
		this.list.add(index, element);
	}

	public boolean add(E o) {
		return this.list.add(o);
	}

	public boolean addAll(Collection<? extends E> c) {
		return this.list.addAll(c);
	}

	public boolean addAll(int index, Collection<? extends E> c) {
		return this.list.addAll(index, c);
	}

	public void clear() {
		this.list.clear();
	}

	public boolean contains(Object o) {
		return this.list.contains(o);
	}

	public boolean containsAll(Collection<?> c) {
		return this.list.containsAll(c);
	}

	public E get(int index) {
		return this.list.get(index);
	}

	public int indexOf(Object o) {
		return this.list.indexOf(o);
	}

	public boolean isEmpty() {
		return this.list.isEmpty();
	}

	public Iterator<E> iterator() {
		return this.list.iterator();
	}

	public int lastIndexOf(Object o) {
		return this.list.lastIndexOf(o);
	}

	public ListIterator<E> listIterator() {
		return this.list.listIterator();
	}

	public ListIterator<E> listIterator(int index) {
		return this.list.listIterator(index);
	}

	public E remove(int index) {
		return this.list.remove(index);
	}

	public boolean remove(Object o) {
		return this.list.remove(o);
	}

	public boolean removeAll(Collection<?> c) {
		return this.list.removeAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return this.list.retainAll(c);
	}

	public E set(int index, E element) {
		return this.list.set(index, element);
	}

	public int size() {
		return this.list.size();
	}

	public List<E> subList(int fromIndex, int toIndex) {
		return this.list.subList(fromIndex, toIndex);
	}

	public Object[] toArray() {
		return this.list.toArray();
	}

	public <T> T[] toArray(T[] a) {
		return this.list.toArray(a);
	}


	// ********** ListChangeListener implementation **********

	public void itemsAdded(ListChangeEvent e) {
		int i = e.getIndex();
		for (Iterator<E> stream = this.items(e); stream.hasNext(); ) {
			this.list.add(i++, stream.next());
		}
	}

	public void itemsRemoved(ListChangeEvent e) {
		int i = e.getIndex();
		for (Iterator<E> stream = this.items(e); stream.hasNext(); ) {
			stream.next();
			this.list.remove(i);
		}
	}

	public void itemsReplaced(ListChangeEvent e) {
		int i = e.getIndex();
		for (Iterator<E> stream = this.items(e); stream.hasNext(); ) {
			this.list.set(i++, stream.next());
		}
	}

	public void itemsMoved(ListChangeEvent e) {
		CollectionTools.move(this.list, e.getTargetIndex(), e.getSourceIndex(), e.getMoveLength());
	}

	public void listCleared(ListChangeEvent e) {
		this.list.clear();
	}

	public void listChanged(ListChangeEvent e) {
		this.list.clear();
		CollectionTools.addAll(this.list, this.getSource(e).iterator());
	}


	// ********** ListDataListener implementation **********

	public void contentsChanged(ListDataEvent e) {
		this.list.clear();
		ListModel lm = (ListModel) e.getSource();
		int size = lm.getSize();
		for (int i = 0; i < size; i++) {
			this.list.add(i, this.getElementAt(lm, i));
		}
	}

	public void intervalAdded(ListDataEvent e) {
		ListModel lm = (ListModel) e.getSource();
		int start = Math.min(e.getIndex0(), e.getIndex1());
		int end = Math.max(e.getIndex0(), e.getIndex1());
		for (int i = start; i <= end; i++) {
			this.list.add(i, this.getElementAt(lm, i));
		}
	}

	public void intervalRemoved(ListDataEvent e) {
		int start = Math.min(e.getIndex0(), e.getIndex1());
		int end = Math.max(e.getIndex0(), e.getIndex1());
		int length = end - start + 1;
		for (int i = 1; i <= length; i++) {
			this.list.remove(start);
		}
	}


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

    @Override
	public boolean equals(Object o) {
		return this.list.equals(o);
	}

    @Override
	public int hashCode() {
		return this.list.hashCode();
	}

    @Override
	public String toString() {
		return this.list.toString();
	}


	// ********** internal methods **********

	/**
	 * minimize the scope of the suppressed warnings.=
	 */
	@SuppressWarnings("unchecked")
	private E getElementAt(ListModel listModel, int index) {
		return (E) listModel.getElementAt(index);
	}

	/**
	 * minimize the scope of the suppressed warnings.=
	 */
	@SuppressWarnings("unchecked")
	private Iterator<E> items(ListChangeEvent event) {
		return (Iterator<E>) event.items();
	}

	/**
	 * minimize the scope of the suppressed warnings.=
	 */
	@SuppressWarnings("unchecked")
	private ListValueModel<E> getSource(ListChangeEvent event) {
		return (ListValueModel<E>) event.getSource();
	}

}
