/////////////////////////////////////////////////////////////
// CINEMA SDK : SHADER																		 //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D																	 //
/////////////////////////////////////////////////////////////
// (c) 1989-2002 MAXON Computer GmbH, all rights reserved	 //
/////////////////////////////////////////////////////////////

// elementary shader datatypes

#ifndef __C4D_SHADER_H
#define __C4D_SHADER_H

#include "ge_lmatrix.h"
#include "ge_matrix.h"
#include "c4d_file.h"
#include "c4d_basetime.h"
#include "ge_prepass.h" // important

#define SHADER_RAYTRACING				0x00000001	// shader needs raytracing
#define SHADER_REFLECTANCE			0x00000002	// shader calculates reflections
#define SHADER_TRANSPARENCY			0x00000004	// shader calculates transparency
#define SHADER_ALPHA						0x00000008	// shader calculates alpha
#define SHADER_CHANGENORMAL			0x00002000	// shader calculates bump mapping
#define SHADER_DISPLACE					0x00004000	// shader calculates displacement mapping
#define SHADER_ENVREQUIRED			0x00100000	// shader needs environment reflection data
#define SHADER_DUDVREQUIRED			0x00200000	// shader needs du/dv bump mapping data
#define SHADER_MIPSAT						0x02000000	// shader requires MIP/SAT data
#define SHADER_VOLUMETRIC				0x20000000	// shader is a volumetric shader
#define SHADER_ASYNC_EX					0x01000000	// shader dialog is asynchronous
#define SHADER_TRANSFORM				0x00000010	// shader needs back-transformed data
#define SHADER_TRANSFORM_N			0x00000020	// shader needs back-transformed normal
#define SHADER_INITCALCULATION	0x80000000  // shader needs initcalculation call

#define CHANNEL_RAYTRACING			0x00000001	// channel needs raytracing
#define CHANNEL_DIRECTBUMP			0x00000002	// channel supports direct bump evaluation
#define CHANNEL_TRANSFORM				0x00000004	// channel needs back-transformed data
#define CHANNEL_TRANSFORM_N			0x00000008	// channel needs back-transformed normal

#define TEX_TILE							0x01				// texture tile enabled
#define TEX_MIRROR						0x02				// texture mirroring enabled
#define TEX_ALPHA							0x04				// texture uses alpha channel (for use within channel shaders)
#define TEX_BUMP							0x08				// bump calculation

#define INIT_SURFACE					0
#define INIT_TRANSPARENCY			1
#define INIT_DISPLACEMENT			3

#define RAY_REFLECTION				(1<<0)			// ray chain contains a reflection ray
#define RAY_TRANSPARENCY			(1<<1)			// ray chain contains a transparency ray (note: refractions are not contained)
#define RAY_REFRACTION				(1<<2)			// ray chain contains a refraction ray
#define RAY_CUSTOM						(1<<3)			// ray chain contains a custom ray

#define RAY_CURR_REFLECTION		(1<<4)			// current ray is a reflection ray
#define RAY_CURR_TRANSPARENCY	(1<<5)			// current ray is a transparency ray
#define RAY_CURR_REFRACTION		(1<<6)			// current ray is a refraction ray
#define RAY_CURR_CUSTOM				(1<<7)			// current ray is a custom ray

#define RAY_VOLUMETRICLIGHT		(1<<8)			// current ray is used to calculate a volumetric light
#define RAY_ALLOWVLMIX				(1<<9)			// custom mixing of visible light sources allowed for this ray; bit must be deleted by shader if used

#define RAY_DIFFUSE_GI				(1<<10)			// current ray calculates diffuse GI
#define RAY_BLURRY						(1<<11)			// ray chain contains a blurry ray

class  CDialog;
class  HyperFile;
class  BaseChannel;
class  BaseDocument;
class  BaseObject;
class  BaseTag;
class  BaseDraw;
class  BaseDrawHelp;
class  BaseThread;
class  Filename;
class  String;
struct RayLight;
struct RayObject;
struct VolumeData;

// channels
#define MAXCHANNELS						13 // channels in C4D material
#define CHANNEL_ANY						-1 // unlabeled plugin channel

