#ifndef _LIB_CLIPMAP_H_
#define _LIB_CLIPMAP_H_

#include "c4d_library.h"

#ifdef __API_INTERN__
	#include "ge_file.h"
#else
	#include "c4d_file.h"
#endif

#ifndef _INTERNAL_DEF_CLIPMAP_

class BaseBitmap;
class GeClipFnt;

typedef struct _NGV_DRAW_PORT*		NGVH_DP;
typedef struct _NGV_RGN*					NGVH_RGN;

struct GE_POINT2D
{
	LONG x;
	LONG y;
};

struct GE_RECT2D
{
	LONG left;
	LONG top;
	LONG right;
	LONG bottom;
};

#define GE_RGN_ERROR					0
#define GE_RGN_NULL						1
#define GE_RGN_SIMPLE					2
#define GE_RGN_COMPLEX				3

#define GE_CLIP_OUT						0
#define GE_CLIP_ALLIN					1
#define	GE_CLIP_PARTIN				2

#define GE_RGN_POLY_EVENODD		1
#define GE_RGN_POLY_WINDING		2

class GeClipMapRgn
{
	public:
		static GeClipMapRgn* Alloc();
		static void Free          (GeClipMapRgn *&data);
	
	private:	
		GeClipMapRgn();

	public:
		void	SetRectRgn					(LONG left, LONG top, LONG right, LONG bottom);
		void	SetRectRgnInd				(const GE_RECT2D &rect);

		void	SetPolygonRgn				(GE_POINT2D *points, LONG count, LONG mode);
		void	SetPolyPolygonRgn		(GE_POINT2D *points, LONG *count, LONG pcount, LONG mode);

		void	CopyRgn							(const GeClipMapRgn &src);

		LONG	GetRgnBox						(GE_RECT2D *rect);
		Bool	EmptyRgn						();
		Bool	EqualRgn						(const GeClipMapRgn &rgn);
		Bool	PtInRgn							(LONG x, LONG y);
		LONG	RectInRgn						(const GE_RECT2D &rect);

		void	OffsetRgn						(LONG x, LONG y);
		void	UnionRectWithRgn		(const GE_RECT2D &rect);
		void	SubtractRectFromRgn	(const GE_RECT2D &rect);

