
#include "lib_clipmap.h"


#define LIBID			LIB_CLIPMAPRGN
#define LIB				GeClipMapRgnLib

static LIB *library_cache = NULL;


static inline LIB *CheckLibRgn(LONG offset)
{
	return (LIB*)CheckLib(LIBID,offset,(C4DLibrary**)&library_cache);
}


GeClipMapRgn* GeClipMapRgn::Alloc()
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,Alloc)); if (!lib || !lib->Alloc) return NULL;
	return lib->Alloc();
}

void GeClipMapRgn::Free(GeClipMapRgn *&data)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,Free)); if (!lib || !lib->Free) return;
	lib->Free(data);
}

GeClipMapRgn::GeClipMapRgn()
{
}

void GeClipMapRgn::SetRectRgn(LONG left, LONG top, LONG right, LONG bottom)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SetRectRgn)); if (!lib || !lib->SetRectRgn) return;
	(this->*lib->SetRectRgn)(left, top, right, bottom);
}

void GeClipMapRgn::SetRectRgnInd(const GE_RECT2D &rect)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SetRectRgnInd)); if (!lib || !lib->SetRectRgnInd) return;
	(this->*lib->SetRectRgnInd)(rect);
}

void GeClipMapRgn::SetPolygonRgn(GE_POINT2D *points, LONG count, LONG mode)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SetPolygonRgn)); if (!lib || !lib->SetPolygonRgn) return;
	(this->*lib->SetPolygonRgn)(points, count, mode);
}

void GeClipMapRgn::SetPolyPolygonRgn(GE_POINT2D *points, LONG *count, LONG pcount, LONG mode)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SetPolyPolygonRgn)); if (!lib || !lib->SetPolyPolygonRgn) return;
	(this->*lib->SetPolyPolygonRgn)(points, count, pcount, mode);
}

void GeClipMapRgn::CopyRgn(const GeClipMapRgn &src)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,CopyRgn)); if (!lib || !lib->CopyRgn) return;
	(this->*lib->CopyRgn)(src);
}

LONG GeClipMapRgn::GetRgnBox(GE_RECT2D *rect)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,GetRgnBox)); if (!lib || !lib->GetRgnBox) return 0;
	return (this->*lib->GetRgnBox)(rect);
}

Bool GeClipMapRgn::EmptyRgn()
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,EmptyRgn)); if (!lib || !lib->EmptyRgn) return FALSE;
	return (this->*lib->EmptyRgn)();
}

Bool GeClipMapRgn::EqualRgn(const GeClipMapRgn &rgn)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,EqualRgn)); if (!lib || !lib->EqualRgn) return FALSE;
	return (this->*lib->EqualRgn)(rgn);
}

Bool GeClipMapRgn::PtInRgn(LONG x, LONG y)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,PtInRgn)); if (!lib || !lib->PtInRgn) return FALSE;
	return (this->*lib->PtInRgn)(x, y);
}

LONG GeClipMapRgn::RectInRgn(const GE_RECT2D &rect)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,RectInRgn)); if (!lib || !lib->RectInRgn) return 0;
	return (this->*lib->RectInRgn)(rect);
}

void GeClipMapRgn::OffsetRgn(LONG x, LONG y)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,OffsetRgn)); if (!lib || !lib->OffsetRgn) return;
	(this->*lib->OffsetRgn)(x, y);
}

void GeClipMapRgn::UnionRectWithRgn(const GE_RECT2D &rect)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,UnionRectWithRgn)); if (!lib || !lib->UnionRectWithRgn) return;
	(this->*lib->UnionRectWithRgn)(rect);
}

void GeClipMapRgn::SubtractRectFromRgn(const GE_RECT2D &rect)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SubtractRectFromRgn)); if (!lib || !lib->SubtractRectFromRgn) return;
	(this->*lib->SubtractRectFromRgn)(rect);
}

void GeClipMapRgn::IntersectRgn(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,IntersectRgn)); if (!lib || !lib->IntersectRgn) return;
	(this->*lib->IntersectRgn)(rgn1, rgn2);
}

void GeClipMapRgn::UnionRgn(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,UnionRgn)); if (!lib || !lib->UnionRgn) return;
	(this->*lib->UnionRgn)(rgn1, rgn2);
}

