/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.text;


import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;


/**
 * Standard implementation of <code>IUndoManager</code>. 
 * It registers with the connected text viewer as text listeners and logs all changes. 
 * It also monitors mouse and keyboard activities in order to partition the stream of
 * text changes into undoable edit commands. <p>
 * This class is not intended to be subclassed.
 * 
 * @see ITextViewer
 * @see ITextListener
 * @see MouseListener
 * @see KeyListener
 */
public class DefaultUndoManager implements IUndoManager {

	/**
	 * Represents an undoable edit command.
	 */
	class TextCommand {
		
		/** The start index of the replaced text */
		protected int fStart= -1;
		/** The end index of the replaced text */
		protected int fEnd= -1;
		/** The newly inserted text */
		protected String fText;
		/** The replaced text */
		protected String fPreservedText;
		
		/**
		 * Reinitializes this text command.
		 */
		protected void reinitialize() {
			fStart= fEnd= -1;
			fText= fPreservedText= null;
		}
		
		/**
		 * Sets the start and the end index of this command.
		 *
		 * @param start the start index
		 * @param end the end index
		 */
		protected void set(int start, int end) {
			fStart= start;
			fEnd= end;
			fText= null;
			fPreservedText= null;
		}
		
		/**
		 * Undo the change described by this command.
		 * 
		 * @since 2.0
		 */
		protected void undoTextChange() {
			try {
				fTextViewer.getDocument().replace(fStart, fText.length(), fPreservedText);
			} catch (BadLocationException x) {
			}
		}
		
		/**
		 * Undo the change described by this command. Also selects and
		 * reveals the change.
		 */
		protected void undo() {
			undoTextChange();
			selectAndReveal(fStart, fPreservedText == null ? 0 : fPreservedText.length());
		}
		
		/**
		 * Re-applies the change described by this command.
		 * 
		 * @since 2.0
		 */
		protected void redoTextChange() {
			try {
				fTextViewer.getDocument().replace(fStart, fEnd - fStart, fText);
			} catch (BadLocationException x) {
			}
		}
		
		/**
		 * Re-applies the change described by this command that previously been 
		 * rolled back. Also selects and reveals the change.
		 */
		protected void redo() {
			redoTextChange();
			selectAndReveal(fStart, fText == null ? 0 : fText.length());
		}
				
		/**
		 * Updates the command stack in response to committing
		 * the current change into this command.
		 */
		protected void updateCommandStack() {
			
			int length= fCommandStack.size();
			for (int i= fCommandCounter + 1; i < length; i++)
				fCommandStack.remove(fCommandCounter + 1);
				
			fCommandStack.add(this);
			
			while (fCommandStack.size() > fUndoLevel)
				fCommandStack.remove(0);
			
			fCommandCounter= fCommandStack.size() - 1;
		}
		
		/**
		 * Creates a new uncommitted text command depending on whether
		 * a compound change is currently being executed.
		 *
		 * @return a new, uncommitted text command or a compound text command
		 */
		protected TextCommand createCurrent() {
			return fFoldingIntoCompoundChange ? new CompoundTextCommand() : new TextCommand();		
		}
		
		/**
		 * Commits the current change into this command.
		 */
		protected void commit() {
			
			if (fStart < 0) {
				reinitialize();
			} else {
								
				fText= fTextBuffer.toString();
				fTextBuffer.setLength(0);
				fPreservedText= fPreservedTextBuffer.toString();
				fPreservedTextBuffer.setLength(0);
				
				updateCommandStack();
			}
			
			fCurrent= createCurrent();
		}
	}
	
	/**
	 * Represents an undoable edit command consisting of several
	 * individual edit commands.
	 */
	class CompoundTextCommand extends TextCommand {
		
		/** The list of individual commands */
		private List fCommands= new ArrayList();
		
		/**
		 * Adds a new individual command to this compound command.
		 *
		 * @param command the command to be added
		 */
		protected void add(TextCommand command) {
			fCommands.add(command);
		}
		
