/*******************************************************************************
 * Copyright (c) 2000, 2008 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.graphics.*;
import org.eclipse.swt.internal.carbon.HMHelpContentRec;
import org.eclipse.swt.internal.carbon.OS;
import org.eclipse.swt.events.*;

/**
 * Instances of this class represent popup windows that are used
 * to inform or warn the user.
 * <p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>BALLOON, ICON_ERROR, ICON_INFORMATION, ICON_WARNING</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Selection</dd>
 * </dl>
 * </p><p>
 * Note: Only one of the styles ICON_ERROR, ICON_INFORMATION,
 * and ICON_WARNING may be specified.
 * </p><p>
 * IMPORTANT: This class is intended to be subclassed <em>only</em>
 * within the SWT implementation.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#tooltips">Tool Tips 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>
 * 
 * @since 3.2
 */
public class ToolTip extends Widget {
	Shell parent, tip;
	int x, y;
	boolean spikeAbove, autohide;
	TextLayout layoutText, layoutMessage;
	String text, message;
	TrayItem item;
	Region region;
	Font boldFont;
	Runnable runnable;
	
	int helpString;
	static final int BORDER = 5;
	static final int PADDING = 5;
	static final int INSET = 4;
	static final int TIP_HEIGHT = 20;
	static final int IMAGE_SIZE = 16;
	static final int DELAY = 10000;

/**
 * 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#ICON_ERROR
 * @see SWT#ICON_INFORMATION
 * @see SWT#ICON_WARNING
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public ToolTip (Shell parent, int style) {
	super (parent, checkStyle (style));
	this.parent = parent;
	createWidget ();
}

static int checkStyle (int style) {
	int mask = SWT.ICON_ERROR | SWT.ICON_INFORMATION | SWT.ICON_WARNING;
	if ((style & mask) == 0) return style;
	return checkBits (style, SWT.ICON_INFORMATION, SWT.ICON_WARNING, SWT.ICON_ERROR, 0, 0, 0);
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when the receiver is selected by the user, by sending
 * it one of the messages defined in the <code>SelectionListener</code>
 * interface.
 * <p>
 * <code>widgetSelected</code> is called when the receiver is selected.
 * <code>widgetDefaultSelected</code> is not called.
 * </p>
 *
 * @param listener the listener which should be notified when the receiver 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);
}

void configure () {
	Display display = parent.getDisplay ();
	int x = this.x;
	int y = this.y;
	if (x == -1 || y == -1) {
		Point point;
		if (item != null) {
			point = item.getLocation ();
		} else {
			point = display.getCursorLocation ();
		}
		x = point.x;
		y = point.y;
	}
	Monitor monitor = parent.getMonitor ();
	Rectangle dest = monitor.getBounds ();
	Point size = getSize (dest.width / 4);
	int w = size.x;
	int h = size.y;
	int t = (style & SWT.BALLOON) != 0 ? TIP_HEIGHT : 0;
	int i = (style & SWT.BALLOON) != 0 ? 17 : 0;
	tip.setSize (w, h + t);
	int [] polyline;
	spikeAbove = dest.height >= y + size.y + t;
	if (dest.width >= x + size.x) {
		if (dest.height >= y + size.y + t) {
			polyline = new int [] {
				0, 5+t, 1, 5+t, 1, 3+t, 3, 1+t, 5, 1+t, 5, t, 
				16, t, 16, 0, 35, t,
				w-5, t, w-5, 1+t, w-3, 1+t, w-1, 3+t, w-1, 5+t, w, 5+t,
				w, h-5+t, w-1, h-5+t, w-1, h-3+t, w-2, h-3+t, w-2, h-2+t, w-3, h-2+t, w-3, h-1+t, w-5, h-1+t, w-5, h+t,
				5, h+t, 5, h-1+t, 3, h-1+t, 3, h-2+t, 2, h-2+t, 2, h-3+t, 1, h-3+t, 1, h-5+t, 0, h-5+t, 
				0, 5+t};
			tip.setLocation (Math.max (0, x - i), y);
		} else {
			polyline = new int [] {
				0, 5, 1, 5, 1, 3, 3, 1, 5, 1, 5, 0, 
				w-5, 0, w-5, 1, w-3, 1, w-1, 3, w-1, 5, w, 5,
				w, h-5, w-1, h-5, w-1, h-3, w-2, h-3, w-2, h-2, w-3, h-2, w-3, h-1, w-5, h-1, w-5, h,
				35, h, 16, h+t, 16, h,
				5, h, 5, h-1, 3, h-1, 3, h-2, 2, h-2, 2, h-3, 1, h-3, 1, h-5, 0, h-5, 
				0, 5};
			tip.setLocation (Math.max (0, x - i), y - size.y - t);
		}
	} else {
		if (dest.height >= y + size.y + t) {
			polyline = new int [] {
				0, 5+t, 1, 5+t, 1, 3+t, 3, 1+t, 5, 1+t, 5, t, 
				w-35, t, w-16, 0, w-16, t,
				w-5, t, w-5, 1+t, w-3, 1+t, w-1, 3+t, w-1, 5+t, w, 5+t,
				w, h-5+t, w-1, h-5+t, w-1, h-3+t, w-2, h-3+t, w-2, h-2+t, w-3, h-2+t, w-3, h-1+t, w-5, h-1+t, w-5, h+t,
				5, h+t, 5, h-1+t, 3, h-1+t, 3, h-2+t, 2, h-2+t, 2, h-3+t, 1, h-3+t, 1, h-5+t, 0, h-5+t, 
				0, 5+t};
			tip.setLocation (Math.min (dest.width - size.x, x - size.x + i), y);
		} else {
			polyline = new int [] {
				0, 5, 1, 5, 1, 3, 3, 1, 5, 1, 5, 0, 
				w-5, 0, w-5, 1, w-3, 1, w-1, 3, w-1, 5, w, 5,
				w, h-5, w-1, h-5, w-1, h-3, w-2, h-3, w-2, h-2, w-3, h-2, w-3, h-1, w-5, h-1, w-5, h,
				w-16, h, w-16, h+t, w-35, h,
				5, h, 5, h-1, 3, h-1, 3, h-2, 2, h-2, 2, h-3, 1, h-3, 1, h-5, 0, h-5, 
				0, 5};
			tip.setLocation (Math.min (dest.width - size.x, x - size.x + i), y - size.y - t);
		}
	}	
	if ((style & SWT.BALLOON) != 0) {
		if (region != null) region.dispose ();
		region = new Region (display);
		region.add (polyline);
		tip.setRegion (region);
	}
}

void createWidget () {
	super.createWidget ();
	this.autohide = true;
	x = y = -1;	
	text = "";
	message = "";
}


void disposeTip () {
	if (tip != null) tip.dispose ();
	tip = null;
	if (region != null) region.dispose ();
	region = null;
	if (layoutText != null) layoutText.dispose ();
	layoutText = null;
	if (layoutMessage != null) layoutMessage.dispose ();
	layoutMessage = null;
	if (boldFont != null) boldFont.dispose ();
	boldFont = null;
}

/**
 * Returns <code>true</code> if the receiver is automatically
 * hidden by the platform, and <code>false</code> otherwise.
 *
 * @return the receiver's auto hide 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 boolean getAutoHide () {
	checkWidget ();
	return autohide;
}

/**
 * Returns the receiver's message, which will be an empty
 * string if it has never been set.
 *
 * @return the receiver's 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>
 */
public String getMessage () {
	checkWidget ();
	return message;
}

/**
 * Returns the receiver's parent, which must be a <code>Shell</code>.
 *
 * @return the receiver's parent
 *
 * @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 Shell getParent () {
	checkWidget ();
	return parent;
}

Point getSize (int maxWidth) {
	int textWidth = 0, messageWidth = 0;
	if (layoutText != null) {
		layoutText.setWidth (-1);
		textWidth = layoutText.getBounds ().width;
	}
	if (layoutMessage != null) {
		layoutMessage.setWidth (-1);
		messageWidth = layoutMessage.getBounds ().width;
	}
	int messageTrim = 2 * INSET + 2 * BORDER + 2 * PADDING;
	boolean hasImage = 	layoutText != null && (style & SWT.BALLOON) != 0 && (style & (SWT.ICON_ERROR | SWT.ICON_INFORMATION | SWT.ICON_WARNING)) != 0;
	int textTrim = messageTrim + (hasImage ? IMAGE_SIZE : 0);
	int width = Math.min (maxWidth, Math.max (textWidth + textTrim, messageWidth + messageTrim));
	int textHeight = 0, messageHeight = 0;
	if (layoutText != null) {
		layoutText.setWidth (maxWidth - textTrim);	
		textHeight = layoutText.getBounds ().height;
	}
	if (layoutMessage != null) {
		layoutMessage.setWidth (maxWidth - messageTrim);
		messageHeight = layoutMessage.getBounds ().height;
	}
	int height = 2 * BORDER + 2 * PADDING + messageHeight;
	if (layoutText != null) height += Math.max (IMAGE_SIZE, textHeight) + 2 * PADDING;
	return new Point (width, height);
}

/**
 * Returns the receiver's text, which will be an empty
 * string if it has never been set.
 *
 * @return the receiver'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>
 */
public String getText () {
	checkWidget ();
	return text;
}

/**
 * Returns <code>true</code> if the receiver is visible, and
 * <code>false</code> otherwise.
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, this method
 * may still indicate that it is considered visible even though
 * it may not actually be showing.
 * </p>
 *
 * @return the receiver's visibility 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 boolean getVisible () {
	checkWidget ();
	if (tip != null) return	tip.getVisible ();
	if (display.helpWidget == this) {
		int window = OS.FrontWindow ();
		int [] windowClass = new int [1];
		OS.GetWindowClass (window, windowClass);
		return windowClass [0] == OS.kHelpWindowClass;
	}
	return false;
}

/**
 * Returns <code>true</code> if the receiver is visible and all
 * of the receiver's ancestors are visible and <code>false</code>
 * otherwise.
 *
 * @return the receiver's visibility 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>
 *
 * @see #getVisible
 */
public boolean isVisible () {
	checkWidget ();
	return getVisible ();
}

void onMouseDown (Event event) {
	notifyListeners (SWT.Selection, new Event ());
	setVisible (false);
}

void onPaint (Event event) {
	GC gc = event.gc;
	int x = BORDER + PADDING;
	int y = BORDER + PADDING;
	if ((style & SWT.BALLOON) != 0 && spikeAbove) y += TIP_HEIGHT;
	if (layoutText != null) {
		int id = style & (SWT.ICON_ERROR | SWT.ICON_INFORMATION | SWT.ICON_WARNING);
		if ((style & SWT.BALLOON) != 0 && id != 0) {
			Display display = getDisplay ();
			Image image = display.getSystemImage (id);
			Rectangle rect = image.getBounds ();
			gc.drawImage (image, 0, 0, rect.width, rect.height, x, y, IMAGE_SIZE, IMAGE_SIZE);
			x += IMAGE_SIZE;
		}
		x += INSET;
		layoutText.draw (gc, x, y);
		y += 2 * PADDING + Math.max (IMAGE_SIZE, layoutText.getBounds ().height);
	}
	if (layoutMessage != null) {
		x = BORDER + PADDING + INSET;
		layoutMessage.draw (gc, x, y);
	}
}

void releaseWidget () {
	super.releaseWidget ();
	if (runnable != null) {
		Display display = getDisplay ();
		display.timerExec (-1, runnable);
	}
	runnable = null;
	disposeTip ();
	if (helpString != 0) OS.CFRelease (helpString);
	helpString = 0;
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the receiver 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);	
}

