/*******************************************************************************
 * Copyright (c) 2006 The Pampered Chef 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:
 *     The Pampered Chef - initial API and implementation
 ******************************************************************************/

package org.eclipse.jface.examples.databinding.mask;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.eclipse.jface.examples.databinding.mask.internal.EditMaskParser;
import org.eclipse.jface.examples.databinding.mask.internal.SWTUtil;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;

/**
 * Ensures text widget has the format specified by the edit mask.  Edit masks
 * are currently defined as follows:
 * 
 * The following characters are reserved words that match specific kinds of 
 * characters:
 * 
 * # - digits 0-9
 * A - uppercase A-Z
 * a - upper or lowercase a-z, A-Z
 * n - alphanumeric 0-9, a-z, A-Z
 *
 * All other characters are literals.  The above characters may be turned into
 * literals by preceeding them with a backslash.  Use two backslashes to
 * denote a backslash.
 * 
 * Examples:
 * 
 * (###) ###-####  U.S. phone number 
 * ###-##-####     U.S. Social Security number
 * \\\###          A literal backslash followed by a literal pound symbol followed by two digits
 * 
 * Ideas for future expansion:
 * 
 * Quantifiers as postfix modifiers to a token.  ie:
 * 
 * #{1, 2}/#{1,2}/####   MM/DD/YYYY date format allowing 1 or 2 digit month or day
 * 
 * Literals may only be quantified as {0,1} which means that they only appear
 * if placeholders on both sides of the literal have data.  This will be used
 * along with:
 * 
 * Right-to-left support for numeric entry.  When digits are being entered and
 * a decimal point is present in the mask, digits to the left of the decimal
 * are entered right-to-left but digits to the right of the decimal left-to-right.
 * This might need to be a separate type of edit mask. (NumericMask, maybe?)
 * 
 * Example:
 * 
 * $#{0,3},{0,1}#{0,3}.#{0,2}  ie: $123,456.12 or $12.12 or $1,234.12 or $123.12
 *
 * 
 * Here's the basic idea of how the current implementation works (the actual 
 * implementation is slightly more abstracted and complicated than this):
 * 
 * We always let the verify event pass if the user typed a new character or selected/deleted anything.
 * During the verify event, we post an async runnable.
 * Inside that async runnable, we:
 *   - Remember the selection position
 *   - getText(), then
 *   - Strip out all literal characters from text
 *   - Truncate the resulting string to raw length of edit mask without literals
 *   - Insert literal characters back in the correct positions
 *   - setText() the resulting string
 *   - reset the selection to the correct location
 *   
 * @since 3.3
 */
public class EditMask {
	
	public static final String FIELD_TEXT = "text";
	public static final String FIELD_RAW_TEXT = "rawText";
	public static final String FIELD_COMPLETE = "complete";
	protected Text text;
	protected EditMaskParser editMaskParser;
	private boolean fireChangeOnKeystroke = true;
	private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
	
	protected String oldValidRawText = "";
	protected String oldValidText = ""; 
	
	/**
	 * Creates an instance that wraps around a text widget and manages its<br>
	 * formatting.
	 * 
	 * @param text
	 * @param editMask
	 */
	public EditMask(Text text) {
		this.text = text;
	}
	
	/**
	 * @return the underlying Text control used by EditMask
	 */
	public Text getControl() {
		return this.text;
	}
	
	/**
	 * Set the edit mask string on the edit mask control.
	 * 
	 * @param editMask The edit mask string
	 */
	public void setMask(String editMask) {
		editMaskParser = new EditMaskParser(editMask);
		text.addVerifyListener(verifyListener);
		text.addFocusListener(focusListener);
		text.addDisposeListener(disposeListener);
		updateTextField.run();
		oldValidText = text.getText();
		oldValidRawText = editMaskParser.getRawResult();
	}

    /**
     * @param string Sets the text string in the receiver
     */
    public void setText(String string) {
    	String oldValue = text.getText();
    	if (editMaskParser != null) {
			editMaskParser.setInput(string);
			String formattedResult = editMaskParser.getFormattedResult();
			text.setText(formattedResult);
			firePropertyChange(FIELD_TEXT, oldValue, formattedResult);
    	} else {
    		text.setText(string);
			firePropertyChange(FIELD_TEXT, oldValue, string);
    	}
		oldValidText = text.getText();
		oldValidRawText = editMaskParser.getRawResult();
	}

	/**
	 * @return the actual (formatted) text
	 */
	public String getText() {
		if (editMaskParser != null) {
			return editMaskParser.getFormattedResult();
		}
		return text.getText();
	}
	