		/*
		 * @see org.eclipse.jface.text.DefaultUndoManager2.TextCommand#undo()
		 */
		protected void undo() {
			ITextViewerExtension extension= null;
			if (fTextViewer instanceof ITextViewerExtension)
				extension= (ITextViewerExtension) fTextViewer;
				
			if (extension != null)
				extension.setRedraw(false);
				
			try {
				
				int size= fCommands.size();
				if (size > 0) {
					
					TextCommand c;
					
					for (int i= size -1; i > 0;  --i) {
						c= (TextCommand) fCommands.get(i);
						c.undoTextChange();
					}
					
					c= (TextCommand) fCommands.get(0);
					c.undo();
				}
					
			} finally {
				if (extension != null)
					extension.setRedraw(true);
			}
		}
		
		/*
		 * @see org.eclipse.jface.text.DefaultUndoManager2.TextCommand#redo()
		 */
		protected void redo() {
			
			ITextViewerExtension extension= null;
			if (fTextViewer instanceof ITextViewerExtension)
				extension= (ITextViewerExtension) fTextViewer;
				
			if (extension != null)
				extension.setRedraw(false);
			
			try {
				
				int size= fCommands.size();
				if (size > 0) {
					
					TextCommand c;
					
					for (int i= 0; i < size -1;  ++i) {
						c= (TextCommand) fCommands.get(i);
						c.redoTextChange();
					}
					
					c= (TextCommand) fCommands.get(size -1);
					c.redo();
				}
				
			} finally {
				if (extension != null)
					extension.setRedraw(true);
			}
		}
		
		/*
		 * @see TextCommand#updateCommandStack
		 */
		protected void updateCommandStack() {
			TextCommand c= new TextCommand();
			c.fStart= fStart;
			c.fEnd= fEnd;
			c.fText= fText;
			c.fPreservedText= fPreservedText;
			
			add(c);
			
			if (!fFoldingIntoCompoundChange)
				super.updateCommandStack();
		}
		
		/*
		 * @see TextCommand#createCurrent
		 */
		protected TextCommand createCurrent() {
			
			if (!fFoldingIntoCompoundChange)
				return new TextCommand();
			
			reinitialize();
			return this;
		}
		
		/*
		 * @see org.eclipse.jface.text.DefaultUndoManager.TextCommand#commit()
		 */
		protected void commit() {
			if (fStart < 0) {
				if (fCommands.size() > 0 && !fFoldingIntoCompoundChange) {
					super.updateCommandStack();
					fCurrent= createCurrent();
					return;
				}
			}
			super.commit();
		}
	}
	
	/**
	 * Represents pretended <code>UndoManager</code> state.
	 */
	class PretendedUndoManagerState {
		/** The counter in the undo stack */
		protected int cmdCounter= -1;
		/** The size of the undo stack */
		protected int stackSize= -1;
	}
	
	/**
	 * Internal listener to mouse and key events.
	 */
	class KeyAndMouseListener implements MouseListener, KeyListener {
		
		/*
		 * @see MouseListener#mouseDoubleClick
		 */
		public void mouseDoubleClick(MouseEvent e) {
		}
		
		/*
		 * If the right mouse button is pressed, the current editing command is closed
		 * @see MouseListener#mouseDown
		 */
		public void mouseDown(MouseEvent e) {
			if (e.button == 1)
				commit();
		}
		
		/*
		 * @see MouseListener#mouseUp
		 */
		public void mouseUp(MouseEvent e) {
		}

		/*
		 * @see KeyListener#keyPressed
		 */
		public void keyReleased(KeyEvent e) {
		}
		
		/*
		 * On cursor keys, the current editing command is closed
		 * @see KeyListener#keyPressed
		 */
		public void keyPressed(KeyEvent e) {
			switch (e.keyCode) {
				case SWT.ARROW_UP:
				case SWT.ARROW_DOWN:
				case SWT.ARROW_LEFT:
				case SWT.ARROW_RIGHT:
					commit();
					break;
			}
		}
	}
	
	/**
	 * Internal listener to text changes.
	 */
	class TextListener implements ITextListener {
		
