/*******************************************************************************
 * 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;

import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;

/**
 * A <code>BufferedWritablePropertyValueModel</code> is used to hold a temporary copy of the value
 * in another property value model (the "wrapped" value holder). The application
 * can modify this temporary copy, ad nauseam; but the temporary copy is only
 * passed through to the "wrapped" value holder when the trigger "accepts" the
 * buffered value. Alternatively, the application can "reset" the buffered value
 * to the original, "wrapped" value.
 * <p>
 * The trigger is another {@link PropertyValueModel} that holds a {@link Boolean}
 * and the application changes the trigger's value to true on "accept", false on "reset".
 * Typically, in a dialog:<ul>
 * <li>pressing the "OK" button will trigger an "accept" and close the dialog
 * <li>pressing the "Cancel" button will simply close the dialog,
 *   dropping the "buffered" values into the bit bucket
 * <li>pressing the "Apply" button will trigger an "accept" and leave the dialog open
 * <li>pressing the "Restore" button will trigger a "reset" and leave the dialog open
 * </ul>
 * <p>
 * A number of buffered property value models can wrap another set of
 * property aspect adapters that adapt the various aspects of a single
 * domain model. All the bufferd property value models can be hooked to the
 * same trigger, and that trigger is controlled by the application, typically
 * via the OK button in a dialog.
 * 
 * @see PropertyAspectAdapter
 */
