/////////////////////////////////////////////////////////////
// CINEMA 4D SDK                                           //
/////////////////////////////////////////////////////////////
// (c) MAXON Computer GmbH, all rights reserved            //
/////////////////////////////////////////////////////////////

#ifndef __C4DGUI_H
#define __C4DGUI_H

#ifndef __API_INTERN__
	#include "ge_math.h"
	#include "c4d_string.h"
	#include "gui.h"
	#define IDC_OK	   1
	#define IDC_CANCEL 2
	#include "c4d_gedata.h"
	#include "c4d_thread.h"
	enum
	{
		FORMAT_REAL									= 'frea',
		FORMAT_LONG									= 'flng',
		FORMAT_PERCENT							= 'fpct',
		FORMAT_DEGREE								= 'fdgr',
		FORMAT_METER								= 'fmet',
		FORMAT_FRAMES								= 'ffrm',
		FORMAT_SECONDS							= 'fsec',
		FORMAT_SMPTE								= 'fsmp'
	};

#else
	#include "ge_math.h"
	#include "ge_string.h"
	#include "gui_defs.h"
	#include "gui_newdialog.h"
	#include "gui_coredefs.h"
	#include "c4d_basetime.h"
	#include "operatingsystem.h"
#endif

class BaseBitmap;
class BaseContainer;
class GeResource;
class Filename;
class SubDialog;
class BaseDocument;
class GeDialog;
struct CUSTOMGUIPLUGIN;

typedef UCHAR OBSOLETE;

// for popupcreation
#define FIRST_POPUP_ID (900000)

#define IDM_CM_CLOSEWINDOW		12097

#define MAXTIME								108000      // maximum time value equal 1.0 hours at 30fps //x2.77x hours!

#define COREMSG_CINEMA_GETCOMMANDNAME				200000033
#define COREMSG_CINEMA_GETCOMMANDENABLED		200000035
#define COREMSG_CINEMA_GETCOMMANDCHECKED    300000115
#define COREMSG_CINEMA_EXECUTEEDITORCOMMAND 200000023
#define COREMSG_CINEMA_EXECUTESUBID         300001036
#define COREMSG_CINEMA_EXECUTEOPTIONMODE    300001037
#define COREMSG_CINEMA_GETCOMMANDHELP       200000234

#define COREMSG_CINEMA_FORCE_AM_UPDATE			1001077		// CoreMesage: Force AM update
#define COREMSG_UPDATECOMMANDSMESSAGE				200000100

#define C4DGUIPTR		(-1)
#define C4DGUINOPTR	(-2)

class C4DGadget
{
	public:
};

class GadgetPtr
{
		LONG _id;
		C4DGadget *gad;

	public:

		GadgetPtr(LONG t_id) { _id = t_id; gad = NULL;}
		GadgetPtr(C4DGadget *t_gad) { _id = C4DGUIPTR; gad = t_gad; }

		LONG Id() const { return _id; };
		C4DGadget *Ptr() const { return gad; }
};

class GeUserArea
{
	friend class GeDialog;

	private:
		Bool owncu;
		CUserArea *cu;

	protected:
		GeDialog  *dlg;

	public:

		GeUserArea(void);
		virtual ~GeUserArea(void);

		CUserArea *Get() { return cu; }
		void Set(CUserArea *t_cu) { cu = t_cu; owncu=TRUE; }
		GeDialog  *GetDialog( void ) { return dlg; }

		// for overriding (for easy message handling)
		virtual Bool Init         (void);
		virtual Bool InitValues   (void);
		virtual Bool GetMinSize   (LONG &w,LONG &h);
		virtual void Sized        (LONG w,LONG h);
		virtual OBSOLETE Draw     (LONG x1,LONG y1,LONG x2,LONG y2);
		virtual void DrawMsg      (LONG x1,LONG y1,LONG x2,LONG y2,const BaseContainer &msg);
		virtual Bool InputEvent   (const BaseContainer &msg);
		virtual Bool CoreMessage  (LONG id,const BaseContainer &msg);
		virtual void Timer        (const BaseContainer &msg);

		// for overriding (for special message handling)
		virtual LONG Message      (const BaseContainer &msg,BaseContainer &result);

		// functions to call
		void Redraw               (Bool threaded=FALSE);
		Bool SendParentMessage    (const BaseContainer &msg);