		/*
		 * @see ITextListener#textChanged
		 */
		public void textChanged(TextEvent e) {
			if (e.getDocumentEvent() != null)
				processTextEvent(e);
		}
	}
	 
	/** Text buffer to collect text which is inserted into the viewer */
	private StringBuffer fTextBuffer= new StringBuffer();
	/** Text buffer to collect viewer content which has been replaced */
	private StringBuffer fPreservedTextBuffer= new StringBuffer(); 
	/** Pretended undo manager state */
	private PretendedUndoManagerState fPretendedState= new PretendedUndoManagerState();
	
	/** The internal text listener */
	private ITextListener fTextListener;
	/** The internal key and mouse event listener */
	private KeyAndMouseListener fKeyAndMouseListener;
	
	
	/** Indicates inserting state */
	private boolean fInserting= false;
	/** Indicates overwriting state */
	private boolean fOverwriting= false;
	/** Indicates whether the current change belongs to a compound change */
	private boolean fFoldingIntoCompoundChange= false;
	
	/** The text viewer the undo manager is connected to */
	private ITextViewer fTextViewer;
	
	/** Supported undo level */
	private int fUndoLevel;
	/** The list of undoable edit commands */
	private List fCommandStack;
	/** The currently constructed edit command */
	private TextCommand fCurrent;
	/** The last delete edit command */
	private TextCommand fPreviousDelete;
	/** Command counter into the edit command stack */
	private int fCommandCounter= -1;
			
			 
	/**
	 * Creates a new undo manager who remembers the specified number of edit commands.
	 *
	 * @param undoLevel the length of this manager's history
	 */
	public DefaultUndoManager(int undoLevel) {
		setMaximalUndoLevel(undoLevel);
	}
	
	/*
	 * @see IUndoManager#beginCompoundChange
	 */
	public void beginCompoundChange() {
		fFoldingIntoCompoundChange= true;
		commit();
	}
	
	/*
	 * @see IUndoManager#endCompoundChange
	 */
	public void endCompoundChange() {
		fFoldingIntoCompoundChange= false;
		commit();
	}
		
	/**
	 * Registers all necessary listeners with the text viewer.
	 */
	private void addListeners() {
		StyledText text= fTextViewer.getTextWidget();
		if (text != null) {
			fKeyAndMouseListener= new KeyAndMouseListener();
			text.addMouseListener(fKeyAndMouseListener);
			text.addKeyListener(fKeyAndMouseListener);
			listenToTextChanges(true);
		}
	}
	
	/**
	 * Unregister all previously installed listeners from the text viewer.
	 */
	private void removeListeners() {
		StyledText text= fTextViewer.getTextWidget();
		if (text != null && fKeyAndMouseListener != null) {
			text.removeMouseListener(fKeyAndMouseListener);
			text.removeKeyListener(fKeyAndMouseListener);
			listenToTextChanges(false);
		}
	}
	
	/**
	 * Switches the state of whether there is a text listener or not.
	 *
	 * @param listen the state which should be established
	 */
	private void listenToTextChanges(boolean listen) {
		if (listen && fTextListener == null) {
			fTextListener= new TextListener();
			fTextViewer.addTextListener(fTextListener);
		} else if (!listen && fTextListener != null) {
			fTextViewer.removeTextListener(fTextListener);
			fTextListener= null;
		}
	}
	
	/**
	 * Closes the current editing command and opens a new one.
	 */
	private void commit() {
		
		fInserting= false;
		fOverwriting= false;
		fPreviousDelete.reinitialize();
		
		fCurrent.commit();
	}
	
	/**
	 * Re-applies the previously undone editing command.
	 */
	private void internalRedo() {		
		++fCommandCounter;
		TextCommand cmd= (TextCommand) fCommandStack.get(fCommandCounter);
		
		listenToTextChanges(false);
		cmd.redo();
		listenToTextChanges(true);
		
		fCurrent= new TextCommand();
	}
	
	/**
	 * Does undo the last editing command.
	 */
	private void internalUndo() {		
		TextCommand cmd= (TextCommand) fCommandStack.get(fCommandCounter);
		-- fCommandCounter;
		
		listenToTextChanges(false);
		cmd.undo();
		listenToTextChanges(true);
		
		fCurrent= new TextCommand();
	}
	
