/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *******************************************************************************/
package org.eclipse.swt.widgets;

import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.cocoa.*;

/**
 * Instances of this class are selectable user interface
 * objects that allow the user to enter and modify text.
 * Text controls can be either single or multi-line.
 * When a text control is created with a border, the
 * operating system includes a platform specific inset
 * around the contents of the control.  When created
 * without a border, an effort is made to remove the
 * inset such that the preferred size of the control
 * is the same size as the contents.
 * <p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>CENTER, ICON_CANCEL, ICON_SEARCH, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP</dd>
 * <dt><b>Events:</b></dt>
 * <dd>DefaultSelection, Modify, Verify, OrientationChange</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles MULTI and SINGLE may be specified,
 * and only one of the styles LEFT, CENTER, and RIGHT may be specified.
 * </p>
 * <p>
 * Note: The styles ICON_CANCEL and ICON_SEARCH are hints used in combination with SEARCH.
 * When the platform supports the hint, the text control shows these icons.  When an icon
 * is selected, a default selection event is sent with the detail field set to one of
 * ICON_CANCEL or ICON_SEARCH.  Normally, application code does not need to check the
 * detail.  In the case of ICON_CANCEL, the text is cleared before the default selection
 * event is sent causing the application to search for an empty string.
 * </p>
 * <p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#text">Text snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class Text extends Scrollable {
	int textLimit = LIMIT, tabs = 8;
	char echoCharacter;
	boolean doubleClick, receivingFocus;
	char [] hiddenText;
	String message;
	NSRange selectionRange;
	id targetSearch, targetCancel;
	long /*int*/ actionSearch, actionCancel;
	
	/**
	* The maximum number of characters that can be entered
	* into a text widget.
	* <p>
	* Note that this value is platform dependent, based upon
	* the native widget implementation.
	* </p>
	*/
	public static final int LIMIT;
	
	/**
	* The delimiter used by multi-line text widgets.  When text
	* is queried and from the widget, it will be delimited using
	* this delimiter.
	*/
	public static final String DELIMITER;
	static final char PASSWORD = '\u2022';

	/*
	* These values can be different on different platforms.
	* Therefore they are not initialized in the declaration
	* to stop the compiler from inlining.
	*/
	static {
		LIMIT = 0x7FFFFFFF;
		DELIMITER = "\r";
	}

/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#SINGLE
 * @see SWT#MULTI
 * @see SWT#READ_ONLY
 * @see SWT#WRAP
 * @see SWT#LEFT
 * @see SWT#RIGHT
 * @see SWT#CENTER
 * @see SWT#PASSWORD
 * @see SWT#SEARCH
 * @see SWT#ICON_SEARCH
 * @see SWT#ICON_CANCEL
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Text (Composite parent, int style) {
	super (parent, checkStyle (style));
	if ((style & SWT.SEARCH) != 0) {
		/*
		* Ensure that SWT.ICON_CANCEL and ICON_SEARCH are set.
		* NOTE: ICON_CANCEL has the same value as H_SCROLL and
		* ICON_SEARCH has the same value as V_SCROLL so it is
		* necessary to first clear these bits to avoid a scroll
		* bar and then reset the bit using the original style
		* supplied by the programmer.
		*/
		NSSearchFieldCell cell = new NSSearchFieldCell (((NSSearchField) view).cell ());
		if ((style & SWT.ICON_CANCEL) != 0) {
			this.style |= SWT.ICON_CANCEL;
			NSButtonCell cancelCell = cell.cancelButtonCell();
			targetCancel = cancelCell.target();
			actionCancel = cancelCell.action();
			cancelCell.setTarget (view);
			cancelCell.setAction (OS.sel_sendCancelSelection);
		} else {
			cell.setCancelButtonCell (null);
		}
		if ((style & SWT.ICON_SEARCH) != 0) {
			this.style |= SWT.ICON_SEARCH;
			NSButtonCell searchCell = cell.searchButtonCell();
			targetSearch = searchCell.target();
			actionSearch = searchCell.action();
			searchCell.setTarget (view);
			searchCell.setAction (OS.sel_sendSearchSelection);
		} else {
			cell.setSearchButtonCell (null);
		}
	}
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when the receiver's text is modified, by sending
 * it one of the messages defined in the <code>ModifyListener</code>
 * interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see ModifyListener
 * @see #removeModifyListener
 */
public void addModifyListener (ModifyListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Modify, typedListener);
}

/**
 * Adds a segment listener.
 * <p>
 * A <code>SegmentEvent</code> is sent whenever text content is being modified or
 * a segment listener is added or removed. You can 
 * customize the appearance of text by indicating certain characters to be inserted
 * at certain text offsets. This may be used for bidi purposes, e.g. when
 * adjacent segments of right-to-left text should not be reordered relative to
 * each other. 
 * E.g., multiple Java string literals in a right-to-left language
 * should generally remain in logical order to each other, that is, the
 * way they are stored.
 * </p>
 * <p>
 * <b>Warning</b>: This API is currently only implemented on Windows and GTK.
 * <code>SegmentEvent</code>s won't be sent on Cocoa.
 * </p>
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SegmentEvent
 * @see SegmentListener
 * @see #removeSegmentListener
 * 
 * @since 3.8
 */
public void addSegmentListener (SegmentListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	addListener (SWT.Segments, new TypedListener (listener));
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when the control is selected by the user, by sending
 * it one of the messages defined in the <code>SelectionListener</code>
 * interface.
 * <p>
 * <code>widgetSelected</code> is not called for texts.
 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text,
 * or when ENTER is pressed in a search text. If the receiver has the <code>SWT.SEARCH | SWT.ICON_CANCEL</code> style
 * and the user cancels the search, the event object detail field contains the value <code>SWT.ICON_CANCEL</code>.
 * Likewise, if the receiver has the <code>SWT.ICON_SEARCH</code> style and the icon search is selected, the 
 * event object detail field contains the value <code>SWT.ICON_SEARCH</code>.
 * </p>
 *
 * @param listener the listener which should be notified when the control is selected by the user
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SelectionListener
 * @see #removeSelectionListener
 * @see SelectionEvent
 */
public void addSelectionListener(SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Selection,typedListener);
	addListener (SWT.DefaultSelection,typedListener);
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when the receiver's text is verified, by sending
 * it one of the messages defined in the <code>VerifyListener</code>
 * interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see VerifyListener
 * @see #removeVerifyListener
 */
public void addVerifyListener (VerifyListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Verify, typedListener);
}

/**
 * Appends a string.
 * <p>
 * The new text is appended to the text at
 * the end of the widget.
 * </p>
 *
 * @param string the string to be appended
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void append (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		int charCount = getCharCount ();
		string = verifyText (string, charCount, charCount, null);
		if (string == null) return;
	}
	if ((style & SWT.SINGLE) != 0) {
		setSelection (getCharCount ());
		insertEditText (string);
	} else {
		NSString str;
		if (textLimit != LIMIT) {
			str = getInsertString (string, null);
		} else {
			str = NSString.stringWith (string);
		}
		NSTextView widget = (NSTextView) view;
		NSTextStorage storage = widget.textStorage ();
		NSRange range = new NSRange();
		range.location = storage.length();
		storage.replaceCharactersInRange (range, str);
		range.location = storage.length();
		widget.scrollRangeToVisible (range);
		widget.setSelectedRange(range);
	}
	if (string.length () != 0) sendEvent (SWT.Modify);
}

boolean becomeFirstResponder (long /*int*/ id, long /*int*/ sel) {
	receivingFocus = true;
	boolean result = super.becomeFirstResponder (id, sel);
	receivingFocus = false;
	return result;
}

