#include "operatingsystem.h"
#include "c4d_basebitmap.h"
#include "c4d_memory.h"
#include "c4d_file.h"
#include "c4d_basecontainer.h"
#include "c4d_filterplugin.h"
#include "lib_iconcollection.h"

BaseBitmap *BaseBitmap::Alloc(void)
{
	return C4DOS.Bm->Alloc();
}

void BaseBitmap::Free(BaseBitmap *&bm)
{
	C4DOS.Bm->Free(bm);
	bm=NULL;
}

void MultipassBitmap::Free(MultipassBitmap *&bm)
{
	C4DOS.Bm->Free(bm);
	bm=NULL;
}

LONG BaseBitmap::GetColorMode(void)
{
	return C4DOS.Bm->MPB_GetParameter((MultipassBitmap*)this,MPB_COLORMODE).GetLong();
}

BaseBitmap *BaseBitmap::GetClone(void) 
{
	return C4DOS.Bm->GetClone(this);
}

Bool BaseBitmap::CopyTo(BaseBitmap *dst) 
{
	return C4DOS.Bm->CopyTo(this,dst);
}

BaseBitmap *BaseBitmap::GetClonePart(LONG x, LONG y, LONG w, LONG h) 
{
	return C4DOS.Bm->GetClonePart(this,x,y,w,h);
}

void BaseBitmap::FlushAll(void)
{
	C4DOS.Bm->FlushAll(this);
}
		
LONG BaseBitmap::Init(LONG x, LONG y, LONG depth)
{
	return C4DOS.Bm->Init1(this,x,y,depth);
}

LONG BaseBitmap::Init(const Filename &name, LONG frame, Bool *ismovie)
{
	return C4DOS.Bm->Init2(this,&name,frame,ismovie);
}

LONG BaseBitmap::Save(const Filename &name, LONG format, BaseContainer *data, LONG savebits)
{
	return C4DOS.Bm->Save(this,&name,format,data,savebits);
}

void BaseBitmap::GetLine(LONG y, void *data)
{
	C4DOS.Bm->GetLine(this,y,data);
}

void BaseBitmap::SetLine(LONG y, void *data, LONG depth)
{
	C4DOS.Bm->SetLine(this,y,data,depth);
}

void BaseBitmap::SetCMAP(LONG i, LONG r, LONG g, LONG b)
{
	C4DOS.Bm->SetCMAP(this,i,r,g,b);
}

void BaseBitmap::ScaleBicubic(BaseBitmap *dest, LONG src_xmin, LONG src_ymin, LONG src_xmax, LONG src_ymax, LONG dst_xmin, LONG dst_ymin, LONG dst_xmax, LONG dst_ymax)
{
	C4DOS.Bm->ScaleBicubic(this,dest,src_xmin,src_ymin,src_xmax,src_ymax,dst_xmin,dst_ymin,dst_xmax,dst_ymax);
}

void BaseBitmap::ScaleIt(BaseBitmap *dst, LONG intens, Bool sample, Bool nprop)
{
	C4DOS.Bm->ScaleIt(this,dst,intens,sample,nprop);
}

void BaseBitmap::Clear(LONG r, LONG g, LONG b)
{
	C4DOS.Bm->Clear(this,0,0,GetBw()-1,GetBh()-1,r,g,b);
}

void BaseBitmap::Clear(LONG x1, LONG y1, LONG x2, LONG y2, LONG r, LONG g, LONG b)
{
	C4DOS.Bm->Clear(this,x1,y1,x2,y2,r,g,b);
}

AlphaBitmap *BaseBitmap::AddChannel(Bool internal, Bool straight)
{
	return C4DOS.Bm->AddChannel(this,internal,straight);
}

void BaseBitmap::RemoveChannel(AlphaBitmap *channel)
{
	C4DOS.Bm->RemoveChannel(this,channel);
}

AlphaBitmap *BaseBitmap::GetInternalChannel(void)
{
	return C4DOS.Bm->GetInternalChannel(this);
}

LONG BaseBitmap::GetChannelCount(void)
{
	return C4DOS.Bm->GetChannelCount(this);
}

AlphaBitmap *BaseBitmap::GetChannelNum(LONG num)
{
	return C4DOS.Bm->GetChannelNum(this,num);
}

Bool BaseBitmap::SetData(LONG id,const GeData &data)
{
	return C4DOS.Bm->SetBaseBitmapData(this,id,data);
}