		LONG GetId                (void);
		LONG GetWidth             (void);
		LONG GetHeight            (void);
		Bool IsEnabled						(void);
		Bool HasFocus							(void);

		// input events and tTimer
		void SetTimer             (LONG timer);
		Bool GetInputState        (LONG askdevice,LONG askchannel,BaseContainer &res);
		Bool GetInputEvent        (LONG askdevice,BaseContainer &res);
		void KillEvents           (void);
		Bool IsHotkeyDown					(LONG id);
		
		// pens
		void DrawSetPen           (const Vector &color);
		void DrawSetPen           (LONG id);
		void DrawSetPen           (const GeData &d);
		void DrawSetTextCol       (LONG fg,LONG bg);
		void DrawSetTextCol       (const Vector &fg,LONG bg);
		void DrawSetTextCol       (LONG fg,const Vector &bg);
		void DrawSetTextCol       (const Vector &fg,const Vector &bg);
		void DrawSetTextCol       (const GeData& fg, const GeData& bg);
		Bool GetColorRGB          (LONG colorid, LONG &r, LONG &g, LONG &b);
		void ActivateFading				(LONG milliseconds);
		void AdjustColor					(LONG colorid, LONG highlightid, Real percent);

		// draw functions
		void DrawLine             (LONG x1,LONG y1,LONG x2,LONG y2);
		void DrawRectangle        (LONG x1,LONG y1,LONG x2,LONG y2);
		void DrawBitmap           (BaseBitmap *bmp,LONG wx,LONG wy,LONG ww,LONG wh,LONG x,LONG y,LONG w,LONG h,LONG mode);
#define	DRAWTEXT_HALIGN_LEFT			0
#define	DRAWTEXT_HALIGN_CENTER		1
#define	DRAWTEXT_HALIGN_RIGHT			2
#define	DRAWTEXT_HALIGN_MASK			0x000f
#define	DRAWTEXT_VALIGN_TOP				(0<<4)
#define	DRAWTEXT_VALIGN_CENTER		(1<<4)
#define	DRAWTEXT_VALIGN_BOTTOM		(2<<4)
#define	DRAWTEXT_VALIGN_MASK			0x00f0
#define	DRAWTEXT_STD_ALIGN				( DRAWTEXT_HALIGN_LEFT | DRAWTEXT_VALIGN_TOP )
		void DrawText             (const String &txt,LONG x,LONG y,LONG flags = DRAWTEXT_STD_ALIGN );
#define DRAWBEZIER_BX		0
#define DRAWBEZIER_BY		1
#define DRAWBEZIER_CX		2
#define DRAWBEZIER_CY		3
#define DRAWBEZIER_DX		4
#define DRAWBEZIER_DY		5
		void DrawBezier						(Real sx, Real sy, Real *p, LONG len, Bool closed, Bool filled);
		void FillBitmapBackground (BaseBitmap *bmp,LONG offsetx,LONG offsety);

		// fonts
		void DrawSetFont          (LONG fontid);
		LONG DrawGetTextWidth     (const String &text);
		LONG DrawGetTextWidth_ListNodeName(BaseList2D *node, LONG fontid=FONT_STANDARD);
		LONG DrawGetFontHeight    (void);
		LONG DrawGetFontBaseLine	(void);
		void DrawSetTextRotation	(Real textrotation); // degree, cw, dont forget to reset it to 0 afterwards

		// others
		void SetClippingRegion    (LONG x,LONG y,LONG w,LONG h);
		void ClearClippingRegion  (void);
		Bool OffScreenOn          (void);
		Bool OffScreenOn					(LONG x, LONG y, LONG w, LONG h);
		void ScrollArea           (LONG xdiff,LONG ydiff,LONG x,LONG y,LONG w,LONG h);

		Bool Local2Global         (LONG *x, LONG *y);
		Bool Global2Local         (LONG *x, LONG *y);
		Bool Local2Screen         (LONG *x, LONG *y);
		Bool Screen2Local         (LONG *x, LONG *y);

		void LayoutChanged        (void);