void GeClipMapRgn::SubtractRgn(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,SubtractRgn)); if (!lib || !lib->SubtractRgn) return;
	(this->*lib->SubtractRgn)(rgn1, rgn2);
}

void GeClipMapRgn::XorRgn(const GeClipMapRgn &rgn1, const GeClipMapRgn &rgn2)
{
	LIB *lib = CheckLibRgn(LIBOFFSET(LIB,XorRgn)); if (!lib || !lib->XorRgn) return;
	(this->*lib->XorRgn)(rgn1, rgn2);
}

//////////////////////////////////////////////////////


#undef LIBID
#undef LIB

#define LIBID			LIB_CLIPMAP
#define LIB				GeClipMapLib

static LIB *library_engine = NULL;


static inline LIB *CheckLibMap(LONG offset)
{
	return (LIB*)CheckLib(LIBID,offset,(C4DLibrary**)&library_engine);
}


GeClipMap* GeClipMap::Alloc()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Alloc)); if (!lib || !lib->Alloc) return NULL;
	return lib->Alloc();
}

void GeClipMap::Free(GeClipMap *&data)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Free)); if (!lib || !lib->Free) return;
	lib->Free(data);
}

GeClipMap::GeClipMap()
{
}

Bool GeClipMap::Init(LONG w, LONG h, LONG bits)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Init)); if (!lib || !lib->Init) return FALSE;
	return(this->*lib->Init)(w, h, bits);
}

Bool GeClipMap::InitWith(BaseBitmap *bm)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,InitWith)); if (!lib || !lib->InitWith) return FALSE;
	return (this->*lib->InitWith)(bm);
}

Bool GeClipMap::InitFrom(BaseBitmap *bm, AlphaBitmap *alpha_channel)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,InitFrom)); if (!lib || !lib->InitFrom) return FALSE;
	return (this->*lib->InitFrom)(bm, alpha_channel);
}

Bool GeClipMap::InitFromFile(const Filename &name, LONG frame, Bool *ismovie)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,InitFromFile)); if (!lib || !lib->InitFromFile) return FALSE;
	return (this->*lib->InitFromFile)(name, frame, ismovie);
}

void GeClipMap::Destroy()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Destroy)); if (!lib || !lib->Destroy) return;
	(this->*lib->Destroy)();
}

void GeClipMap::GetDim(LONG *w, LONG *h)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,GetDim)); if (!lib || !lib->GetDim) return;
	(this->*lib->GetDim)(w, h);
}

LONG GeClipMap::GetBw()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,GetBw)); if (!lib || !lib->GetBw) return NOTOK;
	return (this->*lib->GetBw)();
}

LONG GeClipMap::GetBh()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,GetBh)); if (!lib || !lib->GetBh) return NOTOK;
	return (this->*lib->GetBh)();
}

BaseBitmap* GeClipMap::GetBitmap()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,GetBitmap)); if (!lib || !lib->GetBitmap) return NULL;
	return (this->*lib->GetBitmap)();
}

void GeClipMap::BeginDraw()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,BeginDraw)); if (!lib || !lib->BeginDraw) return;
	(this->*lib->BeginDraw)();
}

void GeClipMap::EndDraw()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,EndDraw)); if (!lib || !lib->EndDraw) return;
	(this->*lib->EndDraw)();
}

void GeClipMap::SetOffset(LONG off_x, LONG off_y)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetOffset)); if (!lib || !lib->SetOffset) return;
	(this->*lib->SetOffset)(off_x, off_y);
}

void GeClipMap::SetDrawMode(LONG mode, ULONG par)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetDrawMode)); if (!lib || !lib->SetDrawMode) return;
	(this->*lib->SetDrawMode)(mode, par);
}

void GeClipMap::SetColor(LONG r, LONG g, LONG b, LONG a)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetColor)); if (!lib || !lib->SetColor) return;
	(this->*lib->SetColor)(r, g, b, a);
}

void GeClipMap::SetPixel(LONG x, LONG y)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetPixel)); if (!lib || !lib->SetPixel) return;
	(this->*lib->SetPixel)(x, y);
}

void GeClipMap::Line(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,CMLine)); if (!lib || !lib->CMLine) return;
	(this->*lib->CMLine)(x1, y1, x2, y2);
}

