/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Matthew Hall - bug 262221
 ******************************************************************************/

package org.eclipse.core.databinding;

import java.util.Collections;

import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.list.ListDiff;
import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.internal.databinding.BindingStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;

/**
 * @since 1.0
 * 
 */
public class ListBinding extends Binding {

	private UpdateListStrategy targetToModel;
	private UpdateListStrategy modelToTarget;
	private IObservableValue validationStatusObservable;
	private boolean updatingTarget;
	private boolean updatingModel;

	private IListChangeListener targetChangeListener = new IListChangeListener() {
		public void handleListChange(ListChangeEvent event) {
			if (!updatingTarget) {
				doUpdate((IObservableList) getTarget(),
						(IObservableList) getModel(), event.diff,
						targetToModel, false, false);
			}
		}
	};
	private IListChangeListener modelChangeListener = new IListChangeListener() {
		public void handleListChange(ListChangeEvent event) {
			if (!updatingModel) {
				doUpdate((IObservableList) getModel(),
						(IObservableList) getTarget(), event.diff,
						modelToTarget, false, false);
			}
		}
	};

	/**
	 * @param target
	 * @param model
	 * @param modelToTargetStrategy
	 * @param targetToModelStrategy
	 */
	public ListBinding(IObservableList target, IObservableList model,
			UpdateListStrategy targetToModelStrategy,
			UpdateListStrategy modelToTargetStrategy) {
		super(target, model);
		this.targetToModel = targetToModelStrategy;
		this.modelToTarget = modelToTargetStrategy;
		if ((targetToModel.getUpdatePolicy() & UpdateValueStrategy.POLICY_UPDATE) != 0) {
			target.addListChangeListener(targetChangeListener);
		} else {
			targetChangeListener = null;
		}
		if ((modelToTarget.getUpdatePolicy() & UpdateValueStrategy.POLICY_UPDATE) != 0) {
			model.addListChangeListener(modelChangeListener);
		} else {
			modelChangeListener = null;
		}
	}

	public IObservableValue getValidationStatus() {
		return validationStatusObservable;
	}

	protected void preInit() {
		validationStatusObservable = new WritableValue(context
				.getValidationRealm(), Status.OK_STATUS, IStatus.class);
	}

	protected void postInit() {
		if (modelToTarget.getUpdatePolicy() == UpdateListStrategy.POLICY_UPDATE) {
			updateModelToTarget();
		}
		if (targetToModel.getUpdatePolicy() != UpdateListStrategy.POLICY_NEVER) {
			validateTargetToModel();
		}
	}

	public void updateModelToTarget() {
		final IObservableList modelList = (IObservableList) getModel();
		modelList.getRealm().exec(new Runnable() {
			public void run() {
				ListDiff diff = Diffs.computeListDiff(Collections.EMPTY_LIST,
						modelList);
				doUpdate(modelList, (IObservableList) getTarget(), diff,
						modelToTarget, true, true);
			}
		});
	}

	public void updateTargetToModel() {
		final IObservableList targetList = (IObservableList) getTarget();
		targetList.getRealm().exec(new Runnable() {
			public void run() {
				ListDiff diff = Diffs.computeListDiff(Collections.EMPTY_LIST,
						targetList);
				doUpdate(targetList, (IObservableList) getModel(), diff,
						targetToModel, true, true);
			}
		});
	}

	public void validateModelToTarget() {
		// nothing for now
	}

	public void validateTargetToModel() {
		// nothing for now
	}

	/*
	 * This method may be moved to UpdateListStrategy in the future if clients
	 * need more control over how the two lists are kept in sync.
	 */
	private void doUpdate(final IObservableList source,
			final IObservableList destination, final ListDiff diff,
			final UpdateListStrategy updateListStrategy,
			final boolean explicit, final boolean clearDestination) {
		final int policy = updateListStrategy.getUpdatePolicy();
		if (policy != UpdateListStrategy.POLICY_NEVER) {
			if (policy != UpdateListStrategy.POLICY_ON_REQUEST || explicit) {
				destination.getRealm().exec(new Runnable() {
					public void run() {
						if (destination == getTarget()) {
							updatingTarget = true;
						} else {
							updatingModel = true;
						}
						final MultiStatus multiStatus = BindingStatus.ok();

						try {
							if (clearDestination) {
								destination.clear();
							}
							diff.accept(new ListDiffVisitor() {
								boolean useMoveAndReplace = updateListStrategy
										.useMoveAndReplace();

								public void handleAdd(int index, Object element) {
									IStatus setterStatus = updateListStrategy
											.doAdd(destination,
													updateListStrategy
															.convert(element),
													index);

									mergeStatus(multiStatus, setterStatus);
								}

								public void handleRemove(int index,
										Object element) {
									IStatus setterStatus = updateListStrategy
											.doRemove(destination, index);

									mergeStatus(multiStatus, setterStatus);
								}

								public void handleMove(int oldIndex,
										int newIndex, Object element) {
									if (useMoveAndReplace) {
										IStatus setterStatus = updateListStrategy
												.doMove(destination, oldIndex,
														newIndex);

										mergeStatus(multiStatus, setterStatus);
									} else {
										super.handleMove(oldIndex, newIndex,
												element);
									}
								}

								public void handleReplace(int index,
										Object oldElement, Object newElement) {
									if (useMoveAndReplace) {
										IStatus setterStatus = updateListStrategy
												.doReplace(destination, index,
														newElement);

										mergeStatus(multiStatus, setterStatus);
									} else {
										super.handleReplace(index, oldElement,
												newElement);
									}
								}
							});
							// TODO - at this point, the two lists will be out
							// of sync if an error occurred...
						} finally {
							validationStatusObservable.setValue(multiStatus);

							if (destination == getTarget()) {
								updatingTarget = false;
							} else {
								updatingModel = false;
							}
						}
					}
				});
			}
		}
	}

	/**
	 * Merges the provided <code>newStatus</code> into the
	 * <code>multiStatus</code>.
	 * 
	 * @param multiStatus
	 * @param newStatus
	 */
	/* package */void mergeStatus(MultiStatus multiStatus, IStatus newStatus) {
		if (!newStatus.isOK()) {
			multiStatus.add(newStatus);
		}
	}

	public void dispose() {
		if (targetChangeListener != null) {
			((IObservableList) getTarget())
					.removeListChangeListener(targetChangeListener);
			targetChangeListener = null;
		}
		if (modelChangeListener != null) {
			((IObservableList) getModel())
					.removeListChangeListener(modelChangeListener);
			modelChangeListener = null;
		}
		super.dispose();
	}
}