		Bool GetDragPosition      (const BaseContainer &msg,LONG *x,LONG *y);
		Bool GetDragObject        (const BaseContainer &msg,LONG *type,void **object);
		Bool HandleMouseDrag      (const BaseContainer &msg,LONG type,void *data,LONG dragflags);
		Bool SetDragDestination   (LONG cursor);
		void GetBorderSize        (LONG type,LONG *l,LONG *t,LONG *r,LONG *b);
		void DrawBorder           (LONG type,LONG x1,LONG y1,LONG x2,LONG y2);

#ifdef __API_INTERN__
		Bool OpenPopUpMenu				(LONG menuid,LONG localx,LONG localy, LONG watchhotkey);
#endif

		Bool CheckDropArea        (const BaseContainer &msg,Bool horiz,Bool vert);

		void MouseDragStart				(LONG button,Real mx,Real my,MOUSEDRAGFLAGS flag);
		MOUSEDRAGRESULT MouseDrag	(Real *mx,Real *my,BaseContainer *channels);
		MOUSEDRAGRESULT MouseDragEnd(void);

		Bool IsR2L				        (void);

#define MOUSEMOVE_DELTA_TABLET	6.0
#define MOUSEMOVE_DELTA_MOUSE 	2.0

		// LassoSelection is working with GeDialog & GeUserArea
};


template <class TYPE> class TriState
{
		LONG tri;
		TYPE value;

	public:
		TriState()							{ tri = -1; value = TYPE(); }
		TriState(const TYPE &val) { tri = 0; value = val; }
		Bool GetTri() const			{ return tri==1; }
		const TYPE &GetValue() const		{ return value;  }
		Bool HasChanged() const { return tri!=-1; }
		void Add(TYPE val)
		{
			if (tri==-1)
			{
				tri = 0;
				value = val;
			}
			else if (tri==0 && value!=val)
			{
				tri = 1;
			}
		}
		void Add(BaseContainer *bc,LONG id);
		LONG Check(GeDialog *dlg,const BaseContainer &msg,LONG cid,LONG gid);
		LONG CheckVector(GeDialog *dlg,const BaseContainer &msg,LONG current_id,LONG gidx,LONG gidy,LONG gidz);
		LONG CheckBaseTime(GeDialog *dlg,const BaseContainer &msg,BaseDocument *doc,LONG cid,LONG gid);
};


class GeDialog
{
	friend class GeUserArea;
	friend class _GeListView;

	private:
		CDialog				*cd;
		LONG					t_lastcoremsg;

	protected:
		Bool					createlayout;

	public:
		GeDialog(void);
		virtual ~GeDialog(void);

		CDialog *Get() { return cd; }
#ifdef __API_INTERN__
		Bool dontfree;
		void Set(CDialog* set);
#endif

		// for overriding (for easy message handling)
		virtual Bool CreateLayout (void);
		virtual Bool InitValues   (void);
		virtual Bool CoreMessage  (LONG id,const BaseContainer &msg);
		virtual Bool Command      (LONG id,const BaseContainer &msg);
		virtual Bool AskClose     (void);
		virtual void Timer        (const BaseContainer &msg);
		virtual void DestroyWindow(void); // use this function to set all pointers to userareas/customgui elements to NULL

		// for overriding (for special message handling)
		virtual LONG Message      (const BaseContainer &msg,BaseContainer &result);

		// functions to call
		Bool Open                 (DLG_TYPE dlgtype,LONG pluginid,LONG xpos=-1,LONG ypos=-1,LONG defaultw=0,LONG defaulth=0,LONG subid=0);
		Bool Close                (void);
		Bool Close                (Bool dummy);
		GeData SendMessage        (const GadgetPtr &id,const BaseContainer &msg);
		Bool SendParentMessage    (const BaseContainer &msg);
		LONG GetId                (void);
		Bool IsOpen								();
		Bool IsVisible						();

		void SetTimer             (LONG timer);
		void SetTitle							(const String &title);

		Bool GetInputState				(LONG askdevice,LONG askchannel,BaseContainer &res);
		Bool GetInputEvent				(LONG askdevice,BaseContainer &res);
		void KillEvents						(void);

