/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NWIDGET__
#define	__NWIDGET__


		#include "ui/ui_event_handler.h"
		#include "geometry/rect.h"
		#include "math/vector.h"
		#include "memory/nshared_ptr.h"
		#include "memory/nweak_ptr.h"


namespace GS {
	class Picture;

	namespace S2D {
		class Widget;

		typedef	SharedPtr <Widget> sWidget;

/// Widget type.
enum	WidgetType
{
	WidgetTypeBase			=	0,
	WidgetTypeSizer,
	WidgetTypeVSizer,
	WidgetTypeHSizer,
	WidgetTypeContainer,
	WidgetTypeSpacer,
	WidgetTypeText,
	WidgetTypeCanvas,
	WidgetTypeDrawable,
	WidgetTypeBitmap,
	WidgetTypeCheck
};

/*!
	@short	Base widget.
	@author	Emmanuel Julien (ejulien@nworks.fr)
*/
class	Widget : public SharedObject
{
public:

enum	Align
{
	AlignNone = 0,
	AlignLeft,
	AlignTop,
	AlignMiddle,
	AlignRight,
	AlignBottom,
	AlignGrow
};

protected:

		WidgetType		type;
		Widget			*parent;

		AutoPtr <EventTable> event_table;

		int				object_id;
		iRect			rect;

		Align			h_align, v_align;

		bool			hidden;					///< Hidden.
		bool			dirty;					///< Dirty flag.

		Vector4			border_size;			///< Border size in pixel (x->top, y->bottom, z->left, w->right).

		SharedList <Widget *> children;

		Vector2		format;					///< Formatting size.

		/// Setup and align output rectangle.
		iRect			FormatOutputRect(const iRect &rect, const iRect &out_rect);

public:

		int				GetId() const { return object_id; }
		WidgetType		GetType() const { return type; }

		void			SetHidden(bool h = true);
		bool			IsHidden() const { return hidden; }
		bool			IsDirty() const { return dirty; }
		
		void			Validate() { dirty = false; }
virtual	void			Invalidate();

virtual	void			Refresh() = 0;
virtual	void			Compose(Picture &output, const iRect &clip_rect) = 0;

		EventTable		*GetEventTable() const { return event_table; }

		void			SetParent(Widget *w);
		Widget			*GetParent() const { return parent; }

		Widget			*GetChild(int id);

		const SharedList <Widget *> &GetChildren() const { return children; }

		/// Return widget rect in parent window client space.
		iRect			GetRect() const;

		void			SetBorderSize(float top = 2, float bottom = 2, float left = 2, float right = 2);
		void			SetHAlign(Align = AlignMiddle);
		void			SetVAlign(Align = AlignMiddle);
		void			SetFormattingSize(const Vector2 &);

		/// Get widget formatting size ratio.
		Vector2			GetFormat() const;

		Widget(int id = -1);
virtual	~Widget();
};

	} // S2D
} // GS


#endif	// __NWIDGET__
