/*
 *  psychlops_widgets_prototype.h
 *  Psychlops Standard Library (Universal)
 *
 *  Last Modified 2009/02/15 by Kenchi HOSOKAWA
 *  (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
 */

#ifndef HEADER_PSYCHLOPS_WIDGET
#define HEADER_PSYCHLOPS_WIDGET

#include <string>
#include "../../../core/graphic/psychlops_g_module.h"
#include "../../../psychlops_core.h"
#include "../psychophysics/psychlops_exp_psychophysics.h"
#include "psychlops_widgets_event.h"


namespace Psychlops {

	class Widget : public Figure {
	};
namespace ExperimentalMethods
{
	class Variable;
}

namespace Widgets {

	class WidgetBase : public Events::Emittable, public Group
	{
		protected:
		Events::Container *parent_;
		Events::Dispatcher slots_;
		public:
		Rectangle area;

		public:
		WidgetBase();
		virtual Rectangle getArea();
		virtual Events::Container& getParent();
		virtual Events::Container& setParent(Events::Container &par);
		virtual Events::Dispatcher& getSlots();
		virtual void distribute(Event &ev);
		virtual void distribute(Events::PointerDeviceEvent &event);
		void tabStop(bool on_off = true);
	};







	struct Theme {
		static bool initialized__;
		static Image default_button, default_horiz_grad;
		enum TYPE_TAG { NORMAL, ALERT };
		public:
		Color normal_foreground[2], active_foreground[2];
		Color normal_background[2], active_background[2], over_background[2];
		Stroke normal_stroke[2], active_stroke[2];
		Image *button_back, *horiz_grad;

		static Theme current;
		static void initialize();
	};

	Point drawableMouse(Drawable &d);




	class WidgetDatum : public Widget {
	public:
		Point datum;
		WidgetDatum();
		~WidgetDatum();
		virtual const Point getDatum() const;
		virtual WidgetDatum& setDatum(const Point&);
		virtual WidgetDatum& centering(const Point&);
		using Figure::centering;
	};

	class WidgetRect : public Widget {
		protected:
		HumanInterfaceDevice::ButtonStateHolder mleft;
		int pressFrame;
		bool tabStopRegistered;

		bool pushed_;

		public:
		static int __LAST_TOTAL_REFRESH;
		static double __autoAlign_;
		static void __autoAlign(WidgetRect &target);		

		Theme *theme;
		Theme::TYPE_TAG theme_type;
		Rectangle area;
		Letters label;

		WidgetRect();
		virtual const Point getDatum() const;
		virtual WidgetRect& setDatum(const Point&);
		virtual WidgetRect& centering(const Point&);
		using Figure::centering;
		double getWidth() const;
		double getHeight() const;
		double getLeft() const;
		double getTop() const;
		double getRight() const;
		double getBottom() const;
		WidgetRect& alignLeft(const double lef);
		WidgetRect& alignTop(const double to_);
		WidgetRect& alignRight(const double rig);
		WidgetRect& alignBottom(const double bot);

		virtual WidgetRect& set(double wid, double hei);
		virtual WidgetRect& set(std::wstring name);
		virtual WidgetRect& set(std::wstring name, double hei);
		virtual WidgetRect& setLabel(std::wstring s);
		virtual WidgetRect& draw(Drawable &target = *Drawable::prime);
		bool pushed();
		WidgetRect& pushThis();
	};

	class StackPanel : public WidgetRect {
	protected:
		std::deque< WidgetRect* > content;
	public:
		enum Orientation { VERTICAL, HORIZONTAL };
		Orientation orientation;
		bool forceBase, forceAnother;

		double pitch;
		StackPanel();
		StackPanel& setWidth(double wid);
		StackPanel& setHeight(double hei);
		StackPanel& append(WidgetRect *target1, WidgetRect *target2=0, WidgetRect *target3=0, WidgetRect *target4=0, WidgetRect *target5=0);
		StackPanel& remove(WidgetRect *target);
		void align(Orientation ori = VERTICAL);
		virtual StackPanel& draw(Drawable &target = *Drawable::prime);

		static StackPanel default_stack;
	};



}	/*	<- namespace Widgets 	*/
}	/*	<- namespace Psycholops 	*/


#endif