static int checkStyle (int style) {
	if ((style & SWT.SEARCH) != 0) {
		style |= SWT.SINGLE | SWT.BORDER;
		style &= ~SWT.PASSWORD;
		/* 
		* NOTE: ICON_CANCEL has the same value as H_SCROLL and
		* ICON_SEARCH has the same value as V_SCROLL so they are
		* cleared because SWT.SINGLE is set. 
		*/
	}
	if ((style & SWT.SINGLE) != 0 && (style & SWT.MULTI) != 0) {
		style &= ~SWT.MULTI;
	}
	style = checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
	if ((style & SWT.SINGLE) != 0) style &= ~(SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
	if ((style & SWT.WRAP) != 0) {
		style |= SWT.MULTI;
		style &= ~SWT.H_SCROLL;
	}
	if ((style & SWT.MULTI) != 0) style &= ~SWT.PASSWORD;
	if ((style & (SWT.SINGLE | SWT.MULTI)) != 0) return style;
	if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0) return style | SWT.MULTI;
	return style | SWT.SINGLE;
}

/**
 * Clears the selection.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void clearSelection () {
	checkWidget ();
	Point selection = getSelection ();
	setSelection (selection.x);	
}

public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	int width = 0, height = 0;
	if ((style & SWT.SINGLE) != 0) {
		NSCell cell = ((NSTextField) view).cell ();
		NSSize size = cell.cellSize ();
		NSString str = ((NSTextField) view).stringValue();
		if (str.length () > 0) {
			width = (int)Math.ceil (size.width);
		}
		height = (int)Math.ceil (size.height);

		Point border = null;
		if ((style & SWT.BORDER) != 0 && (wHint != SWT.DEFAULT || hHint != SWT.DEFAULT)) {
			/* determine the size of the cell without its border */
			NSRect insets = cell.titleRectForBounds (new NSRect ());
			border = new Point (-(int)Math.ceil (insets.width), -(int)Math.ceil (insets.height));
			width -= border.x;
			height -= border.y;
		}
		if (width <= 0) width = DEFAULT_WIDTH;
		if (height <= 0) height = DEFAULT_HEIGHT;
		if (wHint != SWT.DEFAULT) width = wHint;
		if (hHint != SWT.DEFAULT) height = hHint;
		if (border != null) {
			/* re-add the border size (if any) now that wHint/hHint is taken */
			width += border.x;
			height += border.y;
		}
	} else {
		NSLayoutManager layoutManager = (NSLayoutManager)new NSLayoutManager ().alloc ().init ();
		NSTextContainer textContainer = (NSTextContainer)new NSTextContainer ().alloc ();
		NSSize size = new NSSize ();
		size.width = size.height = OS.MAX_TEXT_CONTAINER_SIZE;
		if ((style & SWT.WRAP) != 0) {
			if (wHint != SWT.DEFAULT) size.width = wHint;
			if (hHint != SWT.DEFAULT) size.height = hHint;
		}
		textContainer.initWithContainerSize (size);
		layoutManager.addTextContainer (textContainer);

		NSTextStorage textStorage = (NSTextStorage)new NSTextStorage ().alloc ().init ();
		textStorage.setAttributedString (((NSTextView)view).textStorage ());
		layoutManager.setTextStorage (textStorage);
		layoutManager.glyphRangeForTextContainer (textContainer);

		NSRect rect = layoutManager.usedRectForTextContainer (textContainer);
		width = layoutManager.numberOfGlyphs () == 0 ? DEFAULT_WIDTH : (int)Math.ceil (rect.width);
		height = (int)Math.ceil (rect.height);
		textStorage.release ();
		textContainer.release ();
		layoutManager.release ();

		if (width <= 0) width = DEFAULT_WIDTH;
		if (height <= 0) height = DEFAULT_HEIGHT;
		if (wHint != SWT.DEFAULT) width = wHint;
		if (hHint != SWT.DEFAULT) height = hHint;
		Rectangle trim = computeTrim (0, 0, width, height);
		width = trim.width;
		height = trim.height;
	}
	return new Point (width, height);
}

public Rectangle computeTrim (int x, int y, int width, int height) {
	Rectangle result = super.computeTrim (x, y, width, height);
	if ((style & SWT.SINGLE) != 0) {
		NSTextField widget = (NSTextField) view;
		if ((style & SWT.SEARCH) != 0) {
			NSSearchFieldCell cell = new NSSearchFieldCell (widget.cell ());
			int testWidth = 100;
			NSRect rect = new NSRect ();
			rect.width = testWidth;
			rect = cell.searchTextRectForBounds (rect);
			int leftIndent = (int)rect.x;
			int rightIndent = testWidth - leftIndent - (int)Math.ceil (rect.width);
			result.x -= leftIndent;
			result.width += leftIndent + rightIndent;
		}
		NSRect inset = widget.cell ().titleRectForBounds (new NSRect ());
		result.x -= inset.x;
		result.y -= inset.y;
		result.width -= inset.width;
		result.height -= inset.height;
	}
	return result;
}

/**
 * Copies the selected text.
 * <p>
 * The current selection is copied to the clipboard.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void copy () {
	checkWidget ();
	if ((style & SWT.PASSWORD) != 0 || echoCharacter != '\0') return;
	if ((style & SWT.SINGLE) != 0) {
		Point selection = getSelection ();
		if (selection.x == selection.y) return;
		copyToClipboard (getEditText (selection.x, selection.y - 1));
	} else {
		NSText text = (NSText) view;
		if (text.selectedRange ().length == 0) return;
		text.copy (null);
	}
}

void createHandle () {
	if ((style & SWT.READ_ONLY) != 0) {
		if ((style & (SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL)) == 0) {
			state |= THEME_BACKGROUND;
		}
	}
	if ((style & SWT.SINGLE) != 0) {
		NSTextField widget;
		if ((style & SWT.PASSWORD) != 0) {
			widget = (NSTextField) new SWTSecureTextField ().alloc ();
		} else if ((style & SWT.SEARCH) != 0) {
			widget = (NSTextField) new SWTSearchField ().alloc ();
		} else {
			widget = (NSTextField) new SWTTextField ().alloc ();
		}
		widget.init ();
		widget.setSelectable (true);
		widget.setEditable((style & SWT.READ_ONLY) == 0);
		if ((style & SWT.BORDER) == 0) {
			widget.setFocusRingType (OS.NSFocusRingTypeNone);
			widget.setBordered (false);
		}
		int align = OS.NSLeftTextAlignment;
		if ((style & SWT.CENTER) != 0) align = OS.NSCenterTextAlignment;
		if ((style & SWT.RIGHT) != 0) align = OS.NSRightTextAlignment;
		widget.setAlignment (align);
		NSCell cell = widget.cell();
		cell.setWraps(false);
		cell.setScrollable(true);
//		widget.setTarget(widget);
//		widget.setAction(OS.sel_sendSelection);
		view = widget;
	} else {
		NSScrollView scrollWidget = (NSScrollView) new SWTScrollView ().alloc ();
		scrollWidget.init ();
		scrollWidget.setHasVerticalScroller ((style & SWT.VERTICAL) != 0);
		scrollWidget.setHasHorizontalScroller ((style & SWT.HORIZONTAL) != 0);
		scrollWidget.setAutoresizesSubviews (true);
		if ((style & SWT.BORDER) != 0) scrollWidget.setBorderType (OS.NSBezelBorder);
		
		NSTextView widget = (NSTextView) new SWTTextView ().alloc ();
		widget.init ();
		widget.setEditable ((style & SWT.READ_ONLY) == 0);
		widget.setAllowsUndo(true);
		
		NSSize size = new NSSize ();
		size.width = size.height = Float.MAX_VALUE;
		widget.setMaxSize (size);
		widget.setAutoresizingMask (OS.NSViewWidthSizable | OS.NSViewHeightSizable);

		if ((style & SWT.WRAP) == 0) {
			NSTextContainer textContainer = widget.textContainer ();
			widget.setHorizontallyResizable (true);
			textContainer.setWidthTracksTextView (false);
			NSSize csize = new NSSize ();
			csize.width = csize.height = Float.MAX_VALUE;
			textContainer.setContainerSize (csize);
		}

		int align = OS.NSLeftTextAlignment;
		if ((style & SWT.CENTER) != 0) align = OS.NSCenterTextAlignment;
		if ((style & SWT.RIGHT) != 0) align = OS.NSRightTextAlignment;
		widget.setAlignment (align);
//		widget.setTarget(widget);
//		widget.setAction(OS.sel_sendSelection);
		widget.setRichText (false);
		widget.setDelegate(widget);
		widget.setFont (display.getSystemFont ().handle);
		widget.setUsesFontPanel(false);

		view = widget;
		scrollView = scrollWidget;
	}
}

void createWidget () {
	super.createWidget ();
	if ((style & SWT.PASSWORD) != 0) {
		NSText fieldEditor = view.window().fieldEditor(true, view);
		long /*int*/ nsSecureTextViewClass = OS.objc_lookUpClass("NSSecureTextView");
		if (fieldEditor != null && nsSecureTextViewClass != 0 && fieldEditor.isKindOfClass(nsSecureTextViewClass)) {
			long /*int*/ editorClass = OS.objc_getClass("SWTSecureEditorView");
			OS.object_setClass(fieldEditor.id, editorClass);
		}
	}
	doubleClick = true;
	message = "";
}