		void	IntersectRgn				(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void	UnionRgn						(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void	SubtractRgn					(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void	XorRgn							(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
};

#define GE_CPM_COPY			0
#define GE_CPM_BLEND		1
#define GE_CPM_MASK			2
#define GE_CPM_XOR			3

#define GE_ROP_COPY			0
#define GE_ROP_COL			1
#define GE_ROP_FG				2

class GeClipMap
{
	public:
		static GeClipMap* Alloc();
		static void Free       (GeClipMap *&data);

	private:
		GeClipMap();

	public:
		Bool	Init						(LONG w, LONG h, LONG bits = 32);
		Bool	InitWith				(BaseBitmap *bm);
		Bool	InitFrom				(BaseBitmap *bm, LONG alpha_channel);
		Bool	InitFromFile		(const Filename &name, LONG frame = 0, Bool *ismovie = NULL);
		void	Destroy					();

		void	GetDim					(LONG *w, LONG *h);
		BaseBitmap* GetBitmap	();

		void	BeginDraw				();
		void	EndDraw					();

		void	SetOffset				(LONG off_x, LONG off_y);

		void	SetDrawMode			(LONG mode, ULONG par);

		void	SetColor				(LONG r, LONG g, LONG b, LONG a = 255);

		void	SetPixel				(LONG x, LONG y);
		void	Line						(LONG x1, LONG y1, LONG x2, LONG y2);
		void	PolyLine				(LONG cnt, GE_POINT2D *points);
		void	FillPolygon			(LONG cnt, GE_POINT2D *points);
		void	Rect						(LONG x1, LONG y1, LONG x2, LONG y2);
		void	FillRect				(LONG x1, LONG y1, LONG x2, LONG y2);
		void	Arc							(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg);
		void	FillArc					(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg);
		void	Ellipse					(LONG x1, LONG y1, LONG x2, LONG y2);
		void	FillEllipse			(LONG x1, LONG y1, LONG x2, LONG y2);

		void	SetPixelRGBA		(LONG x, LONG y, LONG r, LONG g, LONG b, LONG a = 255);
		void	GetPixelRGBA		(LONG x, LONG y, LONG *r, LONG *g, LONG *b, LONG *a);

		void	SelectFont			(GeClipFnt *fnt);

		void	TextAt					(LONG x, LONG y, const String &txt);
		LONG	TextWidth				(const String &txt);
		LONG	TextHeight			();
		LONG	TextAscent			();
				
		void	Blit						(LONG dx, LONG dy, const GeClipMap &s_dp, LONG sx1, LONG sy1, LONG sx2, LONG sy2, LONG rop);

		void	SetClipRgn			(const GeClipMapRgn &rgn);
		void	CopyClipRgn			(GeClipMapRgn &dst);
		Bool	ClipPoint				(LONG x, LONG y);
		LONG	ClipArea				(LONG x1, LONG y1, LONG x2, LONG y2);
};

#else

#define GeClipMapRgn		GeClipRgn
#define GeClipMap				GeClipPort2D

#endif

// 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 LIB_CLIPMAPRGN 1000493

struct GeClipMapRgnLib : public C4DLibrary
{
		GeClipMapRgn*	(*Alloc)();
		void					(*Free)(GeClipMapRgn *&data);

		void					(GeClipMapRgn::*SetRectRgn)						(LONG left, LONG top, LONG right, LONG bottom);
		void					(GeClipMapRgn::*SetRectRgnInd)				(const GE_RECT2D &rect);
		void					(GeClipMapRgn::*SetPolygonRgn)				(GE_POINT2D *points, LONG count, LONG mode);
		void					(GeClipMapRgn::*SetPolyPolygonRgn)		(GE_POINT2D *points, LONG *count, LONG pcount, LONG mode);
		void					(GeClipMapRgn::*CopyRgn)							(const GeClipMapRgn &src);
		LONG					(GeClipMapRgn::*GetRgnBox)						(GE_RECT2D *rect);
		Bool					(GeClipMapRgn::*EmptyRgn)							();
		Bool					(GeClipMapRgn::*EqualRgn)							(const GeClipMapRgn &rgn);
		Bool					(GeClipMapRgn::*PtInRgn)							(LONG x, LONG y);
		LONG					(GeClipMapRgn::*RectInRgn)						(const GE_RECT2D &rect);
		void					(GeClipMapRgn::*OffsetRgn)						(LONG x, LONG y);
		void					(GeClipMapRgn::*UnionRectWithRgn)			(const GE_RECT2D &rect);
		void					(GeClipMapRgn::*SubtractRectFromRgn)	(const GE_RECT2D &rect);
		void					(GeClipMapRgn::*IntersectRgn)					(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void					(GeClipMapRgn::*UnionRgn)							(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void					(GeClipMapRgn::*SubtractRgn)					(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
		void					(GeClipMapRgn::*XorRgn)								(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2);
};																												
																													
#define LIB_CLIPMAP 		1000494												
																													
struct GeClipMapLib : public C4DLibrary							
{																													
		GeClipMap*	(*Alloc)											();
		void				(*Free)												(GeClipMap *&data);
																													
		Bool				(GeClipMap::*Init)						(LONG w, LONG h, LONG bits);
		Bool				(GeClipMap::*InitWith)				(BaseBitmap *bm);
		Bool				(GeClipMap::*InitFrom)				(BaseBitmap *bm, LONG alpha_channel);
		Bool				(GeClipMap::*InitFromFile)		(const Filename &name, LONG frame, Bool *ismovie);
		void				(GeClipMap::*Destroy)					();
		void				(GeClipMap::*GetDim)					(LONG *w, LONG *h);
		BaseBitmap*	(GeClipMap::*GetBitmap)				();
		void				(GeClipMap::*BeginDraw)				();
		void				(GeClipMap::*EndDraw)					();
		void				(GeClipMap::*SetOffset)				(LONG off_x, LONG off_y);
		void				(GeClipMap::*SetDrawMode)			(LONG mode, ULONG par);
		void				(GeClipMap::*SetColor)				(LONG r, LONG g, LONG b, LONG a);
		void				(GeClipMap::*SetPixel)				(LONG x, LONG y);
		void				(GeClipMap::*CLine)				 		(LONG x1, LONG y1, LONG x2, LONG y2);
		void				(GeClipMap::*PolyLine)        (LONG cnt, GE_POINT2D *points);
		void				(GeClipMap::*FillPolygon)			(LONG cnt, GE_POINT2D *points);
		void				(GeClipMap::*Rect)						(LONG x1, LONG y1, LONG x2, LONG y2);
		void				(GeClipMap::*FillRect)				(LONG x1, LONG y1, LONG x2, LONG y2);
		void				(GeClipMap::*Arc)							(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg);
		void				(GeClipMap::*FillArc)					(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg);
		void				(GeClipMap::*Ellipse)					(LONG x1, LONG y1, LONG x2, LONG y2);
		void				(GeClipMap::*FillEllipse)			(LONG x1, LONG y1, LONG x2, LONG y2);
		void				(GeClipMap::*SetPixelRGBA)		(LONG x, LONG y, LONG r, LONG g, LONG b, LONG a);
		void				(GeClipMap::*GetPixelRGBA)		(LONG x, LONG y, LONG *r, LONG *g, LONG *b, LONG *a);
		void				(GeClipMap::*SelectFont)			(GeClipFnt *fnt);
		void				(GeClipMap::*TextAt)					(LONG x, LONG y, const String &txt);
		LONG				(GeClipMap::*TextWidth)				(const String &txt);
		LONG				(GeClipMap::*TextHeight)			();
		LONG				(GeClipMap::*TextAscent)			();
		void				(GeClipMap::*Blit)						(LONG dx, LONG dy, const GeClipMap &s_dp, LONG sx1, LONG sy1, LONG sx2, LONG sy2, LONG rop);
		void				(GeClipMap::*SetClipRgn)			(const GeClipMapRgn &rgn);
		void				(GeClipMap::*CopyClipRgn)			(GeClipMapRgn &dst);
		Bool				(GeClipMap::*ClipPoint)				(LONG x, LONG y);
		LONG				(GeClipMap::*ClipArea)				(LONG x1, LONG y1, LONG x2, LONG y2);
};

// 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