	/**
	 * setRawText takes raw text as a parameter but formats it before
	 * setting the text in the Text control.
	 * 
	 * @param string the raw (unformatted) text
	 */
	public void setRawText(String string)  {
		if (string == null) {
			string = "";
		}
		if (editMaskParser != null) {
			String oldValue = editMaskParser.getRawResult();
			editMaskParser.setInput(string);
			text.setText(editMaskParser.getFormattedResult());
			firePropertyChange(FIELD_RAW_TEXT, oldValue, string);
		} else {
	    	String oldValue = text.getText();
    		text.setText(string);
			firePropertyChange(FIELD_RAW_TEXT, oldValue, string);
		}
		oldValidText = text.getText();
		oldValidRawText = editMaskParser.getRawResult();
	}

	/**
	 * @return The input text with literals removed
	 */
	public String getRawText() {
		if (editMaskParser != null) {
			return editMaskParser.getRawResult();
		}
		return text.getText();
	}
	
	/**
	 * @return true if the field is complete according to the mask; false otherwise
	 */
	public boolean isComplete() {
		if (editMaskParser == null) {
			return true;
		}
		return editMaskParser.isComplete();
	}
	
	/**
	 * Returns the placeholder character.  The placeholder 
	 * character must be a different character than any character that is 
	 * allowed as input anywhere in the edit mask.  For example, if the edit
	 * mask permits spaces to be used as input anywhere, the placeholder 
	 * character must be something other than a space character.
	 * <p>
	 * The space character is the default placeholder character.
	 * 
	 * @return the placeholder character
	 */
	public char getPlaceholder() {
		if (editMaskParser == null) {
			throw new IllegalArgumentException("Have to set an edit mask first");
		}
		return editMaskParser.getPlaceholder();
	}
	
	/**
	 * Sets the placeholder character for the edit mask.  The placeholder 
	 * character must be a different character than any character that is 
	 * allowed as input anywhere in the edit mask.  For example, if the edit
	 * mask permits spaces to be used as input anywhere, the placeholder 
	 * character must be something other than a space character.
	 * <p>
	 * The space character is the default placeholder character.
	 * 
	 * @param placeholder The character to use as a placeholder
	 */
	public void setPlaceholder(char placeholder) {
		if (editMaskParser == null) {
			throw new IllegalArgumentException("Have to set an edit mask first");
		}
		editMaskParser.setPlaceholder(placeholder);
		updateTextField.run();
		oldValidText = text.getText();
	}

	/**
	 * Indicates if change notifications will be fired after every keystroke
	 * that affects the value of the rawText or only when the value is either
	 * complete or empty.
	 * 
	 * @return true if every change (including changes from one invalid state to
	 *         another) triggers a change event; false if only empty or valid
	 *         values trigger a change event.  Defaults to false.
	 */
	public boolean isFireChangeOnKeystroke() {
		return fireChangeOnKeystroke;
	}

	/**
	 * Sets if change notifications will be fired after every keystroke that
	 * affects the value of the rawText or only when the value is either
	 * complete or empty.
	 * 
	 * @param fireChangeOnKeystroke
	 *            true if every change (including changes from one invalid state
	 *            to another) triggers a change event; false if only empty or
	 *            valid values trigger a change event.  Defaults to false.
	 */
	public void setFireChangeOnKeystroke(boolean fireChangeOnKeystroke) {
		this.fireChangeOnKeystroke = fireChangeOnKeystroke;
	}

	/**
	 * JavaBeans boilerplate code...
	 * 
	 * @param listener
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		propertyChangeSupport.addPropertyChangeListener(listener);
	}

	/**
	 * JavaBeans boilerplate code...
	 * 
	 * @param propertyName
	 * @param listener
	 */
	public void addPropertyChangeListener(String propertyName,
			PropertyChangeListener listener) {
		propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
	}

	/**
	 * JavaBeans boilerplate code...
	 * 
	 * @param listener
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		propertyChangeSupport.removePropertyChangeListener(listener);
	}

	/**
	 * JavaBeans boilerplate code...
	 * 
	 * @param propertyName
	 * @param listener
	 */
	public void removePropertyChangeListener(String propertyName,
			PropertyChangeListener listener) {
		propertyChangeSupport.removePropertyChangeListener(propertyName,
				listener);
	}

	private boolean isEitherValueNotNull(Object oldValue, Object newValue) {
		return oldValue != null || newValue != null;
	}

