/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/include/sgx/gui/widget.hpp

*/

#ifndef SGX_CORE_GUI_WIDGET_HPP
#define SGX_CORE_GUI_WIDGET_HPP	1

class sgxWidget;

class sgxGUIWidgetCallbackHandler {
public:
	virtual tBOOL			onGUIWidgetPressed(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetRelease(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetLeaveArea(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetReenterArea(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetKeyDown(const sgxWidget *pWidget, const tUINT32 key);
	virtual tBOOL			onGUIWidgetKeyUp(const sgxWidget *pWidget, const tUINT32 key);
	virtual tBOOL			onGUIWidgetHoverEnter(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetHoverLeave(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetFocusGain(const sgxWidget *pWidget);
	virtual tBOOL			onGUIWidgetFocusLose(const sgxWidget *pWidget);
	virtual tBOOL			onGUIWidgetActiveGain(const sgxWidget *pWidget);
	virtual tBOOL			onGUIWidgetActiveLose(const sgxWidget *pWidget);

	virtual tBOOL			onGUIWidgetSelect(const sgxWidget *pWidget, const sgxPoint2i &position);
	virtual tBOOL			onGUIWidgetSelectActive(const sgxWidget *pWidget);
};

class sgxWidgetHandler : public sgxGUIWidgetCallbackHandler {
public:
		tBOOL onSelect(const sgxWidget *pWidget) {
			return onGUIWidgetSelect(pWidget, sgxPoint2i());
	}
};

class sgxWidget : public CGameHandler {
public:

	typedef enum {
		eInFrontOf,
		eBehind,
	} tDepthPosition;

	typedef  enum {
		eAll=0,
		eFunctioningWidgets,
		eAllFromTop,		// reverse order selection
	} tSelectionSet;

	typedef enum {
		eTriggerOnDown = 1,
	} tWidgetFlags;

	sgxWidget(const tINT32 x=0, const tINT32 y=0, const CGUIDesignScreen::tWidgetType type=CGUIDesignScreen::widgetUnknown);

	virtual CGUIDesignScreen::tWidgetType	getType();

	virtual tBOOL			enable(const tBOOL enabled=TRUE);
	virtual tBOOL			disable();
	virtual tBOOL			show(const tBOOL show=TRUE);
	virtual tBOOL			hide();
	virtual void			setCallback(CSGXCallback *pCallback, const tBOOL recursively=FALSE);
	virtual CSGXCallback *	getCallback() const;
	virtual sgxGUIWidgetCallbackHandler *getHandler();
	virtual void			setHandler(sgxGUIWidgetCallbackHandler *pNewHandler, const tBOOL recursively=FALSE);

	virtual void 			setText(const sgxString &s);
	virtual void			getPosition(sgxPoint2i &pt);
	virtual tUINT32			getWidth() const;
	virtual tUINT32			getHeight() const;

	virtual void 			setPosition(const sgxPoint2i &pt);
	virtual void 			setPosition(const tINT32 x, const tINT32 y);
	virtual void 			setSize(const tINT32 w, const tINT32 h);

	virtual void			update(const tREAL32 telaps);
	virtual void			draw() const;
	virtual void			draw(CSGXDrawSurface *pSurface) const { draw(pSurface,0,0); }	// explicitly done, because draw(x,y) would hide parent class method
	virtual tBOOL			draw(CSGXDrawSurface *pSurface, const tINT32 offsetX, const tINT32 offsetY) const;

	virtual tBOOL			onPressed(const sgxPoint2i &position);
	virtual tBOOL			onRelease(const sgxPoint2i &position);
	virtual tBOOL			onLeaveArea(const sgxPoint2i &position);
	virtual tBOOL			onReenterArea(const sgxPoint2i &position);
	virtual tBOOL			onKeyDown(const tUINT32 key);
	virtual tBOOL			onKeyUp(const tUINT32 key);
	virtual tBOOL			onHoverEnter(const sgxPoint2i &position);
	virtual tBOOL			onHoverLeave(const sgxPoint2i &position);
	virtual tBOOL			onFocusGain();
	virtual tBOOL			onFocusLose();
	virtual tBOOL			onActiveGain();
	virtual tBOOL			onActiveLose();

	virtual tBOOL			onSelect(const sgxPoint2i &position);
	virtual tBOOL			onActiveSelect();

	virtual tBOOL			isFocused() const;
	virtual tBOOL			isActive() const;
	virtual tBOOL			isEnabled() const;
	virtual tBOOL			isVisible() const;
	
	virtual tBOOL			isPointInside(const sgxPoint2i &position) const;
	virtual void			getArea(sgxRect2i &rc) const;

	virtual tBOOL 			reorderWidget(sgxWidget *pTargetWidget, const tDepthPosition pos, sgxWidget *pMarkerWidget);

	virtual const sgxWidget*getWidgetAt(const sgxPoint2i &position) const;
	virtual sgxWidget *		getWidgetAt(const sgxPoint2i &position, const tSelectionSet fromSet=eAll);
	virtual tUINT32			getWidgetListWithin(const sgxRect2i &rc, sgxVector<sgxWidget *> &widgetList);
	virtual sgxWidget *		getWidgetOfUserData(const sgxString &str);
	virtual sgxWidget *		getWidgetOfUserData(const tUINT32 userdata);
	virtual sgxWidget *		getWidgetWithKeyShortcut(const tUINT32 key);

	virtual sgxWidget *		addChildWidget(sgxWidget *pWidget);
	virtual tUINT32			getChildWidgetCount();
	virtual sgxWidget *		getChildWidget(const tUINT32 idx);
	virtual sgxWidget *		getChildWidget(const tUINT32 idx, CGUIDesignScreen::tWidgetType type);
	virtual sgxWidget *		getNextSibling(const tBOOL bWrap = FALSE);
	virtual sgxWidget *		getPreviousSibling(const tBOOL bWrap = FALSE);
	virtual void 			clearChildWidgets();
	virtual void 			releaseChildWidgets();

	virtual tUINT32			getUserData() const { return m_UserData; }
	virtual tUINT32 		setUserData(const tUINT32 id) {tUINT32 old = m_UserData; m_UserData=id; return old; }
	virtual tUINT32 		setFlags(const tUINT32 flags) {tUINT32 old = m_iFlags; m_iFlags=flags; return old; }

	virtual tUINT32 		setKeyShortcut(const tUINT32 key) {tUINT32 old = m_KeyboardShortcut; m_KeyboardShortcut=key; m_KeyboardShortcutExt = 0; return old; }
	
protected:

	CGUIDesignScreen::tWidgetType	m_Type;

	sgxVector<sgxWidget *>			m_Children;
	sgxWidget *						m_pParent;
	sgxGUIWidgetCallbackHandler *	m_pHandler;

	tINT32							m_X, m_Y;
	tBOOL							m_bEnabled;
	tBOOL							m_bVisible;
	CSGXCallback *					m_pSelectCallback;

	tBOOL							m_State;
	tUINT32							m_iFlags;
	tBOOL							m_DirectedState;	// true means the mouse has clicked onto it, and is currently hovering over it
	tBOOL							m_isOver;			// for when the cursor hovers over the buttons, whether the button is pressed or not
	sgxWidgetGroup *				m_pGroup;
	tUINT32							m_KeyboardShortcut;		// the key itself
	tUINT32							m_KeyboardShortcutExt;	// the extensions, e.g. alt, necessary
	//
	tMEM_SIZE						m_UserData;
};

#endif /* SGX_CORE_GUI_WIDGET_HPP */