	/**
	 * Checks whether the given text starts with a line delimiter and
	 * subsequently contains a white space only.
	 *
	 * @param text the text to check
	 */
	private boolean isWhitespaceText(String text) {
				
		if (text == null || text.length() == 0)
			return false;
		
		String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();
		int index= TextUtilities.startsWith(delimiters, text);
		if (index > -1) {
			char c;
			int length= text.length();
			for (int i= delimiters[index].length(); i < length; i++) {
				c= text.charAt(i);
				if (c != ' ' && c != '\t')
					return false;
			}
			return true;
		}
		
		return false;
	}
	
	/**
	 * Returns the state the would result if the current editing command would be closed.
	 *
	 * @return the pretended state after closing the current editing command
	 */
	private PretendedUndoManagerState pretendCommit() {
		if (fCurrent.fStart < 0) {
			fPretendedState.stackSize= fCommandStack.size();
			fPretendedState.cmdCounter= fCommandCounter;
		} else {
			int sz= Math.max(fCommandCounter, 0) + 1;
			if (sz > fUndoLevel)
				sz -= fUndoLevel;
			fPretendedState.stackSize= sz;
			fPretendedState.cmdCounter= sz - 1;
		}
		return fPretendedState;	
	}
				
	/**
	 * Processes the given text event in order to determine editor command.
	 *
	 * @param e the text event
	 */
	private void processTextEvent(TextEvent e) {
		
		DocumentEvent event= e.getDocumentEvent();
		if (event == null) {
			commit();
			return;
		}
	
		int start= e.getOffset();
		int modelStart= event.getOffset();
		int end= e.getOffset() + e.getLength();
		int modelEnd= event.getOffset() + event.getLength();
		
		String newText= e.getText();
		String oldText= e.getReplacedText();
		
		
		if (newText == null)
			newText= ""; //$NON-NLS-1$
			
		if (oldText == null)
			oldText= ""; //$NON-NLS-1$
		
		int length= newText.length();
		int diff= end - start;
		
		// normalize verify command
		if (diff < 0) {
			int tmp= end;
			end= start;
			start= tmp;
			diff= -diff;
		}
				
		if (start == end) {
			// text will be inserted
			if ((length == 1) || isWhitespaceText(newText)) {
				// by typing or model manipulation
				if (!fInserting || (modelStart != fCurrent.fStart + fTextBuffer.length())) {
					commit();
					fInserting= true;
				} 
				if (fCurrent.fStart < 0)
					fCurrent.fStart= fCurrent.fEnd= modelStart;
				if (length > 0)
					fTextBuffer.append(newText);
			} else if (length > 0) {
				// by pasting
				commit();
				fCurrent.fStart= fCurrent.fEnd= modelStart;
				fTextBuffer.append(newText);
				commit();
			}
		} else {
			if (length == 0) {
				// text will be deleted by backspace or DEL key or empty clipboard
				length= oldText.length();
				String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();
				
				if ((length == 1) || TextUtilities.equals(delimiters, oldText) > -1) {
					
					// whereby selection is empty
					
					if (fPreviousDelete.fStart == start && fPreviousDelete.fEnd == end) {
						// repeated DEL
							
							// correct wrong settings of fCurrent
						if (fCurrent.fStart == modelEnd && fCurrent.fEnd == modelStart) {
							fCurrent.fStart= modelStart;
							fCurrent.fEnd= modelEnd;
						}
							// append to buffer && extend command range
						fPreservedTextBuffer.append(oldText);
						++fCurrent.fEnd;
						
					} else if (fPreviousDelete.fStart == end) {
						// repeated backspace
						
							// insert in buffer and extend command range
						fPreservedTextBuffer.insert(0, oldText);
						fCurrent.fStart= modelStart;
					
					} else {
						// either DEL or backspace for the first time
						
						commit();
						
						// as we can not decide whether it was DEL or backspace we initialize for backspace
						fPreservedTextBuffer.append(oldText);
						fCurrent.fStart= modelStart;
						fCurrent.fEnd= modelEnd;
					}
					
					fPreviousDelete.set(start, end);
					
				} else if (length > 0) {
					// whereby selection is not empty
					commit();
					fCurrent.fStart= modelStart;
					fCurrent.fEnd= modelEnd;
					fPreservedTextBuffer.append(oldText);
				}
			} else {
				// text will be replaced
								
				if (length == 1) {
					length= oldText.length();
					String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();

					if ((length == 1) || TextUtilities.equals(delimiters, oldText) > -1) {
						// because of overwrite mode or model manipulation
						if (!fOverwriting || (modelStart != fCurrent.fStart +  fTextBuffer.length())) {
							commit();
							fOverwriting= true;
						}

						if (fCurrent.fStart < 0)
							fCurrent.fStart= modelStart;

						fCurrent.fEnd= modelEnd;
						fTextBuffer.append(newText);
						fPreservedTextBuffer.append(oldText);
						return;
					}
				} 
				// because of typing or pasting whereby selection is not empty
				commit();
				fCurrent.fStart= modelStart;
				fCurrent.fEnd= modelEnd;
				fTextBuffer.append(newText);
				fPreservedTextBuffer.append(oldText);
			}
		}
	}
	
