#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(void);
};

class RenderData : public BaseList2D
{
	private:
		RenderData(void);
	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);
};

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

class BaseDocument : public BaseList2D
{
	private:
		BaseDocument(void);
	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);

		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				  GetActiveTags     (AtomArray &selection) const;
		void				  GetActiveMaterials(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 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);

		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	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(void);
		Bool			DoRedo(void);

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

		BaseDocument *Polygonize(void);

		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);
};

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();
	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, Bool show_error);
Bool SaveDocument(BaseDocument *doc, const Filename &name, Bool show_error, LONG format);

LONG RenderDocument(BaseDocument *doc, ProgressHook *pr, void *private_data, BaseBitmap *bmp,
									  const BaseContainer &rdata, LONG renderflags, Bool dummy, Thread *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,
	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
#define RDATA_FRAMETO											5018
#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_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 // 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_POSTEFFECTS_ENABLE					5401 // BOOL

#define SNAP_ENABLE														3002 // BOOL
#define SNAP_POINT														3003 // BOOL
#define SNAP_EDGE															3004 // BOOL
#define SNAP_POLYGON													3005 // BOOL
#define SNAP_GRID															3006 // BOOL
#define SNAP_GRIDLINE													3007 // BOOL
#define SNAP_SPLINE														3008 // BOOL
#define SNAP_SPLINEGRID												3009 // BOOL
#define SNAP_AXIS															3010 // BOOL
#define SNAP_PLANE														3011 // BOOL
#define SNAP_TANGENT													3012 // BOOL
#define SNAP_PERPENDICULAR										3013 // BOOL
#define SNAP_FACECENTER												3014 // BOOL
#define SNAP_MIDPOINT													3015 // BOOL
#define SNAP_SPLINESUB												3016 // LONG
#define SNAP_RADIUS														3017 // LONG
#define SNAP_METHOD														3018 // LONG
#define SNAP_PLANE_SPACING										3019 // REAL
#define SNAP_PLANE_SUB												3020 // LONG
#define SNAP_PLANE_ROUGHSUB										3021 // LONG
#define SNAP_PLANE_ENABLE											3022 // BOOL
#define SNAP_PLANE_DYNAMICGRID								3023 // LONG
#define SNAP_LOCAL_MOVEENABLE									3024 // BOOL
#define SNAP_LOCAL_MOVE												3025 // REAL
#define SNAP_LOCAL_SCALEENABLE								3026 // BOOL
#define SNAP_LOCAL_SCALE											3027 // REAL
#define SNAP_LOCAL_ROTATEENABLE								3028 // BOOL
#define SNAP_LOCAL_ROTATE											3029 // REAL
#define SNAP_LOCAL_TEXTUREENABLE							3030 // BOOL
#define SNAP_LOCAL_TEXTURE										3031 // REAL
#define SNAP_LOCAL_TOOLENABLE									3032 // BOOL
#define SNAP_LOCAL_TOOL												3033 // REAL

#endif