public class BufferedWritablePropertyValueModel<T>
	extends PropertyValueModelWrapper<T>
	implements WritablePropertyValueModel<T>
{

	/**
	 * We cache the value here until it is accepted and passed
	 * through to the wrapped value holder.
	 */
	protected T bufferedValue;

	/**
	 * This is set to true when we are "accepting" the buffered value
	 * and passing it through to the wrapped value holder. This allows
	 * us to ignore the property change event fired by the wrapped
	 * value holder.
	 * (We can't stop listening to the wrapped value holder, because
	 * if we are the only listener that could "deactivate" the wrapped
	 * value holder.)
	 */
	protected boolean accepting;

	/**
	 * This is the trigger that indicates whether the buffered value
	 * should be accepted or reset.
	 */
	protected final PropertyValueModel<Boolean> triggerHolder;

	/** This listens to the trigger holder. */
	protected final PropertyChangeListener triggerChangeListener;

	/**
	 * This flag indicates whether our buffered value has been assigned
	 * a value and is possibly out of synch with the wrapped value.
	 */
	protected boolean buffering;


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

	/**
	 * Construct a buffered property value model with the specified wrapped
	 * property value model and trigger holder.
	 */
	public BufferedWritablePropertyValueModel(WritablePropertyValueModel<T> valueHolder, PropertyValueModel<Boolean> triggerHolder) {
		super(valueHolder);
		if (triggerHolder == null) {
			throw new NullPointerException();
		}
		this.triggerHolder = triggerHolder;
		this.bufferedValue = null;
		this.buffering = false;
		this.accepting = false;
		this.triggerChangeListener = this.buildTriggerChangeListener();
	}


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

	protected PropertyChangeListener buildTriggerChangeListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				BufferedWritablePropertyValueModel.this.triggerChanged(event);
			}
			@Override
			public String toString() {
				return "trigger change listener"; //$NON-NLS-1$
			}
		};
	}


	// ********** ValueModel implementation **********

	/**
	 * If we are currently "buffering" a value, return that;
	 * otherwise, return the wrapped value.
	 */
	public T getValue() {
		return this.buffering ? this.bufferedValue : this.valueHolder.getValue();
	}

	/**
	 * Assign the new value to our "buffered" value.
	 * It will be pushed to the wrapped value holder
	 * when the trigger is "accepted".
	 */
	public void setValue(T value) {
		if (this.buffering) {
			if (this.valuesAreEqual(value, this.valueHolder.getValue())) {
				// the buffered value is being set back to the original value
				this.reset();
			} else {
				// the buffered value is being changed
				Object old = this.bufferedValue;
				this.bufferedValue = value;
				this.firePropertyChanged(VALUE, old, value);
			}
		} else {
			if (this.valuesAreEqual(value, this.valueHolder.getValue())) {
				// the buffered value is being set to the same value as the original value - ignore
			} else {
				// the buffered value is being set for the first time
				Object old = this.valueHolder.getValue();
				this.bufferedValue = value;
				this.buffering = true;
				this.firePropertyChanged(VALUE, old, value);
			}
		}
	}


	// ********** PropertyValueModelWrapper extensions **********

	/**
	 * extend to engage the trigger holder also
	 */
	@Override
	protected void engageModel() {
		super.engageModel();
		this.triggerHolder.addPropertyChangeListener(VALUE, this.triggerChangeListener);
	}

	/**
	 * extend to disengage the trigger holder also
	 */
	@Override
	protected void disengageModel() {
		this.triggerHolder.removePropertyChangeListener(VALUE, this.triggerChangeListener);
		super.disengageModel();
	}


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

	/**
	 * If we are currently "accepting" the value (i.e passing it on to the
	 * "wrapped" model), ignore change notifications, since we caused
	 * them and our own listeners are already aware of the change.
	 */
	@Override
	protected void valueChanged(PropertyChangeEvent event) {
		if ( ! this.accepting) {
			this.valueChanged_(event);
		}
	}

	/**
	 * If we have a "buffered" value, check whether the "wrapped" value has
	 * changed to be the same as the "buffered" value. If it has, stop "buffering";
	 * if not, do nothing.
	 * If we do not yet have a "buffered" value, simply propagate the
	 * change notification with the buffered model as the source.
	 */
	protected void valueChanged_(PropertyChangeEvent event) {
		if (this.buffering) {
			if (this.valuesAreEqual(event.getNewValue(), this.bufferedValue)) {
				// the buffered value is being set back to the original value
				this.reset();
			} else {
				this.handleChangeConflict(event);
			}
		} else {
			this.firePropertyChanged(event.clone(this));
		}
	}

	/**
	 * By default, if we have a "buffered" value and the "wrapped" value changes,
	 * we simply ignore the new "wrapped" value and simply overlay it with the
	 * "buffered" value if it is "accepted". ("Last One In Wins" concurrency model)
	 * Subclasses can override this method to change that behavior with a
	 * different concurrency model. For example, you could drop the "buffered" value
	 * and replace it with the new "wrapped" value, or you could throw an
	 * exception.
	 */
	protected void handleChangeConflict(@SuppressWarnings("unused") PropertyChangeEvent event) {
		// the default is to do nothing
	}

	/**
	 * The trigger changed:<ul>
	 * <li>If it is now true, "accept" the buffered value and push
	 * it to the wrapped value holder.
	 * <li>If it is now false, "reset" the buffered value to its original value.
	 * </ul>
	 */
	protected void triggerChanged(PropertyChangeEvent event) {
		// if nothing has been "buffered", we don't need to do anything:
		// nothing needs to be passed through; nothing needs to be reset;
		if (this.buffering) {
			if (((Boolean) event.getNewValue()).booleanValue()) {
				this.accept();
			} else {
				this.reset();
			}
		}
	}

	protected void accept() {
		// set the accepting flag so we ignore any events
		// fired by the wrapped value holder
		this.accepting = true;
		try {
			this.getValueHolder().setValue(this.bufferedValue);
		} finally {
			this.bufferedValue = null;
			this.buffering = false;
			// clear the flag once the "accept" is complete
			this.accepting = false;
		}
	}

	protected void reset() {
		// notify our listeners that our value has been reset
		Object old = this.bufferedValue;
		this.bufferedValue = null;
		this.buffering = false;
		this.firePropertyChanged(VALUE, old, this.valueHolder.getValue());
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.getValue());
	}


	// ********** convenience methods **********

	/**
	 * Return whether the buffered model is currently "buffering"
	 * a value.
	 */
	public boolean isBuffering() {
		return this.buffering;
	}

	/**
	 * Our constructor accepts only a {@link WritablePropertyValueModel}{@code<T>}.
	 */
	@SuppressWarnings("unchecked")
	protected WritablePropertyValueModel<T> getValueHolder() {
		return (WritablePropertyValueModel<T>) this.valueHolder;
	}


	// ********** inner class **********

	/**
	 * <code>Trigger</code> is a special property value model that only maintains its
	 * value (of <code>true</code> or <code>false</code>) during the change notification caused by
	 * {@link #setValue(T)}. In other words, a <code>Trigger</code>
	 * only has a valid value when it is being set.
	 */
	public static class Trigger extends SimplePropertyValueModel<Boolean> {


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

		/**
		 * Construct a trigger with a null value.
		 */
		public Trigger() {
			super();
		}


		// ********** ValueModel implementation **********

		/**
		 * Extend so that this method can only be invoked during
		 * change notification triggered by {@link #setValue(Object)}.
		 */
		@Override
		public Boolean getValue() {
			if (this.value == null) {
				throw new IllegalStateException("The method Trigger.getValue() may only be called during change notification."); //$NON-NLS-1$
			}
			return this.value;
		}

		/**
		 * Extend to reset the value to <code>null</code> once all the
		 * listeners have been notified.
		 */
		@Override
		public void setValue(Boolean value) {
			super.setValue(value);
			this.value = null;
		}


		// ********** convenience methods **********

		/**
		 * Set the trigger's value:<ul>
		 * 	<li><code>true</code> indicates "accept"
		 * 	<li><code>false</code> indicates "reset"
		 * </ul>
		 */
		public void setValue(boolean value) {
			this.setValue(Boolean.valueOf(value));
		}

		/**
		 * Return the trigger's value:<ul>
		 * 	<li><code>true</code> indicates "accept"
		 * 	<li><code>false</code> indicates "reset"
		 * </ul>
		 * This method can only be invoked during change notification.
		 */
		public boolean booleanValue() {
			return this.getValue().booleanValue();
		}

		/**
		 * Accept the trigger (i.e. set its value to <code>true</code>).
		 */
		public void accept() {
			this.setValue(true);
		}

		/**
		 * Return whether the trigger has been accepted
		 * (i.e. its value was changed to <code>true</code>).
		 * This method can only be invoked during change notification.
		 */
		public boolean isAccepted() {
			return this.booleanValue();
		}

		/**
		 * Reset the trigger (i.e. set its value to <code>false</code>).
		 */
		public void reset() {
			this.setValue(false);
		}

		/**
		 * Return whether the trigger has been reset
		 * (i.e. its value was changed to <code>false</code>).
		 * This method can only be invoked during change notification.
		 */
		public boolean isReset() {
			return ! this.booleanValue();
		}

	}

}