		// set/get functions
		Bool Enable               (const GadgetPtr &id, Bool enabled);
		Bool IsEnabled            (const GadgetPtr &id);
		Bool SetBool              (const GadgetPtr &id, Bool value,LONG tristate=0);
		Bool SetLong              (const GadgetPtr &id, LONG value,LONG min=MINLONGl,LONG max=MAXLONGl,LONG step=1,LONG tristate=0,LONG min2=MINLONGl,LONG max2=MAXLONGl);
		Bool SetReal              (const GadgetPtr &id, Real value,Real min=MINREALr,Real max=MAXREALr,Real step=1.0,LONG format=FORMAT_REAL,Real min2=0.0,Real max2=0.0,Bool quadscale=FALSE,LONG tristate=0);
		Bool SetMeter             (const GadgetPtr &id, Real value,Real min=MINREALr,Real max=MAXREALr,Real step=1.0,LONG tristate=0);
		Bool SetDegree            (const GadgetPtr &id, Real radians_value,Real min=MINREALr,Real max=MAXREALr,Real step=1.0,LONG tristate=0);
		Bool SetPercent           (const GadgetPtr &id, Real value,Real min=0.0,Real max=100.0,Real step=1.0,LONG tristate=0);
		Bool SetTime							(const GadgetPtr &id, const BaseDocument *doc, const BaseTime &value,const BaseTime &min=BaseTime(-MAXTIME,1), const BaseTime &max=BaseTime(MAXTIME,1),LONG stepframes = 1,LONG tristate=0);
		Bool SetString            (const GadgetPtr &id, const String &text,LONG tristate=0, LONG flags=0);
		Bool SetColorField        (const GadgetPtr &id, const Vector &color, Real brightness, Real maxbrightness, LONG flags);
		Bool SetFilename          (const GadgetPtr &id, const Filename &fn,LONG tristate=0);

		Bool GetBool              (const GadgetPtr &id, Bool &value) const;
		Bool GetLong              (const GadgetPtr &id, LONG &value) const;
		Bool GetReal              (const GadgetPtr &id, Real &value) const;
		Bool GetVector            (const GadgetPtr &id_x, const GadgetPtr &id_y, const GadgetPtr &id_z, Vector &value) const;
		Bool GetString            (const GadgetPtr &id, String &text) const;
		Bool GetColorField        (const GadgetPtr &id, Vector &color, Real &brightness) const;
		Bool GetTime							(const GadgetPtr &id, const BaseDocument *doc, BaseTime &time) const;
		Bool GetFilename          (const GadgetPtr &id, Filename &fn) const;

		Bool CheckTristateChange	(const GadgetPtr &id); // return wheter the gadget content has been changed since the last SetXXX or not

		// container set/get functions
		Bool SetBool              (const GadgetPtr &id, const BaseContainer *bc, LONG bcid);
		Bool SetLong              (const GadgetPtr &id, const BaseContainer *bc, LONG bcid,LONG min=MINLONGl,LONG max=MAXLONGl,LONG step=1,LONG min2=MINLONGl,LONG max2=MAXLONGl);
		Bool SetReal              (const GadgetPtr &id, const BaseContainer *bc, LONG bcid,Real min=MINREALr,Real max=MAXREALr,Real step=1.0,LONG format=FORMAT_REAL,Real min2=0.0,Real max2=0.0,Bool quadscale=FALSE);
		Bool SetMeter             (const GadgetPtr &id, const BaseContainer *bc, LONG bcid,Real min=MINREALr,Real max=MAXREALr,Real step=1.0);
		Bool SetDegree            (const GadgetPtr &id, const BaseContainer *bc, LONG bcid,Real min=MINREALr,Real max=MAXREALr,Real step=1.0);
		Bool SetPercent           (const GadgetPtr &id, const BaseContainer *bc, LONG bcid,Real min=0.0,Real max=100.0,Real step=1.0);
		Bool SetTime							(const GadgetPtr &id, const BaseDocument *doc, const BaseContainer *bc, LONG bcid, const BaseTime &min=BaseTime(-MAXTIME,1), const BaseTime &max=BaseTime(MAXTIME,1),LONG stepframes=1);

		Bool SetString            (const GadgetPtr &id, const BaseContainer *bc, LONG bcid, LONG flags=0);
		Bool SetFilename          (const GadgetPtr &id, const BaseContainer *bc, LONG bcid);
		Bool SetColorField        (const GadgetPtr &id, const BaseContainer *bc, LONG bc_colid, LONG bc_brightnessid, Real maxbrightness, LONG flags);

