/*
    ParaGUI - crossplatform widgetset
    Copyright (C) 2000,2001  Alexander Pipelka
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
 
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
    Alexander Pipelka
    pipelka@teleweb.at
 
    Last Update:      $Author: pipelka $
    Update Date:      $Date: 2001/06/01 09:54:42 $
    Source File:      $Source: /usr/local/CVSROOT/linux/paragui/include/Attic/pgwidget.h,v $
    CVS/RCS Revision: $Revision: 1.1.2.21 $
    Status:           $State: Exp $
*/

#ifndef PG_WIDGET_H
#define PG_WIDGET_H

#ifdef SWIG
%include "swigcommon.h"
%module pgwidget
%{
#include "pgwidget.h"
%}
#endif

#include "pgmessageobject.h"
#include "pgdrawobject.h"
#include "pgrectlist.h"

/**
	@author Alexander Pipelka
	
	@short Base class of all widgets.
 
	Provides graphics context and message handling functionality.

	\anchor theme_PG_Widget

	<h2>Theme support</h2><p>

	This class provides themeing capabilities only for subclassed widgets.<p>

	<b>widget type:</b>		none (managed through subclass)<br>
	<b>object name:</b>		none (managed through subclass)<br>

	<h3>Theme sample:</h3>

	\code
	<widget>
		<type value="xxx"/>
			<object>
			<name value="xxx"/>
			<property color="textcolor" value="0x00FFFFFF"/>
			<property color="bordercolor0" value="0x00202020"/>
			<property color="bordercolor1" value="0x00E0E0E0"/>
		</object>
	</widget>
	\endcode
	<p>
	<h2>Code:</h2><p>
*/

class DECLSPEC PG_Widget : public PG_MessageObject, public PG_DrawObject  {
public:
	/**
	Creates a PG_Widget without an object-surface

	@param parent	the parentobject for the new widget or NULL if it is a toplevel widget
	@param rect	initial position for the widget

	This is the constructor for the PG_Widget class (really!)
	*/
	PG_Widget(PG_Widget* parent, const PG_Rect& rect);

	/**
	Creates a PG_Widget with surface (maybe)

	@param parent	the parentobject for the new widget or NULL if it is a toplevel widget
	@param rect	initial position for the widget
	@param bObjectSurface whether create a surface of not
	*/
	PG_Widget(PG_Widget* parent, const PG_Rect& rect, bool bObjectSurface);

	/**
	Destroys a PG_Widget

	This is the destructor for the PG_Widget class
	*/
	~PG_Widget();

	/**
	Load a style from the theme definition

	@param		widgettype		name of the widgettype
	@param		objectname		name of the object

	Loads the defined style for a given widgettype
	*/
	void LoadThemeStyle(const char* widgettype);

	/**
	Load a style from the theme definition

	@param		widgettype		name of the widgettype
	@param		objectname		name of the object

	Loads the defined style of a given widgettype and objectname.
	*/
	virtual void LoadThemeStyle(const char* widgettype, const char* objectname);

	/**
	Start to drag a widget

	StartWidgetDrag prepares to widget to be dragged.
	*/
	void StartWidgetDrag();

	/**
	Drag the widget to a given position (in screen coordinates)

	@param	x		x-position
	@param	y		y-position
	*/
	void WidgetDrag(int x, int y);

	/**
	Finishes a drag operation

	@param	x		x endposition
	@param	y		y endposition
	*/
	void EndWidgetDrag(int x, int y);

	/**
	Move a widget

	@param x	new x-position (in parent context)
	@param y	new y-position (in parent context)
	@return		function succeeded

	This function moves the widget
	*/
	bool MoveWindow(int x, int y);

	/**
	Resize a widget

	@param w	new widget-width
	@param w	new widget-height
	@return		function succeeded

	This function resizes the widget
	*/
	bool SizeWindow(int w, int h);

	/**
	Convert a client (widget) coordinate to a screen position

	@param	x		x - widgetcoordinate
	@param	y		y - widgetcoordinate
	@return			PG_Point structure with the screen position
	*/
	PG_Point ClientToScreen(int x, int y);

	/**
	Convert a screen position to a client (widget) coordinate

	@param	x		x - screenposition
	@param	y		y - screenposition
	@return			PG_Point structure with the client position
	*/
	PG_Point ScreenToClient(int x, int y);

	/**
	Return the pointer to the widget's drawing surface

	@return			SDL_Surface pointer to the drawing surface
	*/
	SDL_Surface* GetWidgetSurface();

	/**
	Return the pointer to the screen surface

	@return			SDL_Surface pointer to the screen surface
	*/
	SDL_Surface* GetScreenSurface();

	/**
	Get the parentwidget of a widget	

	@return		a pointer to the parentwidget or NULL if there is no parentwidget
	*/
	PG_Widget* GetParent();

	/**
	Add a clientwidget (which will be embedded into this widget)
	
	@param	child		the widget to add
	*/
	void AddChild(PG_Widget* child);

