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

#ifndef __C4DBASEDOCUMENT_H
#define __C4DBASEDOCUMENT_H

#include "c4d_baselist.h"
#include "c4d_file.h"
#include "c4d_tools.h"
#include "operatingsystem.h"

class BaseTag;
class TextureTag;
class BaseObject;
class BaseMaterial;
class Thread;

class PluginSceneHook : public BaseList2D
{
	private:
		PluginSceneHook();
		~PluginSceneHook();
};

class RenderData : public BaseList2D
{
	private:
		RenderData();
		~RenderData();
	public:
		RenderData *GetNext(void) { return (RenderData*)AtCall(GetNext)(); }
		RenderData *GetPred(void) { return (RenderData*)AtCall(GetPred)(); }

		PluginVideoPost *GetFirstVideoPost();
		void InsertVideoPost(PluginVideoPost *pvp, PluginVideoPost *pred=NULL);

		static RenderData	*Alloc(void);
		static void Free(RenderData *&v);
};

//---------------------- LAYERS --------------------------------------------------------
class LayerObject : public BaseList2D
{
	private:
		LayerObject();
		~LayerObject();

	public:
		LayerObject *GetNext    (void) { return (LayerObject*)AtCall(GetNext)(); }
		LayerObject *GetPred    (void) { return (LayerObject*)AtCall(GetPred)(); }
		LayerObject *GetDown    (void) { return (LayerObject*)AtCall(GetDown)(); }
		LayerObject *GetUp      (void) { return (LayerObject*)AtCall(GetUp)(); }
		LayerObject *GetDownLast(void) { return (LayerObject*)AtCall(GetDownLast)(); }

		static LayerObject	*Alloc(void);
		static void Free(LayerObject *&v);
};

struct LayerData
{
	Bool   solo;       // solo mode
	Bool   view;       // visible in editor view
	Bool   render;     // visible in render view
	Bool   manager;    // visible in scene browser, timeline
	Bool   locked;     // not selectable, nece no modification possible - greyed out in Scene Browser
	Bool   generators; // generators on /off
	Bool   deformers;  // deformers on /off
	Bool   expressions;// expressions on /off
	Bool   animation;  // animation on/off

	Vector color;
};


//--------------------------------------------------------------------------------------

#define SELECTION_NEW	0
#define SELECTION_ADD	1
#define SELECTION_SUB	2

class BaseDocument : public BaseList2D
{
	private:
		BaseDocument();
		~BaseDocument();
	public:
		BaseDocument *GetNext(void) { return (BaseDocument*)AtCall(GetNext)(); }
		BaseDocument *GetPred(void) { return (BaseDocument*)AtCall(GetPred)(); }

		BaseContainer GetData(LONG type);
		void SetData(LONG type, const BaseContainer &bc);
		BaseContainer *GetSettingsInstance(LONG type);

		BaseObject		*GetFirstObject(void);
		BaseMaterial	*GetFirstMaterial(void);
		RenderData		*GetFirstRenderData(void);

		void InsertRenderData(RenderData *rd, RenderData *pred=NULL);
		void InsertMaterial(BaseMaterial *mat, BaseMaterial *pred=NULL, Bool checknames=TRUE);
		void InsertObject(BaseObject *op, BaseObject *parent, BaseObject *pred, Bool checknames=TRUE);

		RenderData		*GetActiveRenderData(void);
		BaseObject		*GetActiveObject  (void);
		BaseMaterial	*GetActiveMaterial(void);
		BaseTag				*GetActiveTag     (void);

		void				  GetActiveObjects  (AtomArray &selection,Bool childs) const;
		void				  GetActivePolygonObjects(AtomArray &selection,Bool childs) const;
		void				  GetActiveTags     (AtomArray &selection) const;
		void				  GetActiveMaterials(AtomArray &selection) const;
		void				  GetSelection      (AtomArray &selection) const;