		Bool GetBool              (const GadgetPtr &id, BaseContainer *bc, LONG bcid) const;
		Bool GetLong              (const GadgetPtr &id, BaseContainer *bc, LONG bcid) const;
		Bool GetReal              (const GadgetPtr &id, BaseContainer *bc, LONG bcid) const;
		Bool GetTime							(const GadgetPtr &id, const BaseDocument *doc, BaseContainer *bc, LONG bcid) const;
		Bool GetVector            (const GadgetPtr &id_x, const GadgetPtr &id_y, const GadgetPtr &id_z, BaseContainer *bc, LONG bcid) const;
		Bool GetString            (const GadgetPtr &id, BaseContainer *bc, LONG bcid) const;
		Bool GetFilename          (const GadgetPtr &id, BaseContainer *bc, LONG bcid) const;
		Bool GetColorField        (const GadgetPtr &id, BaseContainer *bc, LONG bc_colid, LONG bc_brightnessid) const;

		// set/get functions for tristates
		Bool SetBool              (const GadgetPtr &id, const TriState<Bool> &tri);
		Bool SetLong              (const GadgetPtr &id, const TriState<LONG> &tri,LONG min=MINLONGl,LONG max=MAXLONGl,LONG step=1,LONG min2=MINLONGl,LONG max2=MAXLONGl);
		Bool SetReal              (const GadgetPtr &id, const TriState<Real> &tri,Real min=MINREALr,Real max=MAXREALr,Real step=1.0,LONG format=FORMAT_REAL,Real min2=0.0,Real max2=0.0,Bool quadscale=FALSE);
		Bool SetMeter             (const GadgetPtr &id, const TriState<Real> &tri,Real min=MINREALr,Real max=MAXREALr,Real step=1.0);
		Bool SetDegree            (const GadgetPtr &id, const TriState<Real> &tri,Real min=MINREALr,Real max=MAXREALr,Real step=1.0);
		Bool SetPercent           (const GadgetPtr &id, const TriState<Real> &tri,Real min=0.0,Real max=100.0,Real step=1.0);
		Bool SetTime							(const GadgetPtr &id, const BaseDocument *doc, const TriState<BaseTime> &tri,const BaseTime &min=BaseTime(-MAXTIME,1), const BaseTime &max=BaseTime(MAXTIME,1),LONG stepframes = 1);
		Bool SetString            (const GadgetPtr &id, const TriState<String> &tri, LONG flags=0);
			#define FLAG_CENTER_HORIZ		1
			#define FLAG_CENTER_VERT		2
			#define FLAG_ALIGN_RIGHT		4
		Bool SetMultiLinePos			(const GadgetPtr &id, LONG line, LONG pos);

		Bool SetColorField        (const GadgetPtr &id, const TriState<Vector> &tri, Real brightness, Real maxbrightness, LONG flags);

		Bool CheckValueRanges     (void);

		Bool Local2Global         (LONG *x, LONG *y);
		Bool Global2Local         (LONG *x, LONG *y);
		Bool Screen2Local					(LONG *x, LONG *y);
		Bool Local2Screen					(LONG *x, LONG *y);
		Bool GetColorRGB          (LONG colorid, LONG &r, LONG &g, LONG &b);
		void SetDefaultColor			(const GadgetPtr &id, LONG colorid, LONG mapid);
		void SetDefaultColor			(const GadgetPtr &id, LONG colorid, const Vector &color);

		// layout stuff
		Bool LoadDialogResource   (LONG id, GeResource *lr, LONG flags);

