// TipManager.h
//
// PURPOSE
//   Maintains a set of pop-up tips bound to rectangular
//   regions of any number of views.  Also provides for
//   simple 'manual' operation: call showTip() with text and
//   a screen rectangle, and the tip will be displayed after
//   the mouse has idled in that rectangle.
//
// HISTORY
//   e.moon 19oct99: TipManager now derives from BWindow.
//
//   e.moon 17oct99: reworked the tip window: now exposed via the
//                   TipWindow & TipView classes.
//
//   e.moon 27sep99: optimized TipManager::run() (no longer pounds
//                   the CPU when idling in a view)
//
//   e.moon 13may99: moved TipManager's privates into
//                   TipManagerImpl.h
//
//   e.moon 12may99: expanded to TipManager
//   e.moon 11may99: begun as TipTriggerThread

#ifndef __TipManager_H__
#define __TipManager_H__

#include <SupportDefs.h>
#include <Font.h>
#include <Point.h>
#include <Rect.h>
#include <GraphicsDefs.h>
#include <String.h>

#include <Locker.h>
#include <Window.h>

class BView;

#include "cortex_defs.h"
__BEGIN_CORTEX_NAMESPACE

class TipWindow;

class _TipManagerView;
class _ViewEntry;
class _WindowEntry;

class TipManager :
	protected	BWindow {
	typedef		BWindow _inherited;
	
public:	
	static const BPoint			s_useDefaultOffset;
	static const BPoint			s_defaultOffset;

	static const bigtime_t	s_defIdleTime;
	static const bigtime_t	s_sleepPeriod;

public:										// *** types & constants
	enum flag_t {
		NONE
	};
	
	enum offset_mode_t {
		// offset determines left/top point of tip window
		LEFT_OFFSET_FROM_RECT,		// from the right bound
		LEFT_OFFSET_FROM_POINTER,
		
		// offset determines right/top point of tip window
		// (x offset is inverted; y isn't)
		RIGHT_OFFSET_FROM_RECT,		// from the left bound
		RIGHT_OFFSET_FROM_POINTER
	};

public:										// *** dtor
	virtual ~TipManager();

public:										// *** singleton access
	static TipManager* Instance();
	static void QuitInstance();
	
private:									// hidden constructor (use Instance() to access
													// a single instance)
	TipManager();

public:										// *** add and remove tips

	// add or modify a tip:

	// child allows tips to be added to child views of the main
	// target view.  rect is in view coordinates; only one tip
	// may exist for a particular view with a given top-left
	// corner -- you don't want tip rectangles to overlap in general,
	// but TipManager won't stop you from trying.  Yet.
	// [13may99]

	status_t setTip(
		const BRect&					rect,
		const char*						text,
		BView*								view,
		offset_mode_t					offsetMode	=LEFT_OFFSET_FROM_POINTER,
		BPoint								offset			=s_useDefaultOffset,
		uint32 								flags				=NONE);
	
	// This version of setTip() maps a tip to the entire frame
	// rectangle of a child view.  This call will fail if tips
	// are already being managed for that view; once a
	// full-view tip has been added future attempts call any
	// version of setTip() for that view will also fail.
	// [13may99]

	status_t setTip(
		const char*						text,
		BView*								view,
		offset_mode_t					offsetMode	=LEFT_OFFSET_FROM_POINTER,
		BPoint								offset			=s_useDefaultOffset,
		uint32 								flags				=NONE);
		
	// Remove all tips matching the given rectangle and/or child
	// view.
	
	status_t removeTip(
		const BRect&					rect,
		BView*								view);

	status_t removeAll(
		BView*								view); //nyi-19oct99; lock & hand off
	
	status_t removeAll(
		BWindow*							window); //nyi-19oct99; lock & hand off

public:										// *** manual tip arming

	// [e.moon 19oct99]
	// Call when the mouse has entered a particular region of
	// the screen for which you want a tip to be displayed.
	// The tip will be displayed if the mouse stops moving
	// for idleTime microseconds within the rectangle screenRect.

	status_t showTip(
		const char*						text,
		BRect									screenRect,
		offset_mode_t					offsetMode	=LEFT_OFFSET_FROM_POINTER,
		BPoint								offset			=s_useDefaultOffset,
		uint32 								flags				=NONE);

public:										// *** BWindow
		
public:										// *** BLooper

	virtual bool QuitRequested();
	
public:										// *** BHandler

	virtual void MessageReceived(
		BMessage*							message);
	
private:

	// --------------------------------------------------------------- //
	//                           *** GUTS ***
	// --------------------------------------------------------------- //

	// implements TipManager & enjoys direct (non-polling) access to
	// mouse events:
	_TipManagerView*				m_view;
	
	
private:
	static TipManager*			s_instance;
	static BLocker					s_instanceLock;
};

__END_CORTEX_NAMESPACE
#endif /*__TipManager_H__*/