/**
 * Cuts the selected text.
 * <p>
 * The current selection is first copied to the
 * clipboard and then deleted from the widget.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void cut () {
	checkWidget ();
	if ((style & SWT.READ_ONLY) != 0) return;
	if ((style & SWT.PASSWORD) != 0 || echoCharacter != '\0') return;
	boolean cut = true;
	char [] oldText = null;
	Point oldSelection = getSelection ();
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		if (oldSelection.x != oldSelection.y) {
			oldText = getEditText (oldSelection.x, oldSelection.y - 1);
			String newText = verifyText ("", oldSelection.x, oldSelection.y, null);
			if (newText == null) return;
			if (newText.length () != 0) {
				copyToClipboard (oldText);
				if ((style & SWT.SINGLE) != 0) {
					insertEditText (newText);
				} else {
					NSTextView widget = (NSTextView) view;
					widget.replaceCharactersInRange (widget.selectedRange (), NSString.stringWith (newText));
				}
				cut = false;
			}
		}
	}
	if (cut) {
		if ((style & SWT.SINGLE) != 0) {
			if (oldText == null) oldText = getEditText (oldSelection.x, oldSelection.y - 1);
			copyToClipboard (oldText);
			insertEditText ("");
		} else {
			((NSTextView) view).cut (null);
		}
	}
	Point newSelection = getSelection ();
	if (!cut || !oldSelection.equals (newSelection)) sendEvent (SWT.Modify);
}

Color defaultBackground () {
	return display.getWidgetColor (SWT.COLOR_LIST_BACKGROUND);
}

NSFont defaultNSFont () {
	if ((style & SWT.MULTI) != 0) return display.textViewFont;
	if ((style & SWT.SEARCH) != 0) return display.searchFieldFont;
	if ((style & SWT.PASSWORD) != 0) return display.secureTextFieldFont;
	return display.textFieldFont;
}

Color defaultForeground () {
	return display.getWidgetColor (SWT.COLOR_LIST_FOREGROUND);
}

void deregister() {
	super.deregister();
	
	if ((style & SWT.SINGLE) != 0) {
		display.removeWidget(((NSControl)view).cell());
	}
}

void drawBackground (long /*int*/ id, NSGraphicsContext context, NSRect rect) {
	if ((style & SWT.SINGLE) != 0) {
		if (backgroundImage == null) return;
		if (new NSView(id).isKindOfClass(OS.class_NSText)) {
			NSText text = new NSText(id);
			if (!text.isFieldEditor()) return;
		}
	}
	if ((style & SWT.MULTI) != 0 && id != scrollView.id) return;
	fillBackground (view, context, rect, -1);
}

void drawInteriorWithFrame_inView(long /*int*/ id, long /*int*/ sel, NSRect cellFrame, long /*int*/ viewid) {
	Control control = findBackgroundControl();
	if (control == null) control = this;
	Image image = control.backgroundImage;
	if (image != null && !image.isDisposed()) {
		NSGraphicsContext context = NSGraphicsContext.currentContext();
 	 	control.fillBackground (view, context, cellFrame, -1);
	}
	super.drawInteriorWithFrame_inView(id, sel, cellFrame, viewid);
}


boolean dragDetect (int x, int y, boolean filter, boolean [] consume) {
	Point selection = getSelection ();
	if (selection.x != selection.y) {
		long /*int*/ position = getPosition (x, y);
		if (selection.x <= position && position < selection.y) {
			if (super.dragDetect (x, y, filter, consume)) {
				if (consume != null) consume [0] = true;
				return true;
			}
		}
	}
	return false;
}

void enableWidget(boolean enabled) {
	super.enableWidget(enabled);
	
	if ((style & SWT.MULTI) != 0) {
		setForeground(this.foreground);
	}
}

Cursor findCursor () {
	Cursor cursor = super.findCursor ();
	return (cursor != null) ? cursor : display.getSystemCursor (SWT.CURSOR_IBEAM);
}

/**
 * Returns the line number of the caret.
 * <p>
 * The line number of the caret is returned.
 * </p>
 *
 * @return the line number
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getCaretLineNumber () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return 0;
    return (getTopPixel () + getCaretLocation ().y) / getLineHeight ();
}

boolean acceptsFirstResponder(long /*int*/ id, long /*int*/ sel) {
	if ((style & SWT.READ_ONLY) != 0) return true;
	return super.acceptsFirstResponder(id, sel);
}

/**
 * Returns a point describing the location of the caret relative
 * to the receiver.
 *
 * @return a point, the location of the caret
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Point getCaretLocation () {
	checkWidget ();
	NSTextView widget = null;
	if ((style & SWT.SINGLE) != 0) {
		if (this.hasFocus()) {
			widget = new NSTextView(view.window().fieldEditor(true, view));
		}
	} else {
		widget = (NSTextView) view;
	}
	if (widget == null) return new Point (0, 0);
	NSLayoutManager layoutManager = widget.layoutManager();
	NSTextContainer container = widget.textContainer();
	NSRange range = widget.selectedRange();
	long /*int*/ [] rectCount = new long /*int*/ [1];
	long /*int*/ pArray = layoutManager.rectArrayForCharacterRange(range, range, container, rectCount);
	NSRect rect = new NSRect();
	if (rectCount[0] > 0) OS.memmove(rect, pArray, NSRect.sizeof);
	return new Point((int)rect.x, (int)rect.y);
}

