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

#ifndef _LIB_PREFS_H_
#define _LIB_PREFS_H_

#include "c4d_library.h"
#include "c4d_basecontainer.h"
#include "c4d_gui.h"

#define PREFS_PRI_COMMON			10000200
#define PREFS_PRI_INTERFACE		10000190
#define PREFS_PRI_VIEWPORT		10000180
#define PREFS_PRI_DOCUMENT		10000170
#define PREFS_PRI_ONLINEHELP	10000160
#define PREFS_PRI_SYSTEM			10000150
#define PREFS_PRI_UNITS				10000140
#define PREFS_PRI_IMEXPORT		10000130
#define PREFS_PRI_MATERIAL		10000120
#define PREFS_PRI_TEXTUREPATH	10000110
#define PREFS_PRI_MANAGER			10000100
#define PREFS_PRI_XPRESSO			10000090
#define PREFS_PRI_BROWSER			10000080
#define PREFS_PRI_BODYPAINT3D	10000070
#define PREFS_PRI_SKETCH			10000060
#define PREFS_PRI_HAIR				10000050


class CDialog;
class SubDialog;

// public stuff
struct PrefsDialogHook
{
	void *thisptr;

	CDialog *(*SubDialog_Alloc    )(PrefsDialogHook *thi,void *&userdata);
	void    (*SubDialog_Free      )(PrefsDialogHook *thi,void *userdata);
	void		(*SubDialog_EditStart )(PrefsDialogHook *thi,void *userdata,BaseContainer *bc);
	void		(*SubDialog_EditApply	)(PrefsDialogHook *thi,void *userdata,const BaseContainer &originaldata);
	void		(*SubDialog_EditUndo	)(PrefsDialogHook *thi,void *userdata,const BaseContainer &originaldata);
	void		(*InitPrefs						)(PrefsDialogHook *thi,BaseContainer *bc);
};

Bool PrefsLib_InitPrefs();
Bool PrefsLib_OpenDialog(LONG page);

// helper function for InitPrefs Callback
inline void CheckPrefsData(BaseContainer *worldcontainer,LONG containerid, const GeData &defaultvalue)
{
	if (!worldcontainer) return;
	if (worldcontainer->FindIndex(containerid)!=NOTOK) return;
	worldcontainer->SetData(containerid,defaultvalue);
}

//Example:
//class XXXHook : public XXXHookClass
//{
//	public:	
//		
//		virtual SubDialog *Alloc()	{	return gNew PrefsDlg_XXX(DLG_PREFS_XXX,this); }
//
//		virtual void InitPrefs(BaseContainer *bc)
//		{
//			CheckPrefsData(bc,PLUGIN_ID,GeData(XXX));
//		}
//};

// a class for convenience, DO NOT STORE STATIC !!!
class PrefsDialogHookClass
{
		PrefsDialogHook hook;
		BaseContainer *worldedit;

	public:

		PrefsDialogHookClass();

		Bool Register(LONG id,const String &name,LONG parentid, LONG sortid);
		BaseContainer *GetData();

		// overridable functions
		virtual SubDialog *Alloc();
		virtual void Free(SubDialog *dlg);
		virtual void EditStart(SubDialog *dlg,BaseContainer *worldedit);
		virtual void EditApply(SubDialog *dlg,const BaseContainer &originaldata);
		virtual void EditUndo(SubDialog *dlg,const BaseContainer &originaldata);
		virtual void InitPrefs(BaseContainer *bc);
};

class PrefsDlg_Base : public SubDialog 
{
	protected:
		LONG page;
		PrefsDialogHookClass *hook;

	public:

		PrefsDlg_Base(LONG t_page,PrefsDialogHookClass *t_hook)
		{
			page = t_page;
			hook = t_hook;
		}

		virtual Bool CreateLayout(void)
		{
			if (!LoadDialogResource(page,NULL,BFH_SCALEFIT|BFV_SCALEFIT)) return FALSE;
			return TRUE;
		}

		virtual Bool InitValues(void)
		{
			BaseContainer *data = hook->GetData();
			if (!data) return TRUE;
			SetValues(data);
			EnableValues(data);
			return SubDialog::InitValues();
		}

		virtual Bool Command(LONG id,const BaseContainer &msg);

		virtual void SetValues(BaseContainer *data)
		{
		}

		virtual void EnableValues(BaseContainer *data)
		{
		}

		virtual LONG CommandValues(LONG id,const BaseContainer &msg,BaseContainer *data)
		{
			return 0;
		}
};

// public class


// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF

#define LIBRARY_PREFS					1000466

struct PrefsLib : public C4DLibrary
{
	Bool    (*PrefsLib_RegisterEx )(LONG id,const String *str,PrefsDialogHook *prefsdialoghook,LONG parentid, LONG sortid);
	Bool    (*PrefsLib_Register   )(LONG id,const String *str,PrefsDialogHook *prefsdialoghook,LONG parentid, LONG sortid,LONG sizeofprefs);
	Bool		(*PrefsLib_InitPrefs	)();
	Bool		(*PrefsLib_OpenDialog )(LONG page);
};

// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF

#endif
