/*=============================================================================#
 # Copyright (c) 2005, 2020 IBM Corporation and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - org.eclipse.jdt: initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.value.AbstractVetoableValue;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;


/**
 * {@link IObservable} implementation that wraps a {@link SnippetEditor}. The time at which
 * listeners should be notified about changes to the text is specified on construction.
 * 
 * <dl>
 *   <dt>Events:</dt>
 *   <dd>If the update event type (specified on construction) is <code>SWT.Modify</code> a value
 *       change event will be fired on every key stroke. If the update event type is
 *       <code>SWT.FocusOut</code> a value change event will be fired on focus out. When in either
 *       mode if the user is entering text and presses [Escape] the value will be reverted back to
 *       the last value set using doSetValue(). Regardless of the update event type a value
 *       changing event will fire on verify to enable vetoing of changes.</dd>
 * </dl>
 */
@NonNullByDefault
public class SnippetEditorObservable extends AbstractVetoableValue<String> {
	
	/**
	 * {@link Text} widget that this is being observed.
	 */
	private final StyledText text;
	
	/**
	 * Flag to track when the model is updating the widget. When
	 * <code>true</code> the handlers for the SWT events should not process
	 * the event as this would cause an infinite loop.
	 */
	private boolean updating= false;
	
	/**
	 * SWT event that on firing this observable will fire change events to its
	 * listeners.
	 */
	private final int updateEventType;
	
	/**
	 * Valid types for the {@link #updateEventType}.
	 */
	private static final int[] validUpdateEventTypes= new int[] { SWT.Modify,
			SWT.FocusOut, SWT.None };
	
	/**
	 * Previous value of the Text.
	 */
	private String oldValue;
	
	private final Listener updateListener= new Listener() {
		@Override
		public void handleEvent(final Event event) {
			if (!SnippetEditorObservable.this.updating) {
				final String newValue= SnippetEditorObservable.this.text.getText();
				
				if (!newValue.equals(SnippetEditorObservable.this.oldValue)) {
					fireValueChange(Diffs.createValueDiff(SnippetEditorObservable.this.oldValue, newValue));
					SnippetEditorObservable.this.oldValue= newValue;
				}
			}
		}
	};
	
	private final VerifyListener verifyListener;
	
	
	/**
	 * Constructs a new instance.
	 * 
	 * @param realm can not be <code>null</code>
	 * @param text
	 * @param updateEventType
	 */
	public SnippetEditorObservable(final Realm realm, final SnippetEditor editor,
			final int updateEventType) {
		super(realm);
		
		boolean eventValid= false;
		for (int i= 0; !eventValid && i < validUpdateEventTypes.length; i++) {
			eventValid= (updateEventType == validUpdateEventTypes[i]);
		}
		if (!eventValid) {
			throw new IllegalArgumentException(
					"UpdateEventType [" + updateEventType + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
		}
		
		this.text= editor.getSourceViewer().getTextWidget();
		this.updateEventType= updateEventType;
		if (updateEventType != SWT.None) {
			this.text.addListener(updateEventType, this.updateListener);
		}
		
		this.oldValue= this.text.getText();
		
		this.verifyListener= new VerifyListener() {
			@Override
			public void verifyText(final VerifyEvent e) {
				if (!SnippetEditorObservable.this.updating) {
					final String currentText= SnippetEditorObservable.this.text.getText();
					final String newText= currentText.substring(0, e.start) + e.text
							+ currentText.substring(e.end);
					if (!fireValueChanging(Diffs.createValueDiff(currentText,
							newText))) {
						e.doit= false;
					}
				}
			}
		};
		this.text.addVerifyListener(this.verifyListener);
		
		this.text.addDisposeListener(new DisposeListener(){
			@Override
			public void widgetDisposed(final DisposeEvent e) {
				SnippetEditorObservable.this.dispose();
			}
		});
	}
	
	
	/**
	 * Sets the bound {@link Text Text's} text to the passed <code>value</code>.
	 * 
	 * @param value
	 *            new value, String expected
	 * @see org.eclipse.core.databinding.observable.value.AbstractVetoableValue#doSetApprovedValue(java.lang.Object)
	 * @throws ClassCastException
	 *             if the value is anything other than a String
	 */
	@Override
	protected void doSetApprovedValue(final String value) {
		try {
			this.updating= true;
			this.text.setText((value == null) ? "" : value.toString()); //$NON-NLS-1$
			this.oldValue= this.text.getText();
		} finally {
			this.updating= false;
		}
	}
	
	/**
	 * Returns the current value of the {@link Text}.
	 * 
	 * @see org.eclipse.core.databinding.observable.value.AbstractVetoableValue#doGetValue()
	 */
	@Override
	public String doGetValue() {
		return this.oldValue= this.text.getText();
	}
	
	/**
	 * Returns the type of the value from {@link #doGetValue()}, i.e.
	 * String.class
	 * 
	 * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType()
	 */
	@Override
	public Object getValueType() {
		return String.class;
	}
	
	@Override
	public void dispose() {
		if (!this.text.isDisposed()) {
			if (this.updateEventType != SWT.None) {
				this.text.removeListener(this.updateEventType, this.updateListener);
			}
			this.text.removeVerifyListener(this.verifyListener);
		}
		super.dispose();
	}
	
}