/**
 * Returns the character position of the caret.
 * <p>
 * Indexing is zero based.
 * </p>
 *
 * @return the position of the caret
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getCaretPosition () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		return selectionRange != null ? (int)/*64*/selectionRange.location : 0;
	} else {
		NSRange range = ((NSTextView)view).selectedRange();
		return (int)/*64*/range.location;
	}
}

/**
 * Returns the number of characters.
 *
 * @return number of characters in the widget
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getCharCount () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		return (int)((NSControl) view).stringValue().length ();
	} else {
		return (int)/*64*/((NSTextView) view).textStorage ().length ();
	}
}

/**
 * Returns the double click enabled flag.
 * <p>
 * The double click flag enables or disables the
 * default action of the text widget when the user
 * double clicks.
 * </p>
 * 
 * @return whether or not double click is enabled
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public boolean getDoubleClickEnabled () {
	checkWidget ();
    return doubleClick;
}

/**
 * Returns the echo character.
 * <p>
 * The echo character is the character that is
 * displayed when the user enters text or the
 * text is changed by the programmer.
 * </p>
 * 
 * @return the echo character
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #setEchoChar
 */
public char getEchoChar () {
	checkWidget ();
	return echoCharacter;
}

/**
 * Returns the editable state.
 *
 * @return whether or not the receiver is editable
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public boolean getEditable () {
	checkWidget ();
	return (style & SWT.READ_ONLY) == 0;
}

char [] getEditText () {
	if (hiddenText != null) {
		char [] text = new char [hiddenText.length];
		System.arraycopy (hiddenText, 0, text, 0, text.length);
		return text;
	}
	NSString str = null;
	if ((style & SWT.SINGLE) != 0) {
		str = ((NSTextField) view).stringValue();
	} else {
		str = ((NSTextView)view).textStorage().string();
	}

	int length = (int)/*64*/str.length ();
	char [] buffer = new char [length];
	NSRange range = new NSRange ();
	range.length = length;
	str.getCharacters (buffer, range);
	return buffer;
}

char [] getEditText (int start, int end) {
	NSString str = null;
	if ((style & SWT.SINGLE) != 0) {
		str = ((NSTextField) view).stringValue();
	} else {
		str = ((NSTextView)view).textStorage().string();
	}

	int length = (int)/*64*/str.length ();
	end = Math.min (end, length - 1);
	if (start > end) return new char [0];
	start = Math.max (0, start);
	NSRange range = new NSRange ();
	range.location = start;
	range.length = Math.max (0, end - start + 1);
	char [] buffer = new char [(int)/*64*/range.length];
	if (hiddenText != null) {
		System.arraycopy (hiddenText, (int)/*64*/range.location, buffer, 0, buffer.length);
	} else {
		str.getCharacters (buffer, range);
	}
	return buffer;
}

NSString getInsertString (String string, NSRange range) {
	NSString str;
	int charCount = getCharCount ();
	int length = string.length ();
	int selectionLength = range != null ? (int)/*64*/(range.length) : 0;
	if (charCount - selectionLength + length > textLimit) {
		length = textLimit - charCount + selectionLength;
		length = Math.max (0, length);
	}
	char [] buffer = new char [length];
	string.getChars (0, buffer.length, buffer, 0);
	str = NSString.stringWithCharacters (buffer, buffer.length);
	return str;
}

/**
 * Returns the number of lines.
 *
 * @return the number of lines in the widget
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getLineCount () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return 1;
	NSTextStorage storage = ((NSTextView) view).textStorage ();
	int count = (int)/*64*/storage.paragraphs ().count ();
	NSString string = storage.string();
	long /*int*/ length = string.length(), c;
	if (length == 0 || (c = string.characterAtIndex(length - 1)) == '\n' || c == '\r') {
		count++;
	}
	return count;
}

/**
 * Returns the line delimiter.
 *
 * @return a string that is the line delimiter
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #DELIMITER
 */
public String getLineDelimiter () {
	checkWidget ();
	return DELIMITER;
}

/**
 * Returns the height of a line.
 *
 * @return the height of a row of text
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getLineHeight () {
	checkWidget ();
	Font font = this.font != null ? this.font : defaultFont();
	if ((style & SWT.SINGLE) != 0) {
		NSDictionary dict = NSDictionary.dictionaryWithObject(font.handle, OS.NSFontAttributeName);
		NSString str = NSString.stringWith(" ");
		NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString(str, dict);
		NSSize size = attribStr.size();
		attribStr.release();
		return (int) size.height;
	} else {
		NSTextView widget = (NSTextView)view;
		return (int)Math.ceil(widget.layoutManager().defaultLineHeightForFont(font.handle));
	}
}

/**
 * Returns the orientation of the receiver, which will be one of the
 * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
 *
 * @return the orientation style
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.1.2
 */
public int getOrientation () {
	checkWidget ();
	return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
}

/**
 * Returns the widget message.  The message text is displayed
 * as a hint for the user, indicating the purpose of the field.
 * <p>
 * Typically this is used in conjunction with <code>SWT.SEARCH</code>.
 * </p>
 * 
 * @return the widget message
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.3
 */
public String getMessage () {
	checkWidget ();
	return message;
}

long /*int*/ getPosition (long /*int*/ x, long /*int*/ y) {
//	checkWidget ();
	if ((style & SWT.MULTI) != 0) {
		NSTextView widget = (NSTextView) view;
		NSPoint viewLocation = new NSPoint();
		viewLocation.x = x;
		viewLocation.y = y;
		return widget.characterIndexForInsertionAtPoint(viewLocation);
	} else {
		//TODO 
		return 0;
	}
}

/**
 * Returns a <code>Point</code> whose x coordinate is the
 * character position representing the start of the selected
 * text, and whose y coordinate is the character position
 * representing the end of the selection. An "empty" selection
 * is indicated by the x and y coordinates having the same value.
 * <p>
 * Indexing is zero based.  The range of a selection is from
 * 0..N where N is the number of characters in the widget.
 * </p>
 *
 * @return a point representing the selection start and end
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Point getSelection () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		if (selectionRange == null) {
			NSString str = ((NSTextField) view).stringValue();
			return new Point((int)/*64*/str.length (), (int)/*64*/str.length ());
		}
		return new Point ((int)/*64*/selectionRange.location, (int)/*64*/(selectionRange.location + selectionRange.length));
	} else {
		NSTextView widget = (NSTextView) view;
		NSRange range = widget.selectedRange ();
		return new Point ((int)/*64*/range.location, (int)/*64*/(range.location + range.length));
	}
}

/**
 * Returns the number of selected characters.
 *
 * @return the number of selected characters.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getSelectionCount () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		return selectionRange != null ? (int)/*64*/selectionRange.length : 0;
	} else {
		NSTextView widget = (NSTextView) view;
		NSRange range = widget.selectedRange ();
		return (int)/*64*/range.length;
	}
}

/**
 * Gets the selected text, or an empty string if there is no current selection.
 *
 * @return the selected text
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public String getSelectionText () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		Point selection = getSelection ();
		if (selection.x == selection.y) return "";
		return new String (getEditText (selection.x, selection.y - 1));
	} else {
		NSTextView widget = (NSTextView) view;
		NSRange range = widget.selectedRange ();
		NSString str = widget.textStorage ().string ();
		char[] buffer = new char [(int)/*64*/range.length];
		str.getCharacters (buffer, range);
		return new String (buffer);
	}
}