/**
 * Makes the receiver hide automatically when <code>true</code>,
 * and remain visible when <code>false</code>.
 *
 * @param autoHide the auto hide 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>
 * 
 * @see #getVisible
 * @see #setVisible
 */
public void setAutoHide (boolean autohide) {
	checkWidget ();
	this.autohide = autohide;
	//TODO - update when visible
}

/**
 * Sets the location of the receiver, which must be a tooltip,
 * to the point specified by the arguments which are relative
 * to the display.
 * <p>
 * Note that this is different from most widgets where the
 * location of the widget is relative to the parent.
 * </p>
 *
 * @param x the new x coordinate for the receiver
 * @param y the new y coordinate for 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 setLocation (int x, int y) {
	checkWidget ();
	if (this.x == x && this.y == y) return;
	this.x = x;
	this.y = y;
	if (tip != null && tip.getVisible ()) configure ();
}

/**
 * Sets the location of the receiver, which must be a tooltip,
 * to the point specified by the argument which is relative
 * to the display.
 * <p>
 * Note that this is different from most widgets where the
 * location of the widget is relative to the parent.
 * </p><p>
 * Note that the platform window manager ultimately has control
 * over the location of tooltips.
 * </p>
 *
 * @param location the new location for the receiver
 *
 * @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 setLocation (Point location) {
	checkWidget ();
	if (location == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	setLocation (location.x, location.y);
}

/**
 * Sets the receiver's message.
 *
 * @param string the new message
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the text 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 setMessage (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	message = string;
	if (tip != null) {
		layoutMessage.setText (string);
		if (tip.getVisible ()) configure ();
	}
}

/**
 * Sets the receiver's text.
 *
 * @param string the new text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the text 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);
	text = string;
	if (tip != null) {
		layoutText.setText (string);
		TextStyle style = new TextStyle (boldFont, null, null);
		layoutText.setStyle (style, 0, string.length ());
		if (tip.getVisible ()) configure ();
	}
}

/**
 * Marks the receiver as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise. 
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, marking
 * it visible may not actually cause it to be displayed.
 * </p>
 *
 * @param visible the new visibility 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 setVisible (boolean visible) {
	if (helpString != 0) OS.CFRelease (helpString);
	helpString = 0;
	if (runnable != null) display.timerExec (-1, runnable);
	runnable = null;
	if (visible) {
		OS.HMHideTag ();
		display.helpWidget = this;
		if (!autohide || (style & SWT.BALLOON) != 0) {
			// Show tip
			if (tip == null) {
				tip = new Shell (parent, SWT.ON_TOP | SWT.NO_TRIM | SWT.TOOL);
				Color background = display.getSystemColor (SWT.COLOR_INFO_BACKGROUND);
				tip.setBackground (background);
				Listener listener = new Listener () {
					public void handleEvent (Event event) {
						switch (event.type) {
							case SWT.Paint: onPaint (event); break;
							case SWT.MouseDown: onMouseDown (event); break;
						}
					}
				};
				tip.addListener (SWT.Paint, listener);
				tip.addListener (SWT.MouseDown, listener);
				
				layoutText = new TextLayout (display);
				layoutText.setText (text);
				Font font = display.getSystemFont ();
				FontData data = font.getFontData () [0];
				boldFont = new Font (display, data.getName (), data.getHeight (), SWT.BOLD);
				TextStyle style = new TextStyle (boldFont, null, null);
				layoutText.setStyle (style, 0, text.length ());	
				layoutMessage = new TextLayout (display);
				layoutMessage.setText(message);
			}
			
			configure ();
			tip.setVisible (true);
			if (autohide) {
				runnable = new Runnable () {
					public void run () {
						if (!isDisposed ()) setVisible (false);
					}
				};
				display.timerExec(DELAY, runnable);
			}
		} else {
			// Show HMTag
			if (tip != null) disposeTip ();
			if (x == -1 || y == -1) {
				Point point;
				if (item != null) {
					point = item.getLocation ();
					x = point.x;
					y = point.y;
				} else {
					org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point ();
					OS.GetGlobalMouse (pt);
					x = pt.h;
					y = pt.v;
				}
			}
			StringBuffer string = new StringBuffer (text);
			if (text.length () > 0) string.append ("\n\n");
			string.append (message);
			char [] buffer = new char [string.length ()];
			string.getChars (0, buffer.length, buffer, 0);
			helpString = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, buffer, buffer.length);
			HMHelpContentRec helpContent = new HMHelpContentRec ();
			helpContent.tagSide = (short) OS.kHMAbsoluteCenterAligned;
			helpContent.absHotRect_left = (short)x;
			helpContent.absHotRect_top = (short)y;
			helpContent.absHotRect_right = (short)(x + 1);
			helpContent.absHotRect_bottom = (short) (y + 1);
			helpContent.content0_contentType = OS.kHMCFStringContent;
			helpContent.content0_tagCFString = helpString;
			helpContent.content1_contentType = OS.kHMCFStringContent;
			helpContent.content1_tagCFString = helpString;
			OS.HMDisplayTag(helpContent);
		}
	} else {
		if (display.helpWidget == this) {
			display.helpWidget = null;
			OS.HMHideTag ();
			if (tip != null) tip.setVisible (false);
		}
	}
}

}