#define CHANNEL_COLOR					 0
#define CHANNEL_LUMINANCE			 1
#define CHANNEL_TRANSPARENCY	 2
#define CHANNEL_REFLECTION		 3
#define CHANNEL_ENVIRONMENT		 4
#define CHANNEL_FOG						 5
#define CHANNEL_BUMP					 6
#define CHANNEL_ALPHA					 7
#define CHANNEL_SPECULAR			 8
#define CHANNEL_SPECULARCOLOR	 9
#define CHANNEL_GLOW					10
#define CHANNEL_DISPLACEMENT	11
#define CHANNEL_DIFFUSION			12

#define BASECHANNEL_COLOR_EX					1000  // VECTOR
#define BASECHANNEL_BRIGHTNESS_EX			1001  // REAL
#define BASECHANNEL_MIXMODE_EX   			1006	// LONG
#define BASECHANNEL_MIXSTRENGTH_EX		1007	// REAL

#define BASECHANNEL_TEXTURE      			1002  // STRING
#define BASECHANNEL_BLUR_OFFSET  			1003	// REAL
#define BASECHANNEL_BLUR_STRENGTH			1004	// REAL
#define BASECHANNEL_INTERPOLATION			1005	// LONG
#define BASECHANNEL_TIME_FROM    			1008	// LONG
#define BASECHANNEL_TIME_TO      			1009	// LONG
#define BASECHANNEL_TIME_FPS     			1010	// LONG
#define BASECHANNEL_TIME_MODE    			1011	// LONG
#define BASECHANNEL_TIME_TIMING  			1012	// LONG
#define BASECHANNEL_TIME_START   			1013	// BASETIME
#define BASECHANNEL_TIME_END     			1014	// BASETIME
#define BASECHANNEL_TIME_LOOPS   			1015	// LONG
#define BASECHANNEL_SHADERID					1016  // LONG
#define BASECHANNEL_SUGGESTEDFOLDER		1017	// FILENAME

#define INITRENDERFLAG_TEXTURES				(1<<0)
#define INITRENDERFLAG_PAINTERNOMIP		(1<<1)
#define INITRENDERFLAG_NOMIP					(1<<2)

struct InitRenderStruct
{
	InitRenderStruct(void)
	{
		version=0;
		fps=30;
		docpath=NULL;
		errorlist=NULL;
		matname=NULL;
		vd=NULL;
		doc=NULL;
		thread=NULL;
		flags=INITRENDERFLAG_TEXTURES;
	}

	LONG					version;
	BaseTime			time;
	LONG					fps;
	Filename			*docpath;
	String				*matname;
	void					*errorlist;
	VolumeData		*vd;
	BaseDocument	*doc;
	BaseThread		*thread;
	LONG					flags;
};

// TexData::side
#define SIDE_FRONT_AND_BACK	0
#define SIDE_FRONT					1
#define SIDE_BACK						2

// texture information, read-only
struct TexData
{
	private:
		TexData(void);
	public:
		Matrix  m,im;
		CHAR		texflag;
		CHAR		additive,proj,side;
		LONG    restrict;
		Real		ox,oy,lenx,leny;
		void		*mp;
		LONG		uvwind;

	static TexData *Alloc();
	static void Free(TexData *&td);
	void Init(void);
};

// ray structure
struct Ray
{
	// read and write
	LVector p,v;			// ray position and vector
	Real		ior;			// current index of refraction
	Vector	pp[3];		// 3 additional ray points for MIP-Mapping
	Vector	vv[3];		// 3 additional ray vectors for MIP-Mapping

	// read-only
	Vector	transport; // current intensity (for special shadow calculation)
};

class VPBitmap;

struct Multipass
{
	VPBitmap	**bmp;
	LONG			*ind;
	Real			*result;
	LONG			cnt,cmp;

	Vector		**diffuse;
	LONG			diffuse_cnt;

	Vector		**specular;
	LONG			specular_cnt;

	Vector		**shadow;
	LONG			shadow_cnt;

	RayLight	**light;
	LONG			light_cnt;

	Real			**ochannel;
	LONG			*ochannelid;
	LONG			ochannel_cnt;

	Vector		*vp_ambient,*vp_diffuse,*vp_specular,*vp_shadow,*vp_reflection,*vp_transparency;
	Vector		*vp_radiosity,*vp_caustics,*vp_illumination;
	Vector		*vp_mat_color,*vp_mat_luminance,*vp_mat_transparency,*vp_mat_reflection;
	Vector		*vp_mat_environment,*vp_mat_specularcolor,*vp_atmosphere;
	Real			*vp_depth,*vp_mat_specular,*vp_mat_diffusion,*vp_atmosphere_mul;
};