/**
 * Returns the number of tabs.
 * <p>
 * Tab stop spacing is specified in terms of the
 * space (' ') character.  The width of a single
 * tab stop is the pixel width of the spaces.
 * </p>
 *
 * @return the number of tab characters
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getTabs () {
	checkWidget ();
	return tabs;
}

/**
 * Returns the widget text.
 * <p>
 * The text for a text widget is the characters in the widget, or
 * an empty string if this has never been set.
 * </p>
 *
 * @return the widget text
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public String getText () {
	checkWidget ();
	NSString str;
	if ((style & SWT.SINGLE) != 0) {
		return new String (getEditText ());
	} else {
		str = ((NSTextView)view).textStorage ().string ();
	}
	return str.getString();
}

/**
 * Returns a range of text.  Returns an empty string if the
 * start of the range is greater than the end.
 * <p>
 * Indexing is zero based.  The range of
 * a selection is from 0..N-1 where N is
 * the number of characters in the widget.
 * </p>
 *
 * @param start the start of the range
 * @param end the end of the range
 * @return the range of text
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public String getText (int start, int end) {
	checkWidget ();
	if (!(start <= end && 0 <= end)) return ""; //$NON-NLS-1$
	if ((style & SWT.SINGLE) != 0) {
		return new String (getEditText (start, end));
	}
	NSTextStorage storage = ((NSTextView) view).textStorage ();
	end = Math.min (end, (int)/*64*/storage.length () - 1);
	if (start > end) return ""; //$NON-NLS-1$
	start = Math.max (0, start);
	NSRange range = new NSRange ();
	range.location = start;
	range.length = end - start + 1;
	NSAttributedString substring = storage.attributedSubstringFromRange (range);
	NSString string = substring.string ();
	return string.getString();
}

/**
 * Returns the widget's text as a character array.
 * <p>
 * The text for a text widget is the characters in the widget, or
 * a zero-length array if this has never been set.
 * </p>
 *
 * @return a character array that contains the widget's text
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see #setTextChars(char[])
 *
 * @since 3.7
 */
public char[] getTextChars () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		return getEditText ();
	} else {
		NSString str = ((NSTextView)view).textStorage ().string ();
		int length = (int)/*64*/str.length ();
		char [] buffer = new char [length];
		NSRange range = new NSRange ();
		range.length = length;
		str.getCharacters (buffer, range);
		return buffer;
	}
}

/**
 * Returns the maximum number of characters that the receiver is capable of holding. 
 * <p>
 * If this has not been changed by <code>setTextLimit()</code>,
 * it will be the constant <code>Text.LIMIT</code>.
 * </p>
 * 
 * @return the text limit
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #LIMIT
 */
public int getTextLimit () {
	checkWidget ();
    return textLimit;
}

/**
 * Returns the zero-relative index of the line which is currently
 * at the top of the receiver.
 * <p>
 * This index can change when lines are scrolled or new lines are added or removed.
 * </p>
 *
 * @return the index of the top line
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getTopIndex () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return 0;
    return getTopPixel () / getLineHeight ();
}

/**
 * Returns the top pixel.
 * <p>
 * The top pixel is the pixel position of the line
 * that is currently at the top of the widget.  On
 * some platforms, a text widget can be scrolled by
 * pixels instead of lines so that a partial line
 * is displayed at the top of the widget.
 * </p><p>
 * The top pixel changes when the widget is scrolled.
 * The top pixel does not include the widget trimming.
 * </p>
 *
 * @return the pixel position of the top line
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getTopPixel () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return 0;
	return (int)scrollView.contentView().bounds().y;
}

/**
 * Inserts a string.
 * <p>
 * The old selection is replaced with the new text.
 * </p>
 *
 * @param string the string
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is <code>null</code></li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void insert (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		Point selection = getSelection ();
		string = verifyText (string, selection.x, selection.y, null);
		if (string == null) return;
	}
	if ((style & SWT.SINGLE) != 0) {
		insertEditText (string);
	} else {
		NSTextView widget = (NSTextView) view;
		NSRange range = widget.selectedRange ();
		NSString str;
		if (textLimit != LIMIT) {
			str = getInsertString (string, range);
		} else {
			str = NSString.stringWith (string);
		}
		widget.textStorage ().replaceCharactersInRange (range, str);
	}
	if (string.length () != 0) sendEvent (SWT.Modify);
}

void insertEditText (String string) {
	int length = string.length ();
	Point selection = getSelection ();
	if (hasFocus () && hiddenText == null) {
		if (textLimit != LIMIT) {
			int charCount = getCharCount();
			if (charCount - (selection.y - selection.x) + length > textLimit) {
				length = textLimit - charCount + (selection.y - selection.x);
				length = Math.max(0, length);
			}
		}
		char [] buffer = new char [length];
		string.getChars (0, buffer.length, buffer, 0);
		NSString nsstring = NSString.stringWithCharacters (buffer, buffer.length);
		NSText fieldEditor = ((NSTextField) view).currentEditor ();
		if (fieldEditor != null) fieldEditor.replaceCharactersInRange (fieldEditor.selectedRange (), nsstring);
		selectionRange = null;
	} else {
		String oldText = getText ();
		if (textLimit != LIMIT) {
			int charCount = oldText.length ();
			if (charCount - (selection.y - selection.x) + length > textLimit) {
				string = string.substring(0, textLimit - charCount + (selection.y - selection.x));
			}
		}
		String newText = oldText.substring (0, selection.x) + string + oldText.substring (selection.y);
		setEditText (newText);
		setSelection (selection.x + string.length ());
	}
}

boolean isEventView (long /*int*/ id) {
	if ((style & SWT.MULTI) != 0) return super.isEventView (id);
	return true;
}

boolean isNeeded(ScrollBar scrollbar) {
	boolean result = false;
	if ((style & SWT.MULTI) != 0) {
		NSRect docFrame = scrollView.documentView().frame();
		NSRect contentFrame = scrollView.contentView().frame();
		if ((scrollbar.style & SWT.VERTICAL) != 0) {
			result = docFrame.height > contentFrame.height;
		} else {
			result = docFrame.width > contentFrame.width;
		}
	}
	return result;
}

/**
 * Pastes text from clipboard.
 * <p>
 * The selected text is deleted from the widget
 * and new text inserted from the clipboard.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void paste () {
	checkWidget ();
	if ((style & SWT.READ_ONLY) != 0) return;
	boolean paste = true;
	String oldText = null;
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		oldText = getClipboardText ();
		if (oldText != null) {
			Point selection = getSelection ();
			String newText = verifyText (oldText, selection.x, selection.y, null);
			if (newText == null) return;
			if (!newText.equals (oldText)) {
				if ((style & SWT.SINGLE) != 0) {
					insertEditText (newText);
				} else {
					NSTextView textView = (NSTextView) view;
					NSRange range = textView.selectedRange ();
					NSString str;
					if (textLimit != LIMIT) {
						str = getInsertString (newText, range);
					} else {
						str = NSString.stringWith (newText);
					}
					textView.replaceCharactersInRange (range, str);
				}
				paste = false;
			}
		}
	}
	if (paste) {
		if ((style & SWT.SINGLE) != 0) {
			if (oldText == null) oldText = getClipboardText ();
			if (oldText == null) return;
			insertEditText (oldText);
		} else {
			if (textLimit != LIMIT) {
				if (oldText == null) oldText = getClipboardText ();
				if (oldText == null) return;
				NSTextView textView = (NSTextView) view;
				NSRange range = textView.selectedRange ();
				NSString str = getInsertString (oldText, range);
				textView.replaceCharactersInRange (range, str);
			} else {
				((NSTextView) view).paste (null);
			}
		}
	}
	sendEvent (SWT.Modify);
}

void register() {
	super.register();
	
	if ((style & SWT.SINGLE) != 0) {
		display.addWidget(((NSControl)view).cell(), this);
	}
}

void releaseWidget () {
	super.releaseWidget ();
	if ((style & SWT.SINGLE) != 0) ((NSControl)view).abortEditing();
	hiddenText = null;
	message = null;
	selectionRange = null;
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the receiver's text is modified.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see ModifyListener
 * @see #addModifyListener
 */