	/**
	Process a native PG_ event

	@param	event	PG_ event to process
	@return			true if the event was sucessfully processed

	ProcessEvent asks the widget to process a given event.
	*/
	bool ProcessEvent(const SDL_Event* event);

	/**
	Set the widgetid

	@param	id		a number which can be used to identify the widget

	This id can be used in callbacks or eventhandlers to identify the widget
	*/
	void SetID(int id);

	/**
	Return the widgetid
	@return			id of the widget
	*/
	int GetID();

	/**
	Check if the mousepointer is currently inside the widget
	@return			true if the mousepointer is inside
	*/
	bool IsMouseInside();

	/**  */
	bool IsDisplayRectValid();

	/**
	Redraw the widget and all embedded child widgets
	@param	update		if true Update() is called after the redraw
	@return					true if the redraw operation succeeded
	*/
	bool Redraw(bool update = true);

	/**
	Blit the widget to the screen
	@param	recursive		if true all embedded widget will also be blitted to screen
	@param restore		restore the background before blitting if true
	This function only performs a SDL_BlitSurface() the screen content will NOT be updated
	*/
	virtual void Blit(bool recursive = true, bool restore = true);

	/**
	Update the widget's screen area
	@param	doBlit		if true a Blit() operation is done before the update
	*/
	void Update(bool doBlit = true);

	/**
	Update a screen area
	@param r	update rectangle
	*/
	static void UpdateRect(const PG_Rect& r);

	/**
	Update (render) the whole application screen
	*/
	static void UpdateScreen();

	/**
	Make a widget visible
	@param	fade		do a smooth fade in if true
	*/
	void Show(bool fade = false);

	/**
	Hide a widget
	@param	fade		do a smooth fade out if true
	*/
	void Hide(bool fade = false);

	/**
	Reorder the widget in front of all others
	*/
	void BringToFront();

	/**
	Hide all widgets of an application
	*/
	static void HideAll();

	void RecalcClipRect();

	/**
	Restore the background (all widgets behind this one)
	*/
	virtual bool RestoreBackground(PG_Rect* clip = NULL);

	static PG_Widget* FindWidgetFromPos(int x, int y);

	/**
	Set the visiblility of a widget with updating the screen contents
	@param	visible		true - visible / false - invisible
	*/
	void SetVisible(bool visible);

	/**
	Set the number of steps for fading in/out widgets
	@param	steps		number of steps
	*/
	void SetFadeSteps(int steps);

	/**
	Set the transparency of all child widgets
	@param	t	transparency 0 - opaque / 255 - full transparent
	*/
	void SetChildTransparency(Uint8 t);

	/**
	Get a list of child widgets

	@return		pointer to childlist
	*/
	PG_RectList* GetChildList();

	/**
	Get the number of childwidgets

	@return		number of childwidgets
	*/
	int GetChildCount();

	/**
	Set the font

	@param newfont	the widget's new font

	This function sets the font of the widget
	*/
	void SetFont(TTF_Font* newfont);

	/**
	Returns the current font

	@return		pointer to the TTF_Font structure
	*/
	TTF_Font* GetFont();

	/**  */
	void MoveRect(int x, int y);

	/**
	Set the text color for the widget
	@param	color	a Uint32 defining the color (0x00RRGGBB)
	*/
	void SetTextColor(Uint32 color);

	/**
	Set the text color for the widget
	@param	color	a SDL_Color struct defining the color
	*/
#ifdef SWIG
	/** SWIG can't handle multiple functions with one name */
	%name(SetTextColor2) void SetTextColor(SDL_Color c);
#else
	void SetTextColor(SDL_Color c);
#endif
	
	/**
	Return the current text color
	@return	SDL_Color struct
	*/
	SDL_Color GetTextColor();
	
	/** */
	static void BulkUpdate();

	/** */
	static void BulkBlit();
		
	// Navigation

	/** */
	virtual bool Action(PG_ACTION action);

	/**  */
	virtual void eventMouseLeave();

	/**  */
	virtual void eventMouseEnter();

protected:

	/**  */
	virtual void eventShow();

	/**  */
	virtual void eventHide();

	/**  */
	void FadeOut();

	/**  */
	void FadeIn();

	/**  */
	bool AcceptEvent(const SDL_Event* event);

	/**	*/
	bool RemoveChild(PG_Widget* child);

	void RemoveFromWidgetList();
	void AddToWidgetList();

	PG_RectList* GetWidgetList();

	bool bSetCaptureOnShow;

private:

	void InitWidget();

	PG_Widget(const PG_Widget&);
	PG_Widget& operator=(const PG_Widget&);

	PG_Widget* my_widgetParent;
	PG_RectList* my_childList;

	SDL_mutex* my_mutexProcess;
	TTF_Font* my_font;
	SDL_Color my_textcolor;
	
	static PG_RectList widgetList;

	int my_id;
	bool my_mouseInside;
	int my_fadeSteps;
	bool my_haveTooltip;

	static bool bBulkUpdate;
};

#endif // PG_WIDGET_H