	private void firePropertyChange(String propertyName, Object oldValue,
			Object newValue) {
		if (isEitherValueNotNull(oldValue, newValue)) {
			propertyChangeSupport.firePropertyChange(propertyName,
					oldValue, newValue);
		}
	}

	protected boolean updating = false;

	protected int oldSelection = 0;
	protected int selection = 0;
	protected String oldRawText = "";
   protected boolean replacedSelectedText = false;
	
	private VerifyListener verifyListener = new VerifyListener() {
		public void verifyText(VerifyEvent e) {
         // If the edit mask is already full, don't let the user type
         // any new characters
         if (editMaskParser.isComplete() && // should eventually be .isFull() to account for optional characters
               e.start == e.end && 
               e.text.length() > 0) 
         {
            e.doit=false;
            return;
         }
         
			oldSelection = selection;
			Point selectionRange = text.getSelection();
         selection = selectionRange.x;
         
			if (!updating) {
   			replacedSelectedText = false;
   			if (selectionRange.y - selectionRange.x > 0 && e.text.length() > 0) {
   			   replacedSelectedText = true;
   			}
            // If the machine is loaded down (ie: spyware, malware), we might
            // get another keystroke before asyncExec can process, so we use 
            // greedyExec instead.
            SWTUtil.greedyExec(Display.getCurrent(), updateTextField);
//				Display.getCurrent().asyncExec(updateTextField);
         }
		}
	};

	private Runnable updateTextField = new Runnable() {
		public void run() {
			updating = true;
			try {
				if (!text.isDisposed()) {
					Boolean oldIsComplete = new Boolean(editMaskParser.isComplete());
				
					editMaskParser.setInput(text.getText());
					text.setText(editMaskParser.getFormattedResult());
					String newRawText = editMaskParser.getRawResult();
				
					updateSelectionPosition(newRawText);
					firePropertyChangeEvents(oldIsComplete, newRawText);
				}
			} finally {
				updating = false;
			}
		}

		private void updateSelectionPosition(String newRawText) {

         // Adjust the selection
         if (isInsertingNewCharacter(newRawText) || replacedSelectedText) {
            // Find the position after where the new character was actually inserted
            int selectionDelta = 
               editMaskParser.getNextInputPosition(oldSelection)
               - oldSelection;
            if (selectionDelta == 0) {
               selectionDelta = editMaskParser.getNextInputPosition(selection)
               - selection;
            }
            selection += selectionDelta;
         }
         
			// Did we just type something that was accepted by the mask?
			if (!newRawText.equals(oldRawText)) { // yep
            
            // If the user hits <end>, bounce them back to the end of their actual input
				int firstIncompletePosition = editMaskParser.getFirstIncompleteInputPosition();
				if (firstIncompletePosition > 0 && selection > firstIncompletePosition)
					selection = firstIncompletePosition;
				text.setSelection(new Point(selection, selection));
            
			} else { // nothing was accepted by the mask
            
				// Either we backspaced over a literal or we typed an illegal character
				if (selection > oldSelection) { // typed an illegal character; backup
					text.setSelection(new Point(selection-1, selection-1));
				} else { // backspaced over a literal; don't interfere with selection position
					text.setSelection(new Point(selection, selection));
				}
			}
			oldRawText = newRawText;
		}

		private boolean isInsertingNewCharacter(String newRawText) {
			return newRawText.length() > oldRawText.length();
		}

		private void firePropertyChangeEvents(Boolean oldIsComplete, String newRawText) {
			Boolean newIsComplete = new Boolean(editMaskParser.isComplete());
			if (!oldIsComplete.equals(newIsComplete)) {
				firePropertyChange(FIELD_COMPLETE, oldIsComplete, newIsComplete);
			}
			if (!newRawText.equals(oldValidRawText)) {
				if ( newIsComplete.booleanValue() || "".equals(newRawText) || fireChangeOnKeystroke) {
					firePropertyChange(FIELD_RAW_TEXT, oldValidRawText, newRawText);
					firePropertyChange(FIELD_TEXT, oldValidText, text.getText());
					oldValidText = text.getText();
					oldValidRawText = newRawText;
				}
			}
		}
	};
	
	private FocusListener focusListener = new FocusAdapter() {
		public void focusGained(FocusEvent e) {
			selection = editMaskParser.getFirstIncompleteInputPosition();
			text.setSelection(selection, selection);
		}
	};
	
	private DisposeListener disposeListener = new DisposeListener() {
		public void widgetDisposed(DisposeEvent e) {
			text.removeVerifyListener(verifyListener);
			text.removeFocusListener(focusListener);
			text.removeDisposeListener(disposeListener);
		}
	};

}