public void removeModifyListener (ModifyListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Modify, listener);
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the receiver's text is modified.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SegmentEvent
 * @see SegmentListener
 * @see #addSegmentListener
 * 
 * @since 3.8
 */
public void removeSegmentListener (SegmentListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	eventTable.unhook (SWT.Segments, listener);
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the control is selected by the user.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SelectionListener
 * @see #addSelectionListener
 */
public void removeSelectionListener(SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Selection, listener);
	eventTable.unhook (SWT.DefaultSelection,listener);
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the control is verified.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see VerifyListener
 * @see #addVerifyListener
 */
public void removeVerifyListener (VerifyListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Verify, listener);
}

/**
 * Selects all the text in the receiver.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void selectAll () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		setSelection (0, getCharCount ());
	} else {
		((NSTextView) view).selectAll (null);
	}
}

boolean sendKeyEvent (NSEvent nsEvent, int type) {
	boolean result = super.sendKeyEvent (nsEvent, type);
	if (!result) return result;
	if (type != SWT.KeyDown) return result;
	long /*int*/ modifierFlags = nsEvent.modifierFlags();
	if ((modifierFlags & OS.NSCommandKeyMask) != 0) {
		short keyCode = nsEvent.keyCode ();
		switch (keyCode) {
			case 7: /* X */
				if ((style & SWT.PASSWORD) == 0) cut ();
				return false;
			case 8: /* C */
				if ((style & SWT.PASSWORD) == 0) copy ();
				return false;
			case 9: /* V */
				paste ();
				return false;
			case 0: /* A */
				NSApplication.sharedApplication().sendAction(OS.sel_selectAll_, null, NSApplication.sharedApplication());
				return false;
		}
	}
	if (isDisposed()) return false;
	if ((style & SWT.SINGLE) != 0) {
		short keyCode = nsEvent.keyCode ();
		switch (keyCode) {
			case 76: /* KP Enter */
			case 36: /* Return */
				sendSelectionEvent (SWT.DefaultSelection);
		}
	}
	return result;
}

boolean sendKeyEvent (int type, Event event) {
	boolean result = super.sendKeyEvent (type, event);
	if (!result) return result;
	if (type != SWT.KeyDown) return result;
	if ((event.stateMask & SWT.COMMAND) != 0) {
		switch (event.keyCode) {
			case 'z': 
				NSUndoManager undoManager = view.undoManager();
				if (undoManager == null && (style & SWT.SINGLE) != 0) {
					NSText fieldEditor = ((NSTextField) view).currentEditor ();
					undoManager = fieldEditor.undoManager();
				}
				if (undoManager != null) {
					if ((event.stateMask & SWT.SHIFT) != 0) {
						if (undoManager.canRedo()) {
							undoManager.redo();
							return false;
						}
					} else {
						if (undoManager.canUndo()) {
							undoManager.undo();
							return false;
						}
					}
				}
				return false;
		}
	}
	if (isDisposed()) return false;
	return result;
}

void sendSearchSelection () {
	if (targetSearch != null) {
		((NSSearchField)view).sendAction(actionSearch, targetSearch);
	}
	Event event = new Event ();
	event.detail = SWT.ICON_SEARCH;
	sendSelectionEvent (SWT.DefaultSelection, event, false);
}

void sendCancelSelection () {
	if (targetCancel != null) {
		((NSSearchField)view).sendAction(actionCancel, targetCancel);
	}
	Event event = new Event ();
	event.detail = SWT.ICON_CANCEL;
	sendSelectionEvent (SWT.DefaultSelection, event, false);
}

void setBackgroundColor(NSColor nsColor) {
	if ((style & SWT.SINGLE) != 0) {
		((NSTextField) view).setBackgroundColor (nsColor);
	} else {
		((NSTextView) view).setBackgroundColor (nsColor);
	}
}

void setBackgroundImage(NSImage image) {
	if ((style & SWT.SINGLE) != 0) {
		NSTextField widget = (NSTextField) view;
		widget.setDrawsBackground(image == null);
	} else {
		((NSTextView) view).setDrawsBackground(image == null);
		scrollView.setDrawsBackground(image == null);
	}
}

/**
 * Sets the double click enabled flag.
 * <p>
 * The double click flag enables or disables the
 * default action of the text widget when the user
 * double clicks.
 * </p><p>
 * Note: This operation is a hint and is not supported on
 * platforms that do not have this concept.
 * </p>
 * 
 * @param doubleClick the new double click flag
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setDoubleClickEnabled (boolean doubleClick) {
	checkWidget ();
	this.doubleClick = doubleClick;
}

/**
 * Sets the echo character.
 * <p>
 * The echo character is the character that is
 * displayed when the user enters text or the
 * text is changed by the programmer. Setting
 * the echo character to '\0' clears the echo
 * character and redraws the original text.
 * If for any reason the echo character is invalid,
 * or if the platform does not allow modification
 * of the echo character, the default echo character
 * for the platform is used.
 * </p>
 *
 * @param echo the new echo character
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setEchoChar (char echo) {
	checkWidget ();
	if ((style & SWT.MULTI) != 0) return;
	if ((style & SWT.PASSWORD) == 0) {
		Point selection = getSelection ();
		char [] text = getTextChars ();
		echoCharacter = echo;
		setEditText (text);
		setSelection (selection);
	}
	echoCharacter = echo;
}

/**
 * Sets the editable state.
 *
 * @param editable the new editable state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setEditable (boolean editable) {
	checkWidget ();
	if (editable) {
		style &= ~SWT.READ_ONLY;
	} else {
		style |= SWT.READ_ONLY;
	}
	if ((style & SWT.SINGLE) != 0) {
		((NSTextField) view).setEditable (editable);
	} else {
		((NSTextView) view).setEditable (editable);
	}
}

void setEditText (String string) {
	char [] text = new char [string.length()];
	string.getChars(0, text.length, text, 0);
	setEditText (text);
}

void setEditText (char[] text) {
	char [] buffer;
	int length = Math.min(text.length, textLimit);
	if ((style & SWT.PASSWORD) == 0 && echoCharacter != '\0') {
		hiddenText = new char [length];
		buffer = new char [length];
		for (int i = 0; i < length; i++) {
			hiddenText [i] = text [i];
			buffer [i] = echoCharacter;
		}
	} else {
		hiddenText = null;
		buffer = text;
	}
	NSTextField widget = (NSTextField)view;
	NSString nsstring = NSString.stringWithCharacters (buffer, length);
	widget.setStringValue(nsstring);
	NSText fieldEditor = widget.currentEditor();
	if (fieldEditor != null) {
		fieldEditor.setString(nsstring);
	}
	selectionRange = null;
}

void setFrameSize(long /*int*/ id, long /*int*/ sel, NSSize size) {
	super.setFrameSize (id, sel, size);
	/*
	* Bug in Cocoa.  When a search field is resized while having
	* focus, its editor is not properly positioned within the
	* widget.   The fix is to reposition the editor.
	*/
	if ((style & SWT.SEARCH) != 0) {
		NSSearchField widget = (NSSearchField)view;
		NSText editor = widget.currentEditor ();
		if (editor != null) {
			NSArray subviews = widget.subviews ();
			if (subviews.count () > 0) {
				NSRect rect = widget.cell ().drawingRectForBounds (widget.bounds ());
				new NSView (subviews.objectAtIndex (0)).setFrame (rect);
			}
		}
	}
}