void GeClipMap::PolyLine(LONG cnt, GE_POINT2D *points)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,PolyLine)); if (!lib || !lib->PolyLine) return;
	(this->*lib->PolyLine)(cnt, points);
}

void GeClipMap::FillPolygon(LONG cnt, GE_POINT2D *points)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,FillPolygon)); if (!lib || !lib->FillPolygon) return;
	(this->*lib->FillPolygon)(cnt, points);
}

void GeClipMap::Rect(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Rect)); if (!lib || !lib->Rect) return;
	(this->*lib->Rect)(x1, y1, x2, y2);
}

void GeClipMap::FillRect(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,FillRect)); if (!lib || !lib->FillRect) return;
	(this->*lib->FillRect)(x1, y1, x2, y2);
}

void GeClipMap::Arc(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Arc)); if (!lib || !lib->Arc) return;
	(this->*lib->Arc)(x1, y1, x2, y2, seg);
}

void GeClipMap::FillArc(LONG x1, LONG y1, LONG x2, LONG y2, LONG seg)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,FillArc)); if (!lib || !lib->FillArc) return;
	(this->*lib->FillArc)(x1, y1, x2, y2, seg);
}

void GeClipMap::Ellipse(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Ellipse)); if (!lib || !lib->Ellipse) return;
	(this->*lib->Ellipse)(x1, y1, x2, y2);
}

void GeClipMap::FillEllipse(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,FillEllipse)); if (!lib || !lib->FillEllipse) return;
	(this->*lib->FillEllipse)(x1, y1, x2, y2);
}

void GeClipMap::SetPixelRGBA(LONG x, LONG y, LONG r, LONG g, LONG b, LONG a)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetPixelRGBA)); if (!lib || !lib->SetPixelRGBA) return;
	(this->*lib->SetPixelRGBA)(x, y, r, g, b, a);
}

void GeClipMap::GetPixelRGBA(LONG x, LONG y, LONG *r, LONG *g, LONG *b, LONG *a)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,GetPixelRGBA)); if (!lib || !lib->GetPixelRGBA) return;
	(this->*lib->GetPixelRGBA)(x, y, r, g, b, a);
}

void GeClipMap::SelectFont(GeClipFnt *fnt)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SelectFont)); if (!lib || !lib->SelectFont) return;
	(this->*lib->SelectFont)(fnt);
}

void GeClipMap::TextAt(LONG x, LONG y, const String &txt)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,TextAt)); if (!lib || !lib->TextAt) return;
	(this->*lib->TextAt)(x, y, txt);
}

LONG GeClipMap::TextWidth(const String &txt)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,TextWidth)); if (!lib || !lib->TextWidth) return 0;
	return (this->*lib->TextWidth)(txt);
}

LONG GeClipMap::TextHeight()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,TextHeight)); if (!lib || !lib->TextHeight) return 0;
	return (this->*lib->TextHeight)();
}

LONG GeClipMap::TextAscent()
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,TextAscent)); if (!lib || !lib->TextAscent) return 0;
	return (this->*lib->TextAscent)();
}

void GeClipMap::Blit(LONG dx, LONG dy, const GeClipMap &s_dp, LONG sx1, LONG sy1, LONG sx2, LONG sy2, LONG rop)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,Blit)); if (!lib || !lib->Blit) return;
	(this->*lib->Blit)(dx, dy, s_dp, sx1, sy1, sx2, sy2, rop);
}

void GeClipMap::SetClipRgn(const GeClipMapRgn &rgn)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,SetClipRgn)); if (!lib || !lib->SetClipRgn) return;
	(this->*lib->SetClipRgn)(rgn);
}

void GeClipMap::CopyClipRgn(GeClipMapRgn &dst)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,CopyClipRgn)); if (!lib || !lib->CopyClipRgn) return;
	(this->*lib->CopyClipRgn)(dst);
}

Bool GeClipMap::ClipPoint(LONG x, LONG y)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,ClipPoint)); if (!lib || !lib->ClipPoint) return FALSE;
	return (this->*lib->ClipPoint)(x, y);
}

LONG GeClipMap::ClipArea(LONG x1, LONG y1, LONG x2, LONG y2)
{
	LIB *lib = CheckLibMap(LIBOFFSET(LIB,ClipArea)); if (!lib || !lib->ClipArea) return 0;
	return (this->*lib->ClipArea)(x1, y1, x2, y2);
}