// main volume shader structure
struct BaseVolumeData
{
	protected:
		BaseVolumeData(void);
	public:
		// read-only
		LONG				version;	// version number of structure
		LONG				fps;			// frames per second
		Vector			ambient;	// global ambient component
		Real				time;			// current time in seconds

		// read and write
		// returnable data: color, transparency, reflection, genlock colour, transparent and reflectant ray, point and normal
		Vector			col;							// set the calculated color here
		Vector			trans;						// set the calculated transparency here
		Vector			refl;							// set the calculated reflection here
		Real				alpha;						// set the calculated alpha here
		Ray					*tray,*rray;			// read and write the transparency/reflection rays; NEVER change the pointers
		Vector			p;								// surface point - may only be modified by Displace
		Vector			bumpn;						// surface phong & bump normal

		// read-only
		Ray					*ray;							// current eye ray
		Vector			orign;						// original surface normal
		Vector			n;								// surface phong normal
		Vector			dispn;						// suggested displacement direction
		Vector			uvw;							// surface uvw coordinates - INVALID for volumetric shaders
		Vector			delta;						// MIP sample radius
		Real				dist;							// distance from eye to surface point
		LONG				lhit;							// surface identity
		TexData			*tex;							// surface texture, NEVER change pointer
		Real				cosc;							// angle beween ray vector and unbumped normal
		Vector			ddu,ddv;					// bump mapping basis vectors
		LONG				raydepth;					// depth of actual ray

		LONG				calc_trans;				// specifies, if transparency shall be rendered
		LONG				calc_refl;				// specifies, if reflections shall be rendered
		LONG				calc_shadow;			// specifies, if shadows shall be rendered
		LONG				calc_illum;				// specifies, if illumination shall be rendered
		LONG				calc_mip;					// specifies, if mip calculations shall be done

		Vector			pp[3];						// MIP corner points in global space
		Vector			nn[3];						// MIP normals of the three other corner points

		LONG				raybits;					// ray information
		RayLight		*xlight;					// lightsource during shadow evaluation
		RayObject		*op;							// object

		// read and write
		LONG				recursion_id;			// plugin ID of data passed through recursion
		void				*recursion_data;	// address of data passed through recursion
		Multipass   *multipass;				// to be filled for multipasses

		// read only
		Vector			back_p;						// set SHADER_TRANSFORM   (CHANNEL_TRANSFORM  ) to access this value
		Vector			back_delta;				// set SHADER_TRANSFORM   (CHANNEL_TRANSFORM  ) to access this value; local space
		Vector			back_orign;				// set SHADER_TRANSFORM_N (CHANNEL_TRANSFORM_N) to access this value
		Vector			back_n;						// set SHADER_TRANSFORM_N (CHANNEL_TRANSFORM_N) to access this value

		Real				global_mip;				// global MIP scale
};

// main channel shader structure
struct ChannelData
{
	ChannelData() { }
	ChannelData(BaseVolumeData *t_vd) : p(t_vd->uvw), n(t_vd->n), d(t_vd->delta) { t=t_vd->time; texflag=0; vd=(VolumeData*)t_vd; off=0.0; scale=t_vd->global_mip; }

	// read-only
	Vector			p;					// texture position in UVW coordinates
	Vector			n;					// surface normal
	Vector			d;					// MIP sample radius in UVW coordinates
	Real				t;					// current time in seconds
	LONG				texflag;		// texture flags
	VolumeData	*vd;				// pointer to volume information, can be NULL
	Real				off,scale;	// blur offset and scale 
};

#define MSG_SETDATA					112000
#define MSG_GETDATA					112001
#define MSG_GETALLSTRINGS		112004
#define MSG_SHADERV5TOV6		112005
#define MSG_SHADERV6TOV7		112006
#define MSG_SHADERREAD			112009
#define MSG_RENAMETEXTURES	112010

struct RenameTextureMessage
{
	Filename oldname;
	Filename newname;
	BaseDocument *doc;
	LONG changecnt;
};

struct VPFragment
{
	LONG				id;
	UCHAR 			subx,suby;
	WORD 				weight;
	RayObject		*op;
	
	Vector			color;

	Real				z;
	Vector			p;
	Vector			n;
	
	VPFragment	*next;
};

struct ShaderReadData
{
	HyperFile *hf;
	LONG			oldid;
	Real			*data;
};

#endif