		void SetActiveObject    (BaseObject *op,LONG mode=SELECTION_NEW);
		void SetActiveTag       (BaseTag *tag,LONG mode=SELECTION_NEW);
		void SetActiveMaterial  (BaseMaterial	*mp,LONG mode=SELECTION_NEW);
		void SetActiveRenderData(RenderData *rd);
		void SetSelection       (BaseList2D *bl, LONG mode=SELECTION_NEW);

		void Flush(void);

		BaseObject *GetHighest(LONG type, Bool editor);

		BaseMaterial	*SearchMaterial   (const String &str);
		BaseMaterial	*SearchMaterialInc(const String &str);
		BaseObject		*SearchObject     (const String &str);
		BaseObject		*SearchObjectInc  (const String &str);

		BaseObject		*GetHelperAxis(void);

		BaseContainer	GetAllTextures(void);
		BaseContainer	GetAllTextures(const AtomArray *ar);

		Bool			GetChanged(void);
		void			SetChanged(void);

		Filename	GetDocumentName(void);
		Filename	GetDocumentPath(void);
		void			SetDocumentName(const Filename &fn);
		void			SetDocumentPath(const Filename &path);

		Real			GetLOD(void);
		void			SetLOD(Real lod);

		LONG			GetFps(void);
		void			SetFps(LONG fps);

		BaseTime	GetMinTime(void);
		void			SetMinTime(const BaseTime &t);

		BaseTime	GetMaxTime(void);
		void			SetMaxTime(const BaseTime &t);

		BaseTime	GetUsedMinTime(BaseList2D *check);
		BaseTime	GetUsedMaxTime(BaseList2D *check);

		BaseTime	GetLoopMinTime(void);
		void			SetLoopMinTime(const BaseTime &t);

		BaseTime	GetLoopMaxTime(void);
		void			SetLoopMaxTime(const BaseTime &t);

		Bool			GetRenderLod(void);
		void			SetRenderLod(Bool lod);

		BaseTime	GetTime      (void);
		void			SetTime(const BaseTime &t);

		LONG			GetMode(void);
		void			SetMode(LONG m);

		LONG			GetAction(void);
		void			SetAction(LONG a);

		Bool			IsEditMode(void);

		Bool			StartUndo(void);
		Bool			EndUndo(void);
		Bool			AddUndo(LONG type, void *data);
		Bool			DoUndo(Bool multiple = FALSE);
		Bool			DoRedo(void);
		BaseList2D* GetUndoPtr() { return C4DOS.Bd->GetUndoPtr(this); }
		void      AutoKey(BaseList2D *undo, BaseList2D *op, Bool recursive, Bool pos, Bool scale, Bool rot, Bool param, Bool pla) { C4DOS.Bd->AutoKey(this, undo, op, recursive, pos, scale, rot, param, pla); }
		Bool			RecordKey(BaseList2D *op, const BaseTime &time, const DescID &id, BaseList2D *undo, Bool eval_attribmanager, Bool autokeying, Bool allow_linking){ return C4DOS.Bd->RecordKey(this,op,time,id,undo,eval_attribmanager,autokeying,allow_linking); }
		void      Record(void) { C4DOS.Bd->Record(this); }

		void			AnimateDocument(BaseThread *bt,Bool doexpressions,Bool doanim);
		void			AnimateObject(BaseList2D *op, const BaseTime &time, LONG flags);

		BaseDocument *Polygonize(Bool keepanimation=FALSE);

		BaseDraw  *GetActiveBaseDraw(void);
		BaseDraw  *GetRenderBaseDraw(void);
		BaseDraw  *GetBaseDraw(LONG num);
		LONG		  GetSplinePlane(void);

		Bool			SoundCommand(LONG command);

		void			SetRewind(LONG flags=0);

		PluginSceneHook *FindSceneHook(LONG id) { return C4DOS.Bd->FindSceneHook(this,id); }

		static BaseDocument *Alloc(void);
		static void Free(BaseDocument *&v);