		C4DGadget *AddCheckbox          (LONG id, LONG flags, LONG initw, LONG inith, const String &name);
		C4DGadget *AddButton            (LONG id, LONG flags, LONG initw, LONG inith, const String &name);
		C4DGadget *AddStaticText        (LONG id, LONG flags, LONG initw, LONG inith, const String &name,LONG borderstyle);
		C4DGadget *AddArrowButton       (LONG id, LONG flags, LONG initw, LONG inith, LONG arrowtype);
		C4DGadget *AddEditText          (LONG id, LONG flags, LONG initw=0, LONG inith=0, LONG editflags=0);
		C4DGadget *AddMultiLineEditText (LONG id, LONG flags, LONG initw=0, LONG inith=0,LONG style=0);
		C4DGadget *AddEditNumber        (LONG id, LONG flags, LONG initw=80, LONG inith=0);
		C4DGadget *AddEditNumberArrows  (LONG id, LONG flags, LONG initw=70, LONG inith=0);
		C4DGadget *AddEditSlider        (LONG id, LONG flags, LONG initw=80, LONG inith=0);
		C4DGadget *AddSlider            (LONG id, LONG flags, LONG initw=90, LONG inith=0);
		C4DGadget *AddColorField        (LONG id, LONG flags, LONG initw=0,  LONG inith=0, LONG colorflags=0/*DR_COLORFIELD_ICC_xxxx*/);
		C4DGadget *AddColorChooser      (LONG id, LONG flags, LONG initw=0,  LONG inith=0, LONG layoutflags=0);
		C4DGadget *AddRadioButton				(LONG id, LONG flags, LONG initw, LONG inith, const String &name);
		C4DGadget *AddRadioText					(LONG id, LONG flags, LONG initw, LONG inith, const String &name);
		C4DGadget *AddEditShortcut      (LONG id, LONG flags, LONG initw=0, LONG inith=0, LONG shortcutflags=0);

		C4DGadget *AddSeparatorH        (LONG initw,LONG flags=BFH_FIT);
		C4DGadget *AddSeparatorV        (LONG inith,LONG flags=BFV_FIT);

		Bool AddRadioGroup							(LONG id, LONG flags, LONG columns=1, LONG rows=0);
		C4DGadget *AddComboBox          (LONG id, LONG flags, LONG initw=0, LONG inith=0,Bool specialalign=FALSE);
		C4DGadget *AddComboButton				(LONG id, LONG flags, LONG initw=0, LONG inith=0,Bool specialalign=FALSE);
		C4DGadget *AddPopupButton				(LONG id, LONG flags, LONG initw=0, LONG inith=0);
		Bool AddListView								(LONG id, LONG flags, LONG initw=0, LONG inith=0);

		Bool AddChild             (const GadgetPtr &id, LONG subid,const String &child);
		Bool FreeChildren         (const GadgetPtr &id);
		Bool SetPopup							(const GadgetPtr &id,const BaseContainer &bc);
		Bool AddChildren					(const GadgetPtr &id, const BaseContainer &bc);

		C4DGadget *AddUserArea          (LONG id, LONG flags, LONG initw=0, LONG inith=0);
		Bool AttachUserArea							(GeUserArea &ua,const GadgetPtr &id,USERAREAFLAGS userareaflags=USERAREA_COREMESSAGE);

		Bool AddSubDialog					(LONG id,LONG flags,LONG initw=0,LONG inith=0);
		Bool AttachSubDialog	    (SubDialog *userdlg,LONG id);

		Bool AddDlgGroup          (LONG type);

		Bool GroupBeginInMenuLine	();
		Bool TabGroupBegin        (LONG id, LONG flags,LONG tabtype=TAB_TABS);
		Bool GroupBegin           (LONG id, LONG flags,LONG cols,LONG rows,const String &title,LONG groupflags, LONG initw=0, LONG inith=0);
		Bool GroupEnd             (void);
		Bool GroupSpace           (LONG spacex,LONG spacey);
		Bool GroupBorder          (ULONG borderstyle);
		Bool GroupBorderNoTitle		(ULONG borderstyle);
		Bool GroupBorderSpace     (LONG left, LONG top,LONG right,LONG bottom);
		Bool GroupWeightsSave			(const GadgetPtr &id,BaseContainer &weights);
		Bool GroupWeightsLoad			(const GadgetPtr &id,const BaseContainer &weights);
			// flags for GroupWeights
			#define GROUPWEIGHTS_PERCENT_W_CNT	2000
			#define GROUPWEIGHTS_PERCENT_W_VAL	(GROUPWEIGHTS_PERCENT_W_CNT+1)
			#define GROUPWEIGHTS_PERCENT_H_CNT  3000
			#define GROUPWEIGHTS_PERCENT_H_VAL	(GROUPWEIGHTS_PERCENT_H_CNT+1)

		Bool GetItemDim           (const GadgetPtr &id,LONG *x,LONG *y,LONG *w,LONG *h);
		Bool GetDragPosition      (const BaseContainer &msg,LONG *x,LONG *y);
		Bool GetDragObject        (const BaseContainer &msg,LONG *type,void **object);
		Bool SetDragDestination   (LONG cursor,LONG gadgetid=0);