void setFont(NSFont font) {
	if ((style & SWT.MULTI) !=  0) {
		((NSTextView) view).setFont (font);
		return;
	}
	super.setFont (font);
}

void setForeground (double /*float*/ [] color) {
	NSColor nsColor;
	if (color == null) {
		nsColor = NSColor.textColor ();
		if ((style & SWT.MULTI) != 0 && !isEnabled()) nsColor = NSColor.disabledControlTextColor();
	} else {
		double /*float*/ alpha = 1;
		if ((style & SWT.MULTI) != 0 && !isEnabled()) alpha = 0.5f;
		nsColor = NSColor.colorWithDeviceRed (color [0], color [1], color [2], alpha);
	}
	if ((style & SWT.SINGLE) != 0) {
		((NSTextField) view).setTextColor (nsColor);
	} else {
		((NSTextView) view).setTextColor (nsColor);
	}
}

/**
 * Sets the orientation of the receiver, which must be one
 * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
 * <p>
 * Note: This operation is a hint and is not supported on
 * platforms that do not have this concept.
 * </p>
 *
 * @param orientation new orientation style
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.1.2
 */
public void setOrientation (int orientation) {
	checkWidget ();
}

void setOrientation () {
	int direction = (style & SWT.RIGHT_TO_LEFT) != 0 ? OS.NSWritingDirectionRightToLeft : OS.NSWritingDirectionLeftToRight;
	if ((style & SWT.SINGLE) != 0) {
		NSTextField widget = (NSTextField)view;
		widget.setBaseWritingDirection(direction);
	} else {
		NSTextView widget = (NSTextView)view;
		widget.setBaseWritingDirection(direction);
	}
}

/**
 * Sets the widget message. The message text is displayed
 * as a hint for the user, indicating the purpose of the field.
 * <p>
 * Typically this is used in conjunction with <code>SWT.SEARCH</code>.
 * </p>
 * 
 * @param message the new message
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the message is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.3
 */
public void setMessage (String message) {
	checkWidget ();
	if (message == null) error (SWT.ERROR_NULL_ARGUMENT);
	this.message = message;
	if ((style & SWT.SINGLE) != 0) {
		NSString str = NSString.stringWith (message);
		NSTextFieldCell cell = new NSTextFieldCell (((NSTextField) view).cell ());
		cell.setPlaceholderString (str);
	}
}

/**
 * Sets the selection.
 * <p>
 * Indexing is zero based.  The range of
 * a selection is from 0..N where N is
 * the number of characters in the widget.
 * </p><p>
 * Text selections are specified in terms of
 * caret positions.  In a text widget that
 * contains N characters, there are N+1 caret
 * positions, ranging from 0..N.  This differs
 * from other functions that address character
 * position such as getText () that use the
 * regular array indexing rules.
 * </p>
 *
 * @param start new caret position
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setSelection (int start) {
	checkWidget ();
	setSelection (start, start);
}

/**
 * Sets the selection to the range specified
 * by the given start and end indices.
 * <p>
 * Indexing is zero based.  The range of
 * a selection is from 0..N where N is
 * the number of characters in the widget.
 * </p><p>
 * Text selections are specified in terms of
 * caret positions.  In a text widget that
 * contains N characters, there are N+1 caret
 * positions, ranging from 0..N.  This differs
 * from other functions that address character
 * position such as getText () that use the
 * usual array indexing rules.
 * </p>
 *
 * @param start the start of the range
 * @param end the end of the range
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setSelection (int start, int end) {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) {
		NSString str = ((NSTextField) view).stringValue();
		int length = (int)/*64*/str.length ();
		int selStart = Math.min (Math.max (Math.min (start, end), 0), length);
		int selEnd = Math.min (Math.max (Math.max (start, end), 0), length);
		selectionRange = new NSRange ();
		selectionRange.location = selStart;
		selectionRange.length = selEnd - selStart;
		NSText fieldEditor = ((NSControl)view).currentEditor();
		if (fieldEditor != null) {
			fieldEditor.setSelectedRange (selectionRange);
			fieldEditor.scrollRangeToVisible (selectionRange);
		}
	} else {
		int length = (int)/*64*/((NSTextView) view).textStorage ().length ();
		int selStart = Math.min (Math.max (Math.min (start, end), 0), length);
		int selEnd = Math.min (Math.max (Math.max (start, end), 0), length);
		NSRange range = new NSRange ();
		range.location = selStart;
		range.length = selEnd - selStart;
		NSTextView widget = (NSTextView) view;
		widget.setSelectedRange (range);
		widget.scrollRangeToVisible (range);
	}
}

/**
 * Sets the selection to the range specified
 * by the given point, where the x coordinate
 * represents the start index and the y coordinate
 * represents the end index.
 * <p>
 * Indexing is zero based.  The range of
 * a selection is from 0..N where N is
 * the number of characters in the widget.
 * </p><p>
 * Text selections are specified in terms of
 * caret positions.  In a text widget that
 * contains N characters, there are N+1 caret
 * positions, ranging from 0..N.  This differs
 * from other functions that address character
 * position such as getText () that use the
 * usual array indexing rules.
 * </p>
 *
 * @param selection the point
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setSelection (Point selection) {
	checkWidget ();
	if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
	setSelection (selection.x, selection.y);
}

/**
 * Sets the number of tabs.
 * <p>
 * Tab stop spacing is specified in terms of the
 * space (' ') character.  The width of a single
 * tab stop is the pixel width of the spaces.
 * </p>
 *
 * @param tabs the number of tabs
 *
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setTabs (int tabs) {
	checkWidget ();
	if (this.tabs == tabs) return;
	this.tabs = tabs;
	if ((style & SWT.SINGLE) != 0) return;
	double /*float*/ size = textExtent("s").width * tabs;
	NSTextView widget = (NSTextView)view;
	NSParagraphStyle defaultStyle = widget.defaultParagraphStyle();
	NSMutableParagraphStyle paragraphStyle = new NSMutableParagraphStyle(defaultStyle.mutableCopy());
	paragraphStyle.setTabStops(NSArray.array());
	NSTextTab tab = (NSTextTab)new NSTextTab().alloc();
	tab = tab.initWithType(OS.NSLeftTabStopType, size);
	paragraphStyle.addTabStop(tab);
	tab.release();
	paragraphStyle.setDefaultTabInterval(size);
	widget.setDefaultParagraphStyle(paragraphStyle);
	paragraphStyle.release();
}