		LONG						MaterialGroup_GetCount();
		BaseContainer*	MaterialGroup_Add(const BaseContainer &g);
		Bool						MaterialGroup_Remove(LONG id);
		BaseContainer*	MaterialGroup_GetID(LONG id);
		BaseContainer*	MaterialGroup_GetIndex(LONG i);
		Bool						MaterialGroup_IsVisible(BaseMaterial *mat);

		Bool IsCacheBuilt(Bool force=FALSE) { return C4DOS.Bd->IsCacheBuilt(this,force); }

		void ForceCreateBaseDraw(void);

		// layers
		GeListHead *GetLayerObjectRoot(void);
		Bool HandleSelectedTextureFilename(BaseChannel *bc, const Filename &fn, Filename *resfilename, Bool undo, LONG *already_answered);
		Bool ReceiveMaterials  (BaseObject *op, AtomArray *mat, Bool clearfirst);
		Bool ReceiveNewTexture (BaseObject *op, const Filename &filename, Bool sdown, LONG *already_answered);
};

class Hierarchy
{
	private:
		BaseDocument	*doc;
		BaseThread		*bt;
	public:
		virtual void *Alloc(void)=0;
		virtual void Free(void *data)=0;
		virtual void CopyTo(void *src, void *dst)=0;
		virtual Bool Do(void *data, BaseObject *op, const Matrix &mg, Bool controlobject)=0;

		Bool Run(BaseDocument *doc, Bool spheres, Real lod, LONG flags, void *startdata, BaseThread *bt);
};

class PriorityList
{
	private:
		PriorityList();
		~PriorityList();
	public:
		void Add(GeListNode *node, LONG priority, LONG flags) { C4DOS.Bd->PrAdd(this,node,priority,flags); }
};

BaseDocument	*GetActiveDocument(void);
BaseDocument	*GetFirstDocument(void);
Bool					LoadFile(const Filename &name);

void InsertBaseDocument	(BaseDocument *doc);
void SetActiveDocument	(BaseDocument *doc);
void KillDocument				(BaseDocument *&doc);

BaseDocument *LoadDocument(const Filename &name, LONG loadflags, BaseThread *thread);
Bool MergeDocument(BaseDocument *doc, const Filename &name, LONG loadflags, BaseThread *thread);
Bool SaveDocument(BaseDocument *doc, const Filename &name, Bool show_error, LONG format);
BaseDocument*	IsolateObjects(BaseDocument *doc,const AtomArray &t_objects);

LONG RenderDocument(BaseDocument *doc, const BaseContainer &rdata, ProgressHook *pr, void *private_data, BaseBitmap *bmp,
									  LONG renderflags, BaseThread *th, LONG v_left=NOTOK, LONG v_top=NOTOK, LONG v_right=NOTOK, LONG v_bottom=NOTOK);

// editor modes
enum
{
	Mcamera	      = 0,
	Mobject		    = 1,
	Maxis		      = 2,
	Mtexture		  = 3,
	Mtextureaxis  = 4,
	Mpoints		    = 5,
	Medges				= 6,
	Mpolygons     = 7,
	Manimation	  = 9,
	Mkinematic	  = 10,
	Mmodel        = 11,
	Mpaint        = 12,
	Muvpoints     = 13,
	Muvpolygons   = 14,
	Mpolyedgepoint = 15, // ONLY!!! used in ViewportSelect
	Mdrag					= 1000 // for draggin of handles
};

