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

#ifndef __C4DBASECHANNEL_H
#define __C4DBASECHANNEL_H

#include "ge_math.h"
#include "ge_vector.h"
#include "c4d_basebitmap.h"
#include "c4d_gui.h"
#include "c4d_baselist.h"

class Filename;
class BaseBitmap;
class BaseContainer;
class TextureGroup;
class GeDialog;
class PluginShader;
struct VolumeData;

#define PsBaCall(fnc) (this->*C4DOS.Ba->fnc)

class PluginShader : public BaseList2D 
{
	private:
		PluginShader();
		~PluginShader();
	public:
		LONG InitRender(InitRenderStruct *is) { return PsBaCall(InitRender)(is); }
		void FreeRender(void) { PsBaCall(FreeRender)(); }
		Vector Sample(ChannelData *cd) { return PsBaCall(Sample)(cd); }
		Vector SampleBump(ChannelData *cd, LONG bumpflags) { return PsBaCall(SampleBump)(cd,bumpflags); }
		BaseBitmap *GetBitmap(void) { return PsBaCall(GetBitmap)(); }
		LONG GetRenderInfo(void) { return PsBaCall(GetRenderInfo)(); }
		Bool Compare(PluginShader* dst) { return PsBaCall(PsCompare)(dst); }
		LONG GlMessage(LONG type, void *data) { return PsBaCall(GlMessage)(type, data); }

		PluginShader *GetNext(void) { return (PluginShader*)AtCall(GetNext)(); }
		PluginShader *GetPred(void) { return (PluginShader*)AtCall(GetPred)(); }
		PluginShader *GetUp  (void) { return (PluginShader*)AtCall(GetUp)(); }
		PluginShader *GetDown(void) { return (PluginShader*)AtCall(GetDown)(); }
		PluginShader *GetDownLast(void) { return (PluginShader*)AtCall(GetDownLast)(); }

		static PluginShader *Alloc(LONG type);
		static void Free(PluginShader *&ps);
};

class BaseChannel : public C4DAtom
{
	private:
		BaseChannel();
		~BaseChannel();
	public:
		Bool Compare(BaseChannel *dst);
		
		LONG InitTexture(InitRenderStruct *is); 
		void FreeTexture(void);
	
		BaseContainer		GetData(void);
		void						SetData(const BaseContainer &ct);

		LONG						GetShaderID(void);
		PluginShader*		GetShader(void);
		BaseBitmap*			GetBitmap(void) { return C4DOS.Ba->BCGetBitmap(this); }

		Vector Sample(VolumeData *vd, Vector *p, Vector *delta, Vector *n, Real t, LONG tflag, Real off, Real scale) { return C4DOS.Ba->SampleEx((BaseChannel*)this,vd,p,delta,n,t,tflag,off,scale); }

		Bool Attach(GeListNode *element);

		static BaseChannel *Alloc(void);
		static void Free(BaseChannel *&bc);
};

class TexturePreview : public GeUserArea
{
	private:
		TextureGroup *texgroup;
	
	public:
		TexturePreview(void);
		Bool InitPreview(TextureGroup *t_texgroup);

		// for overriding (for special message handling)
		virtual LONG Message(const BaseContainer &msg,BaseContainer &result);
		virtual Bool GetMinSize(LONG &w,LONG &h);
		virtual void DrawMsg(LONG x1,LONG y1,LONG x2,LONG y2,const BaseContainer &msg);
};

class TextureGroup
{
	private:
		_TextureGroup *tg;
		BaseChannel		*bc;
		CDialog				*cd;
		TexturePreview texprev;

	public:
		TextureGroup(void);
		~TextureGroup(void);

		Bool Init(BaseChannel *bc, GeDialog *cd, LONG idimage, LONG idname, LONG idbluroff, LONG idblurstr, LONG idint, LONG idinfo, LONG idpreview, LONG idedit, LONG idpopup);
		void Update(void);
		Bool Message(const BaseContainer &msg,Bool preview);
};

inline Bool HandleShaderPopupI   (BaseList2D *parent, PluginShader *&current, LONG value, VLONG param) { return C4DOS.Ba->HandleShaderPopupI(parent,current,value,param); }
inline Bool BuildShaderPopupMenuI(BaseContainer *menu, BaseList2D *parent, PluginShader *current, VLONG param) { return C4DOS.Ba->BuildShaderPopupMenuI(menu,parent,current,param); }

inline Bool HandleShaderPopup    (const BaseContainer &bc, const DescID &descid, LONG value, VLONG param) { return C4DOS.Ba->HandleShaderPopup(bc,descid,value,param); }
inline Bool BuildShaderPopupMenu (BaseContainer *menu, const BaseContainer &bc, const DescID &descid, VLONG param) { return C4DOS.Ba->BuildShaderPopupMenu(menu,bc,descid,param); }

inline String GetChannelName(LONG channelid) { return C4DOS.Ba->GetChannelName(channelid); }

#endif