/**
 * Sets the contents of the receiver to the given string. If the receiver has style
 * SINGLE and the argument contains multiple lines of text, the result of this
 * operation is undefined and may vary from platform to platform.
 *
 * @param string the new text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setText (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		string = verifyText (string, 0, getCharCount (), null);
		if (string == null) return;
	}
	if ((style & SWT.SINGLE) != 0) {
		setEditText (string);
		NSText fieldEditor = ((NSControl)view).currentEditor();
		if (fieldEditor != null) {
			NSRange range = new NSRange();
			fieldEditor.setSelectedRange (range);
			fieldEditor.scrollRangeToVisible (range);
		}
	} else {
		NSTextView widget = (NSTextView)view;
		char[] buffer = new char [Math.min(string.length (), textLimit)];
		string.getChars (0, buffer.length, buffer, 0);
		NSString str = NSString.stringWithCharacters(buffer, buffer.length);
		widget.setString (str);
		widget.setSelectedRange(new NSRange());
	}
	sendEvent (SWT.Modify);
}

/**
 * Sets the contents of the receiver to the characters in the array. If the receiver
 * has style <code>SWT.SINGLE</code> and the argument contains multiple lines of text
 * then the result of this operation is undefined and may vary between platforms.
 *
 * @param text a character array that contains the new text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the array is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see #getTextChars()
 *
 * @since 3.7
 */
public void setTextChars (char[] text) {
	checkWidget ();
	if (text == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
		String string = verifyText (new String (text), 0, getCharCount (), null);
		if (string == null) return;
		text = new char [string.length()];
		string.getChars (0, text.length, text, 0);
	}
	if ((style & SWT.SINGLE) != 0) {
		setEditText (text);
		NSText fieldEditor = ((NSControl)view).currentEditor();
		if (fieldEditor != null) {
			NSRange range = new NSRange();
			fieldEditor.setSelectedRange (range);
			fieldEditor.scrollRangeToVisible (range);
		}
	} else {
		NSTextView widget = (NSTextView)view;
		int length = Math.min(text.length, textLimit);
		NSString str = NSString.stringWithCharacters(text, length);
		widget.setString (str);
		widget.setSelectedRange(new NSRange());
	}
	sendEvent (SWT.Modify);
}

/**
 * Sets the maximum number of characters that the receiver
 * is capable of holding to be the argument.
 * <p>
 * Instead of trying to set the text limit to zero, consider
 * creating a read-only text widget.
 * </p><p>
 * To reset this value to the default, use <code>setTextLimit(Text.LIMIT)</code>.
 * Specifying a limit value larger than <code>Text.LIMIT</code> sets the
 * receiver's limit to <code>Text.LIMIT</code>.
 * </p>
 *
 * @param limit new text limit
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #LIMIT
 */
public void setTextLimit (int limit) {
	checkWidget ();
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
	textLimit = limit;
}

/**
 * Sets the zero-relative index of the line which is currently
 * at the top of the receiver. This index can change when lines
 * are scrolled or new lines are added and removed.
 *
 * @param index the index of the top item
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setTopIndex (int index) {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0) return;
	int row = Math.max(0, Math.min(index, getLineCount() - 1));
	NSPoint pt = new NSPoint();
	pt.x = scrollView.contentView().bounds().x;
	pt.y = getLineHeight() * row;
	view.scrollPoint(pt);
}

boolean shouldChangeTextInRange_replacementString(long /*int*/ id, long /*int*/ sel, long /*int*/ affectedCharRange, long /*int*/ replacementString) {
	NSRange range = new NSRange();
	OS.memmove(range, affectedCharRange, NSRange.sizeof);
	boolean result = callSuperBoolean(id, sel, range, replacementString);
	NSString nsString = new NSString(replacementString);
	if (!hooks(SWT.Verify) && ((echoCharacter =='\0') || (style & SWT.PASSWORD) != 0)) {
		if (!result || (getCharCount() - range.length + nsString.length() > textLimit)) {
			return false;
		}
		return true;
	}
	String text = nsString.getString();
	String newText = text;
	if (hooks (SWT.Verify)) {
		NSEvent currentEvent = display.application.currentEvent();
		long /*int*/ type = currentEvent.type();
		if (type != OS.NSKeyDown && type != OS.NSKeyUp) currentEvent = null;
		newText = verifyText(text, (int)/*64*/range.location, (int)/*64*/(range.location+range.length),  currentEvent);
	}
	if (newText == null) return false;
	if (getCharCount() - range.length + newText.length() > textLimit) {
		return false;
	}
	if ((style & SWT.SINGLE) != 0) {
		if (text != newText || echoCharacter != '\0') {
			 //handle backspace and delete
			if (range.length == 1) {
				NSText editor = new NSText(id);
				editor.setSelectedRange (range);
			}
			insertEditText(newText);
			result = false;
		}
	} else {
		if (text != newText) {
			NSTextView widget = (NSTextView) view;
			widget.textStorage ().replaceCharactersInRange (widget.selectedRange(), NSString.stringWith(newText));
			result = false;
		}
	}
	if (!result) sendEvent (SWT.Modify);
	return result;
}

/**
 * Shows the selection.
 * <p>
 * If the selection is already showing
 * in the receiver, this method simply returns.  Otherwise,
 * lines are scrolled until the selection is visible.
 * </p>
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void showSelection () {
	checkWidget ();
	if ((style & SWT.SINGLE) != 0)  {
		setSelection (getSelection ());
	} else {
		NSTextView widget = (NSTextView) view;
		widget.scrollRangeToVisible (widget.selectedRange ());
	}
}

void textViewDidChangeSelection(long /*int*/ id, long /*int*/ sel, long /*int*/ aNotification) {
	NSNotification notification = new NSNotification (aNotification);
	NSText editor = new NSText (notification.object ().id);
	selectionRange = editor.selectedRange ();
}

void textDidChange (long /*int*/ id, long /*int*/ sel, long /*int*/ aNotification) {
	if ((style & SWT.SINGLE) != 0) super.textDidChange (id, sel, aNotification);
	postEvent (SWT.Modify);
}

NSRange textView_willChangeSelectionFromCharacterRange_toCharacterRange (long /*int*/ id, long /*int*/ sel, long /*int*/ aTextView, long /*int*/ oldSelectedCharRange, long /*int*/ newSelectedCharRange) {
	/*
	* If the selection is changing as a result of the receiver getting focus
	* then return the receiver's last selection range, otherwise the full
	* text will be automatically selected.
	*/
	if (receivingFocus && selectionRange != null) return selectionRange;

	/* allow the selection change to proceed */
	NSRange result = new NSRange ();
	OS.memmove(result, newSelectedCharRange, NSRange.sizeof);
	return result;
}

int traversalCode (int key, NSEvent theEvent) {
	int bits = super.traversalCode (key, theEvent);
	if ((style & SWT.READ_ONLY) != 0) return bits;
	if ((style & SWT.MULTI) != 0) {
		bits &= ~SWT.TRAVERSE_RETURN;
		if (key == 48 /* Tab */ && theEvent != null) {
			long /*int*/ modifiers = theEvent.modifierFlags ();
			boolean next = (modifiers & OS.NSShiftKeyMask) == 0;
			if (next && (modifiers & OS.NSControlKeyMask) == 0) {
				bits &= ~(SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS);
			}
		}
	}
	return bits;
}

void updateCursorRects (boolean enabled) {
	super.updateCursorRects (enabled);
	if (scrollView == null) return;
	NSClipView contentView = scrollView.contentView ();
	contentView.setDocumentCursor (enabled ? NSCursor.IBeamCursor () : null);
}

String verifyText (String string, int start, int end, NSEvent keyEvent) {
	Event event = new Event ();
	if (keyEvent != null) setKeyState(event, SWT.MouseDown, keyEvent);
	event.text = string;
	event.start = start;
	event.end = end;
	/*
	 * It is possible (but unlikely), that application
	 * code could have disposed the widget in the verify
	 * event.  If this happens, answer null to cancel
	 * the operation.
	 */
	sendEvent (SWT.Verify, event);
	if (!event.doit || isDisposed ()) return null;
	return event.text;
}

}