#define RDATA_ANTIALIASING								5002
#define RDATA_TRANSPARENCY								5004
#define RDATA_REFLECTION									5005
#define RDATA_SHADOW						 					5006
#define RDATA_RESOLUTION									5007
#define RDATA_XRES												5008
#define RDATA_YRES												5009
#define RDATA_FILMFORMAT									5010
#define RDATA_XFILM												5011
#define RDATA_YFILM												5012
#define RDATA_XPIX												5013
#define RDATA_YPIX												5014
#define RDATA_FRAMESEQUENCE								5016
#define RDATA_FRAMEFROM										5017 // BaseTime
#define RDATA_FRAMETO											5018 // BaseTime
#define RDATA_FIELD												5019
#define RDATA_FRAMERATE										5020
#define RDATA_ACTIVEOBJECTONLY						5021
#define RDATA_AUTOLIGHT										5022
#define RDATA_LOGFILE											5023
#define RDATA_TEXTUREERROR								5024
#define RDATA_RAYDEPTH										5025
#define RDATA_SHADOWDEPTH									5026
#define RDATA_THRESHOLD										5027
#define RDATA_AASOFTNESS									5028
#define RDATA_FORMAT											5033
#define RDATA_NAMEFORMAT									5035
#define RDATA_ALPHACHANNEL								5036
#define RDATA_STRAIGHTALPHA								5038
#define RDATA_SEPARATEALPHA								5039
#define RDATA_VRGENERATE									5040
#define RDATA_PATH												5041
#define RDATA_HSTEPS											5043
#define RDATA_HSTART											5044
#define RDATA_HEND												5045
#define RDATA_VSTEPS											5046
#define RDATA_VSTART											5047
#define RDATA_VEND												5048
#define RDATA_VOLUMETRICLIGHTING					5052
#define RDATA_LOD													5061
#define RDATA_REFLECTIONDEPTH							5063
#define RDATA_TEXTURES										5064
#define RDATA_VRDEFAULTX									5065
#define RDATA_VRDEFAULTY									5066
#define RDATA_SUPPRESSMP									5067
#define RDATA_ENABLEBLURRY								5069 // BOOL
#define RDATA_AAFILTER										5070 // LONG
#define RDATA_AATHRESHOLD									5071 // REAL
#define RDATA_AAMINLEVEL									5072 // LONG
#define RDATA_AAMAXLEVEL									5073 // LONG
#define RDATA_AAOBJECTPROPERTIES					5074 // BOOL
#define RDATA_TRUECOLORDITHERING					5075 // BOOL
#define RDATA_SAVEIMAGE										5076 // BOOL
#define RDATA_FORMATDEPTH									5077 // LONG
#define	RDATA_AAMIPGLOBAL									5078 // REAL
#define RDATA_SHOWHUD											5079 // BOOL
#define RDATA_CACHESHADOWMAPS							5080 // BOOL
#define RDATA_FRAMESTEP										5081 // LONG

#define RDATA_GI_ENABLEDIFFUSE						5100 // BOOL
#define RDATA_GI_MAXDIFFUSEDEPTH					5102 // LONG
#define RDATA_GI_MONTECARLOSAMPLES				5104 // LONG
#define RDATA_GI_ACCURACY									5105 // REAL
#define RDATA_GI_MAXRESOLUTION						5106 // LONG
#define RDATA_GI_STRENGTH									5108 // REAL
#define RDATA_CS_ENABLECAUSTICS						5111 // BOOL
#define RDATA_CS_ENABLEVOLUMECAUSTICS			5112 // BOOL
#define RDATA_CS_STEPSIZE									5113 // REAL
#define RDATA_CS_SAMPLERADIUS							5114 // REAL
#define RDATA_CS_ACCURACY									5115 // LONG
#define RDATA_CS_STRENGTH									5116 // REAL
#define RDATA_GI_MINRESOLUTION						5117 // LONG
#define RDATA_GI_RECOMPUTE								5119 // LONG
#define RDATA_GI_SAVESOLUTION							5120 // BOOL
#define RDATA_CS_RECOMPUTE								5121 // LONG
#define RDATA_CS_SAVESOLUTION							5122 // BOOL
#define RDATA_GI_PREPASS									5123 // LONG
#define RDATA_GI_CAMERASOLUTION_EX				5124 // BOOL
#define RDATA_CS_CAMERASOLUTION						5125 // BOOL
#define RDATA_GI_STOCHASTICMODE_EX				5126 // BOOL
#define RDATA_GI_STOCHASTICDEPTH					5127 // LONG
#define RDATA_GI_STOCHASTICSAMPLES				5128 // LONG
#define RDATA_GI_STOCHASTICACCURACY				5129 // REAL
#define RDATA_GI_LOCKTOSCREEN							5130 // BOOL
#define RDATA_GI_MODE											5131 // LONG
	#define RDATA_GI_MODE_STANDARD						 0 
	#define RDATA_GI_MODE_STOCHASTIC					 1 
	#define RDATA_GI_MODE_CAMERAANIMATION			 2 
	#define RDATA_GI_MODE_OBJECTANIMATION      3 