		Bool GetVisibleArea       (LONG scrollgroupid,LONG *x1,LONG *y1,LONG *x2,LONG *y2);
		Bool SetVisibleArea       (LONG scrollgroupid,LONG x1,LONG y1,LONG x2,LONG y2);
		Bool ScrollGroupBegin     (LONG id, LONG flags,LONG scrollflags,LONG initw=0,LONG inith=0);

		Bool LayoutChanged        (const GadgetPtr &id);
		Bool LayoutChangedNoRedraw(const GadgetPtr &id);
		Bool Activate             (const GadgetPtr &id);

		Bool LayoutFlushGroup     (const GadgetPtr &id);
		Bool RemoveElement				(const GadgetPtr &id);
		Bool HideElement					(const GadgetPtr &id, Bool hide);

		Bool RestoreLayout				(LONG pluginid,LONG subid,void *secret);

		Bool MenuFlushAll         (void); // call to create a complete new menu
		Bool MenuSubBegin         (const String &string); // create a new menugroup
		Bool MenuSubEnd           (void); // close a menugroup
		Bool MenuAddCommand       (LONG cmdid); // add a command to the menugroup
		Bool MenuAddString        (LONG id,const String &string); // add a string to the menugroup
		Bool MenuAddSeparator     (void); // add a separator
		Bool MenuFinished         (void); // call when finished the menulayout
		Bool MenuInitString       (LONG id,Bool enabled,Bool checked);

		Bool CheckClose						(void);

		void *FindCustomGui				(LONG id,LONG pluginid);
		void *AddCustomGui				(LONG id,LONG pluginid,const String &name,LONG flags,LONG minw,LONG minh,const BaseContainer &customdata);
		Bool ReleaseLink();

		Bool MenuSetResource      (LONG id);
#ifdef __API_INTERN__
		Bool OpenPopUpMenu				(LONG menuid,LONG localx,LONG localy, LONG watchhotkey);
#endif

		Bool CheckDropArea        (const GadgetPtr &id,const BaseContainer &msg,Bool horiz,Bool vert);
		Bool CheckCoreMessage			(const BaseContainer &msg, LONG *ownlastcoremsg=NULL); // speedup for CoreMessages, return TRUE if new, FALSE if it's a message of the same age

		static void HandleHelpString(const BaseContainer &msg, BaseContainer &result, const String &sym);
		
		// for private use only!!!
		void *GetWindowHandle			();
		// for private use only!!!
		
		//multiline text gadget
		Bool SetMultiLineMode(const GadgetPtr &id, SCRIPTMODE mode);
		Bool SetMultiLineLock(const GadgetPtr &id, Bool lock);
};

class GeModalDialog : public GeDialog
{
	private:
		Bool dlg_result;
		Bool close;
	public:
		GeModalDialog(void);
		virtual ~GeModalDialog(void);

		Bool Open(LONG xpos=-1,LONG ypos=-1,LONG defaultw=0,LONG defaulth=0,Bool resizable=FALSE);
		Bool Close(Bool result);
		Bool GetResult(void) { return dlg_result; }

		// for overriding (for special message handling)
		virtual LONG Message(const BaseContainer &msg,BaseContainer &result);

		void CheckLong(LONG id, CHECKVALUERANGE type, LONG val, LONG x, LONG y);
		void CheckReal(LONG id, CHECKVALUERANGE type, Real val, Real x, Real y, CHECKVALUEFORMAT format=CHECKVALUEFORMAT_NOTHING);
		void CheckMeter(LONG id, CHECKVALUERANGE type, Real val, Real x, Real y);
		void CheckPercent(LONG id, CHECKVALUERANGE type, Real val, Real x, Real y);
		void CheckDegree(LONG id, CHECKVALUERANGE type, Real val, Real x, Real y);
};

class SubDialog : public GeDialog
{
		Bool dlg_result;

	public:
		SubDialog(void);
		virtual ~SubDialog(void);
		virtual LONG Message(const BaseContainer &msg,BaseContainer &result);
};

class iCustomGui : public SubDialog
{
		LONG layoutmode;
		LONG editheight;
		CUSTOMGUIPLUGIN *plugin;

	public:

		iCustomGui(const BaseContainer &settings,CUSTOMGUIPLUGIN *t_plugin);