	/*
	 * @see IUndoManager#setMaximalUndoLevel
	 */
	public void setMaximalUndoLevel(int undoLevel) {
		fUndoLevel= undoLevel;
	}

	/*
	 * @see IUndoManager#connect
	 */
	public void connect(ITextViewer textViewer) {
		if (fTextViewer == null) {
			fTextViewer= textViewer;	
			fCommandStack= new ArrayList();
			fCurrent= new TextCommand();
			fPreviousDelete= new TextCommand();
			addListeners();
		}
	}
	
	/*
	 * @see IUndoManager#disconnect
	 */
	public void disconnect() {
		if (fTextViewer != null) {
			
			removeListeners();
			
			fCurrent= null;
			if (fCommandStack != null) {
				fCommandStack.clear();
				fCommandStack= null;
			}
			fTextBuffer= null;
			fPreservedTextBuffer= null;
			fTextViewer= null;
		}
	}
	
	/*
	 * @see IUndoManager#reset
	 */
	public void reset() {
		if (fCommandStack != null)
			fCommandStack.clear();
		fCommandCounter= -1;
		if (fCurrent != null)
			fCurrent.reinitialize();
		fFoldingIntoCompoundChange= false;
		fInserting= false;
		fOverwriting= false;
		fTextBuffer.setLength(0);
		fPreservedTextBuffer.setLength(0);		
	}
	
	/*
	 * @see IUndoManager#redoable
	 */
	public boolean redoable() {
		if (fCommandStack != null)  {
			PretendedUndoManagerState s= pretendCommit();
			return (0 <= s.cmdCounter + 1) && (s.cmdCounter + 1 < s.stackSize);
		}
		return false;
	}
	
	/*
	 * @see IUndoManager#undoable
	 */
	public boolean undoable() {
		if (fCommandStack != null) {
			PretendedUndoManagerState s= pretendCommit();
			return (0 <= s.cmdCounter) && (s.cmdCounter < s.stackSize);
		}
		return false;
	}
	
	/*
	 * @see IUndoManager#redo
	 */
	public void redo() {
		if (redoable()) {
			commit();
			internalRedo();
		}
	}
	
	/*
	 * @see IUndoManager#undo
	 */
	public void undo() {
		if (undoable()) {
			fFoldingIntoCompoundChange= false;
			commit();
			internalUndo();
		}
	}
	
	protected void selectAndReveal(int offset, int length) {
		if (fTextViewer instanceof ITextViewerExtension5) {
			ITextViewerExtension5 extension= (ITextViewerExtension5) fTextViewer;
			extension.exposeModelRange(new Region(offset, length));
		} else if (!fTextViewer.overlapsWithVisibleRegion(offset, length))
			fTextViewer.resetVisibleRegion();

		fTextViewer.setSelectedRange(offset, length);
		fTextViewer.revealRange(offset, length);
	}	
}