GeData BaseBitmap::GetData(LONG id, const GeData &t_default)
{
	return C4DOS.Bm->GetBaseBitmapData(this,id,t_default);
}

Bool BaseBitmap::IsMultipassBitmap(void)
{
	return C4DOS.Bm->IsMultipassBitmap(this);
}

MovieSaver *MovieSaver::Alloc(void)
{
	return C4DOS.Ms->Alloc();
}

void MovieSaver::Free(MovieSaver *&ms)
{
	C4DOS.Ms->Free(ms);
	ms=NULL;
}

LONG MovieSaver::Open(const Filename &name, BaseBitmap *bm, LONG fps, LONG id, BaseContainer *data, LONG savebits)
{
	return C4DOS.Ms->Open(this,&name,bm,fps,id,data,savebits);
}

LONG MovieSaver::Write(BaseBitmap *bm)
{
	return C4DOS.Ms->Write(this,bm);
}

void MovieSaver::Close(void)
{
	C4DOS.Ms->Close(this);
}

Bool MovieSaver::Choose(LONG id, BaseContainer *bc)
{
	return C4DOS.Ms->Choose(this,id,bc);
}

#define CallBmLoader(fnc) (((BitmapLoaderData*)(((BITMAPLOADERPLUGIN*)GetPluginStructure())->adr))->*((BITMAPLOADERPLUGIN*)GetPluginStructure())->fnc)
#define CallBmSaver(fnc)  (((BitmapSaverData*)(((BITMAPSAVERPLUGIN*)GetPluginStructure())->adr))->*((BITMAPSAVERPLUGIN*)GetPluginStructure())->fnc)

Bool BitmapLoaderPlugin::BmIdentify(const Filename &name, UCHAR *probe, LONG size)
{
	return CallBmLoader(Identify)(name,probe,size);
}

LONG BitmapLoaderPlugin::BmLoad(const Filename &name, BaseBitmap *bm, LONG frame)
{
	return CallBmLoader(Load)(name,bm,frame);
}

LONG BitmapLoaderPlugin::BmGetSaver(void)
{
	if (!((BITMAPLOADERPLUGIN*)GetPluginStructure())->GetSaver) return 0;
	return CallBmLoader(GetSaver)();
}

Bool BitmapLoaderPlugin::BmGetInformation(const Filename &name, LONG *frames, Real *fps)
{
	if (!((BITMAPLOADERPLUGIN*)GetPluginStructure())->GetInformation) return FALSE;
	return CallBmLoader(GetInformation)(name,frames,fps);
}

void BitmapSaverPlugin::BmGetDetails(LONG *alpha, String *suffix)
{
	if (alpha)
	{
		BaseContainer bc;
		*alpha = CallBmSaver(GetMaxAlphas)(&bc);
	}
	
	if (suffix)
	{
		*suffix=String();
		String *str=((BITMAPSAVERPLUGIN*)GetPluginStructure())->suffix;
		if (str) *suffix=*str;
	}
}

Bool BitmapSaverPlugin::BmEdit(BaseContainer *data)
{
	return CallBmSaver(Edit)(data);
}

LONG BitmapSaverPlugin::BmSave(const Filename &name, BaseBitmap *bm, BaseContainer *data, LONG savebits)
{
	return CallBmSaver(Save)(name,bm,data,savebits);
}

LONG BitmapSaverPlugin::BmOpen(PluginMovieData *&md, const Filename &name, BaseBitmap *bm, BaseContainer *data, LONG savebits, LONG fps)
{
	if (!((BITMAPSAVERPLUGIN*)GetPluginStructure())->Open) return IMAGE_NOMEM;
	return CallBmSaver(Open)(md,name,bm,data,savebits,fps);
}

LONG BitmapSaverPlugin::BmWrite(PluginMovieData *md, BaseBitmap *bm)
{
	if (!((BITMAPSAVERPLUGIN*)GetPluginStructure())->Write) return IMAGE_NOMEM;
	return CallBmSaver(Write)(md,bm);
}

void BitmapSaverPlugin::BmClose(PluginMovieData *&md)
{
	if (!((BITMAPSAVERPLUGIN*)GetPluginStructure())->Close) return;
	CallBmSaver(Close)(md);
}

BaseBitmap *InitResourceBitmap(LONG resource_id)
{
	IconData dat;
	if (!GetIcon(resource_id,&dat) || !dat.bmp) return NULL;

	return dat.bmp->GetClonePart(dat.x,dat.y,dat.w,dat.h);
}