		virtual LONG Message(const BaseContainer &msg,BaseContainer &result);

		virtual LONG CustomGuiWidth();
		virtual LONG CustomGuiHeight();
		virtual void CustomGuiRedraw();
		virtual Bool CustomGuiLayoutChanged();
		virtual Bool CustomGuiActivate();
		virtual Bool SetDefaultForResEdit();

		virtual Bool SetData(const TriState<GeData> &tristate);
		virtual TriState<GeData> GetData();

		// for overriding
		virtual Bool SupportLayoutSwitch();
		virtual void LayoutModeChanged();

		// NOT needed to override
		virtual void SetLayoutMode(LONG mode);
		virtual LONG GetLayoutMode();
			#define LAYOUTMODE_NONE				0	// does not support layoutmodes
			#define LAYOUTMODE_MINIMIZED	1
			#define LAYOUTMODE_MAXIMIZED	2

		LONG GetEditHeight() { return editheight; }

		CUSTOMGUIPLUGIN *GetPlugin() { return plugin; }
};

inline LONG SizePixChr(LONG pixels,LONG chars) { return (pixels<<14)+chars; }
inline LONG SizePix(LONG pixels)               { return SizePixChr(pixels,0); }
inline LONG SizeChr(LONG chars)                { return SizePixChr(0,chars); }

#ifndef __API_INTERN__
	void MessageDialog(const String &str);
	void MessageDialog(LONG id);
	void MessageDialog(LONG id, const String &p1);
	void MessageDialog(LONG id, const String &p1, const String &p2);
	Bool QuestionDialog(const String &str);
	Bool QuestionDialog(LONG id);
	Bool QuestionDialog(LONG id, const String &p1);
	Bool QuestionDialog(LONG id, const String &p1, const String &p2);
	Bool GetInputEvent(LONG askdevice,BaseContainer &res);
	Bool GetInputState(LONG askdevice,LONG askchannel,BaseContainer &res);
#endif

#define MOUSEPOS (0x7FFFFFFF) // use this value for screenx/screeny
LONG ShowPopupMenu(CDialog *cd,LONG screenx,LONG screeny,const BaseContainer &bc,LONG flags=POPUP_RIGHT|POPUP_EXECUTECOMMANDS, LONG *res_mainid=NULL);

Bool RemoveLastCursorInfo(LASTCURSORINFOFUNC func);

String Shortcut2String(LONG shortqual,LONG shortkey);
String Shortcut2String(const BaseContainer &sc);

inline Vector GetGuiWorldColor(LONG cid) { return C4DOS.Ge->GetGuiWorldColor(cid); }

Bool GetIconCoordInfo(LONG &id, const CHAR* ident);
#define INTERFACE_ICON_TYPE_NORMAL		0
#define INTERFACE_ICON_TYPE_DISABLED	1
#define INTERFACE_ICON_TYPE_FOCUS			2
Bool GetInterfaceIcon(LONG type, LONG id_x, LONG id_y, LONG id_w, LONG id_h, IconData &d);
GeClipMap	*GetInterfaceScheme(LONG type);

//-------------------------------------------------------------------------------------------------
class ProgressDialog;
#ifdef __API_INTERN__
	#define C4DThread BaseThread
#endif

class ProgressThread : public C4DThread
{
	public:
		ProgressDialog *dlg;

		virtual void Main(void);
		virtual const CHAR* GetThreadName(void);
};

class ProgressDialog : public GeModalDialog
{
	private:
		ProgressThread thread;
		Real           percent;
		GeSpinlock		 callback_lock;
		void					 *(*callback)( void *context );
		void					 *callback_context;
		void					 *callback_result;
		
	public:
		// from GeModalDialog
		virtual Bool CreateLayout(void);
		virtual Bool InitValues(void);
		virtual void Timer(const BaseContainer& msg);
		virtual LONG Message(const BaseContainer &msg,BaseContainer &result);
		virtual Bool Command(LONG id, const BaseContainer &msg);
		virtual Bool AskClose(void);

		// for use in inherited class  
		void SetPercent(Real p);
		C4DThread	*GetThread( void );
		void	*CallFromMainThread( void *(*fn)( void *context ), void *context );

		// for overriding
		virtual void Main(C4DThread *bt)=0;
		virtual String GetTitle(void)=0;      
};

#endif