#define RDATA_RENDERASEDITOR							5300 // LONG
#define RDATA_RENDERASEDITOR_TRANSP				5302 // BOOL
#define RDATA_RENDERASEDITOR_SHADOWS			5303 // BOOL
#define RDATA_RENDERASEDITOR_POST_EFFECTS	5304 // BOOL

#define RDATA_MULTIPASS_SAVEIMAGE					5200 // BOOL
#define RDATA_MULTIPASS_SAVEONEFILE				5201 // BOOL
#define RDATA_MULTIPASS_ENABLE						5202 // BOOL
#define RDATA_MULTIPASS_SAVEFORMAT				5203 // LONG
#define RDATA_MULTIPASS_SAVEOPTIONS				5204 // BaseContainer
#define RDATA_MULTIPASS_LIGHTS						5205 // LONG
#define RDATA_MULTIPASS_FILENAME					5206 // Filename
#define RDATA_MULTIPASS_SAVEDEPTH					5207 // LONG
#define RDATA_MULTIPASS_LIGHTMODE					5208 // LONG
#define RDATA_MULTIPASS_CHANNELS					5209 // BaseContainer
	#define RDATA_MULTIPASS_ACTIVE						 1 // BOOL
	#define RDATA_MULTIPASS_BLENDDATA					 4 // BaseContainer
	#define RDATA_MULTIPASS_SPECIALGROUP			 5 // LONG
#define RDATA_MULTIPASS_SUFFIX						5210 // LONG
#define RDATA_MULTIPASS_SHADOWCORRECTION	5211 // BOOL

#define RDATA_PROJECTFILE									5212 // BOOL
#define RDATA_PROJECTFILETYPE							5213 // LONG
#define RDATA_PROJECTFILELOCAL						5214 // BOOL
#define RDATA_PROJECTFILEDATA							5215 // BOOL

#define RDATA_POSTEFFECTS_ENABLE					5401 // BOOL
#define RDATA_AMBIENTOCCLUSION						5500 // BaseContainer
#define RDATA_RENDERGAMMA									5501 // REAL
#define RDATA_MOTIONLENGTH								5502 // REAL

#define RDATA_GI_SHOWDIFFUSEILLUMINATION	5602 // BOOL
#define RDATA_GLOBALBRIGHTNESS						5603 // REAL
#define RDATA_ENABLESPD										5604 // BOOL
#define RDATA_AO_APPLYTOSCENE							5605 // BOOL

#define RDATA_SAVECALLBACK_FUNC						5700 // function pointer (SaveCallbackImageFunc)
	#define RDATA_CALLABACK_OPEN						1
	#define RDATA_CALLABACK_WRITE						2
	#define RDATA_CALLABACK_CLOSE						3
#define RDATA_SAVECALLBACK_USERDATA				5701 // pointer

typedef Bool (*SaveCallbackImageFunc)(LONG cmd, void* userdata, BaseDocument* doc, LONG framenum, BaseBitmap* bmp);

Bool InteractiveModeling_Rewind(BaseDocument *doc);
Bool InteractiveModeling_Restart(BaseDocument *doc);

void RunAnimation(BaseDocument *doc, Bool forward, Bool stop);
void SetDocumentTime(BaseDocument *doc, const BaseTime &time);

#endif
