
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include "c4d_general.h"
#include "c4d_shader.h"
#include "c4d_file.h"
#include "c4d_basecontainer.h"
#include "c4d_gui.h"

Parser *Parser::Alloc(void)
{
	return C4DOS.Pr->Alloc();
}

void Parser::Free(Parser *&pr)
{
	C4DOS.Pr->Free(pr);
	pr=NULL;
}

Bool Parser::AddVar(const String &str, Real *value)
{
	return C4DOS.Pr->AddVar(this,&str,value);
}

Bool Parser::Eval(const String &str, LONG *error, Real *res, LONG unit, LONG angletype, LONG basis)
{
	return C4DOS.Pr->Eval(this,&str,error,res,unit,angletype,basis);
}

Bool Parser::AddVarLong(const String &str, LONG *value)
{
	return C4DOS.Pr->AddVarLong(this,&str,value);
}

Bool Parser::EvalLong(const String &str, LONG *error, LONG *res, LONG unit, LONG basis)
{
	return C4DOS.Pr->EvalLong(this,&str,error,res,unit,basis);
}

void GeAddBackgroundHandler(BackgroundHandler *handler, void *tdata, LONG typeclass, LONG priority)
{
	C4DOS.Ge->AddBackgroundHandler(handler,tdata,typeclass,priority);
}

Bool GeRemoveBackgroundHandler(void *tdata, LONG typeclass)
{
	return C4DOS.Ge->RemoveBackgroundHandler(tdata,typeclass);
}

void GeStopBackgroundThreads(LONG typeclass, LONG flags)
{
	C4DOS.Ge->StopBackgroundThreads(typeclass,flags);
}

Bool GeCheckBackgroundThreadsRunning(LONG typeclass, Bool all)
{
	return C4DOS.Ge->CheckBackgroundThreadsRunning(typeclass,all);
}

void GeProcessBackgroundThreads(LONG typeclass)
{
	C4DOS.Ge->ProcessBackgroundThreads(typeclass);
}

void GeShowMouse(LONG v)
{
	C4DOS.Ge->ShowMouse(v);
}

void GeGetSysTime(LONG *year, LONG *month, LONG *day, LONG *hour, LONG *minute, LONG *second)
{
	C4DOS.Ge->GetSysTime(year,month,day,hour,minute,second);
}

String GeGetLineEnd(void)
{
	String str;
	C4DOS.Ge->GetLineEnd(&str);
	return str;
}

LONG GeGetDefaultFPS(void)
{
	return C4DOS.Ge->GetDefaultFPS();
}

LONG GeOutString(const String &str, LONG flags)
{
	return C4DOS.Ge->OutString(&str,flags);
}

LONG GeGetCurrentOS(void)
{
	return C4DOS.Ge->GetCurrentOS();
}

LONG GeGetByteOrder(void)
{
	return C4DOS.Ge->GetByteOrder();
}

void GeGetGray(LONG *r, LONG *g, LONG *b)
{
	C4DOS.Ge->GetGray(r,g,b);
}

Bool GeChooseColor(Vector *col)
{
	return C4DOS.Ge->ChooseColor(col);
}

Bool GeOpenHTML(const String &webaddress)
{
	return C4DOS.Ge->OpenHTML(webaddress);
}

Bool GeChooseFont(BaseContainer *bc)
{
	return C4DOS.Ge->ChooseFont(bc);
}

void GeGetSerialInfo(LONG type, SerialInfo *si)
{
	C4DOS.Ge->GetSerialInfo(type,&si->nr,&si->name,&si->organization,&si->street,&si->city,&si->country);
}

LONG GeGetVersionType(void)
{
	return C4DOS.Ge->GetVersionType();
}

LONG GeGetSystemInfo(void)
{
	return C4DOS.Ge->GetSystemInfo();
}

Bool GeRegisterPlugin(LONG type, LONG id, const String &str, void *data, LONG datasize)
{
	return C4DOS.Ge->RegisterPlugin(API_VERSION,type,id,&str,data,datasize);
}

void GePrint(const String &str)
{
	C4DOS.Ge->Print(&str);
}

void GeConsoleOut(const String &str)
{
	String s = String("\x01")+str;
	C4DOS.Ge->Print(&s);
}

void SetMousePointer(LONG l)
{
	C4DOS.Ge->SetMousePointer(l);
}

Bool ShowBitmap(const Filename &fn)
{
	return C4DOS.Ge->ShowBitmap1(&fn);
}

Bool ShowBitmap(BaseBitmap *bm)
{
	return C4DOS.Ge->ShowBitmap2(bm);
}

void StopAllThreads(void)
{
	C4DOS.Ge->StopAllThreads();
}

void StatusClear(void)
{
	C4DOS.Ge->StatusClear();
}

void StatusSetSpin(void)
{
	C4DOS.Ge->StatusSetSpin();
}

void StatusSetBar(LONG p)
{
	C4DOS.Ge->StatusSetBar(p);
}

void StatusSetText(const String &str)
{
	C4DOS.Ge->StatusSetText(&str);
}

void SpecialEventAdd(LONG messageid, VULONG p1, VULONG p2)
{
	C4DOS.Ge->SpecialEventAdd(messageid,p1,p2);
}

void EventAdd(LONG flags)
{
	C4DOS.Ge->EventAdd(flags);
}

Bool GeSyncMessage(LONG messageid, LONG destid, VULONG p1, VULONG p2)
{
	return C4DOS.Ge->SyncMessage(messageid,destid,p1,p2);
}

Bool DrawViews(LONG flags,BaseDraw *bd)
{
	return C4DOS.Ge->DrawViews(flags,bd);
}

Bool SendModelingCommand(LONG command, ModelingCommandData &data)
{
	return C4DOS.Ge->SendModelingCommand(command,data);
}

Filename GetGlobalTexturePath(LONG i)
{
	Filename fn;
	C4DOS.Ge->GetGlobalTexturePath(i,&fn);
	return fn;
}

void SetGlobalTexturePath(LONG i, const Filename &fn)
{
	C4DOS.Ge->SetGlobalTexturePath(i,&fn);
}

Bool IsInSearchPath(const Filename &texfilename, const Filename &docpath)
{
	return C4DOS.Ge->IsInSearchPath(texfilename,docpath);
}

Bool GenerateTexturePath(const Filename &docpath, const Filename &srcname, const Filename &suggestedfolder, Filename *dstname)
{
	return C4DOS.Ge->GenerateTexturePath(docpath,srcname,suggestedfolder,dstname);
}

void FlushTexture(const Filename &docpath, const String &name, const Filename &suggestedfolder)
{
	C4DOS.Ge->FlushTexture(&docpath,&name,suggestedfolder);
}

void FlushUnusedTextures(void)
{
	C4DOS.Ge->FlushUnusedTextures();
}

BaseContainer *GetToolPluginData(BaseDocument *doc, LONG id)
{
	return C4DOS.Ge->GetToolPluginData(doc,id);
}

BaseContainer *GetWorldPluginData(LONG id)
{
	return C4DOS.Ge->GetWorldPluginData(id);
}

Bool SetWorldPluginData(LONG id, const BaseContainer &bc, Bool add)
{
	return C4DOS.Ge->SetWorldPluginData(id,&bc,add);
}

BaseContainer GetWorldContainer(void)
{
	BaseContainer bc;
	C4DOS.Ge->GetWorldContainer(&bc);
	return bc;
}

BaseContainer *GetWorldContainerInstance(void)
{
	return C4DOS.Ge->GetWorldContainerInstance();
}

void SetWorldContainer(const BaseContainer &bc)
{
	C4DOS.Ge->SetWorldContainer(&bc);
}

Vector GetViewColor(LONG colid)
{
	return C4DOS.Ge->GetColor(colid);
}

void SetViewColor(LONG colid, const Vector &col)
{
	C4DOS.Ge->SetViewColor(colid,col);
}

void ErrorStringDialog(LONG type, Real x, Real y, LONG is)
{
	C4DOS.Ge->ErrorStringDialog(type,x,y,is);
}

Bool ReadPluginInfo(LONG pluginid, void *buffer, LONG size)
{
	return C4DOS.Ge->ReadPluginInfo(pluginid,(CHAR*)buffer,size);
}

Bool WritePluginInfo(LONG pluginid, void *buffer, LONG size)
{
	return C4DOS.Ge->WritePluginInfo(pluginid,(CHAR*)buffer,size);
}

Bool GeGetMovieInfoEx(const Filename &fn, LONG *frames, LONG *fps)
{
	return C4DOS.Ge->GetMovieInfoEx(&fn,frames,fps);
}

Bool GeGetMovieInfo(const Filename &fn, LONG *frames, Real *fps)
{
	return C4DOS.Ge->GetMovieInfo(&fn,frames,fps);
}

Bool GeRegistryAdd(LONG sub_id, LONG main_id, void *data)
{
	return C4DOS.Ge->RegistryAdd(sub_id,main_id,data);
}

Bool GeRegistryRemove(LONG sub_id, LONG main_id)
{
	return C4DOS.Ge->RegistryRemove(sub_id,main_id);
}

Registry *GeRegistryFind(LONG sub_id, LONG main_id)
{
	return C4DOS.Ge->RegistryFind(sub_id,main_id);
}

Registry *GeRegistryFindLast(LONG main_id)
{
	return C4DOS.Ge->RegistryFindLast(main_id);
}

Registry *GeRegistryFindFirst(LONG main_id)
{
	return C4DOS.Ge->RegistryFindFirst(main_id);
}

Registry *GeRegistryFindPrev(Registry *last)
{
	return C4DOS.Ge->RegistryFindPrev(last);
}

Registry *GeRegistryFindNext(Registry *last)
{
	return C4DOS.Ge->RegistryFindNext(last);
}

Bool GeRegistryGetAutoID(LONG *id)
{
	return C4DOS.Ge->RegistryGetAutoID(id);
}

LONG Registry::GetMainID(void)
{
	LONG main_id,sub_id;
	void *data;
	if (!C4DOS.Ge->RegistryGetData(this,&main_id,&sub_id,&data)) return 0;
	return main_id;
}

LONG Registry::GetSubID(void)
{
	LONG main_id,sub_id;
	void *data;
	if (!C4DOS.Ge->RegistryGetData(this,&main_id,&sub_id,&data)) return 0;
	return sub_id;
}

void *Registry::GetData(void)
{
	LONG main_id,sub_id;
	void *data;
	if (!C4DOS.Ge->RegistryGetData(this,&main_id,&sub_id,&data)) return NULL;
	return data;
}

Bool RenameDialog(String *str)
{
	return C4DOS.Ge->RenameDialog(str);
}

Bool LassoSelection::Start(GeDialog &dlg, LONG mode, LONG start_x, LONG start_y, LONG start_button, LONG sx1, LONG sy1, LONG sx2, LONG sy2)
{
	return C4DOS.Cd->LSStart(this,(CBaseFrame*)dlg.Get(),mode,start_x,start_y,start_button,sx1,sy1,sx2,sy2);
}

Bool LassoSelection::Start(GeUserArea &ua, LONG mode, LONG start_x, LONG start_y, LONG start_button, LONG sx1, LONG sy1, LONG sx2, LONG sy2)
{
	return C4DOS.Cd->LSStart(this,(CBaseFrame*)ua.Get(),mode,start_x,start_y,start_button,sx1,sy1,sx2,sy2);
}

Bool LassoSelection::Start(EditorWindow *win, LONG mode, LONG start_x, LONG start_y, LONG start_button, LONG sx1, LONG sy1, LONG sx2, LONG sy2)
{
	return C4DOS.Cd->LSStart(this,(CBaseFrame*)win,mode,start_x,start_y,start_button,sx1,sy1,sx2,sy2);
}

Bool LassoSelection::GetRectangle(Real &x1, Real &y1, Real &x2, Real &y2)
{
	return C4DOS.Cd->LSGetRectangle(this,x1,y1,x2,y2);
}

Bool LassoSelection::CheckSingleClick()
{
	return C4DOS.Cd->LSCheckSingleClick(this);
}

Bool LassoSelection::Test(LONG x, LONG y)
{
	return C4DOS.Cd->LSTest(this,x,y);
}

Bool LassoSelection::TestPolygon(const Vector &pa, const Vector &pb, const Vector &pc, const Vector &pd)
{
	return C4DOS.Cd->LSTestPolygon(this,pa,pb,pc,pd);
}

LONG LassoSelection::GetMode()
{
	return C4DOS.Cd->LSGetMode(this);
}

LassoSelection *LassoSelection::Alloc()
{
	return C4DOS.Cd->LSAlloc();
}

void LassoSelection::Free(LassoSelection *&ls)
{
	C4DOS.Cd->LSFree(ls);
	ls=NULL;
}

void FindInManager(BaseList2D *bl)
{
	C4DOS.Ge->FindInManager(bl);
}

void GeSleep(LONG milliseconds)
{
	C4DOS.Ge->GeSleep(milliseconds);
}

Bool GeIsMainThread(void)
{
	return C4DOS.Ge->IsMainThread();
}

Bool GeIsActiveToolEnabled(void)
{
	return C4DOS.Ge->IsActiveToolEnabled();
}

GeListHead *GetScriptHead(LONG type)
{
	return C4DOS.Ge->GetScriptHead(type);
}

Bool GetCommandLineArgs(C4DPL_CommandLineArgs &args)
{
	return C4DOS.Ge->GetCommandLineArgs(args);
}

LONG GetDynamicScriptID(BaseList2D *bl)
{
	return C4DOS.Ge->GetDynamicScriptID(bl);
}

Bool GeGetLanguage(LONG index, String *extension, String *name, Bool *default_language)
{
	return C4DOS.Ge->GetLanguage(index,extension,name,default_language);
}

LONG GeIdentifyFile(const Filename &name, UCHAR *probe, LONG probesize, LONG recognition, BasePlugin **bp)
{
	return C4DOS.Ge->IdentifyFile(name,probe,probesize,recognition,bp);
}

GeData SendCoreMessage(LONG coreid, const BaseContainer &msg, LONG eventid)
{
	return C4DOS.Ge->SendCoreMessage(coreid,msg,eventid);
}

BaseContainer GetMachineFeatures()
{
	GeData dat = SendCoreMessage(COREMSG_CINEMA,BaseContainer(COREMSG_CINEMA_GETMACHINEFEATURES),0);
	if (!dat.GetContainer()) return BaseContainer();
	return *dat.GetContainer();
}

Bool GePluginMessage(LONG id, void *data)
{
	return C4DOS.Ge->PluginMessage(id,data);
}

Bool CheckIsRunning(LONG type)
{
	return C4DOS.Ge->CheckIsRunning(type);
}

String GeGetDefaultFilename(LONG id)
{
	return C4DOS.Ge->GetDefaultFilename(id).GetString();
}

void _GeDebugBreak(LONG line, const CHAR *file)
{
	C4DOS.Ge->GeDebugBreak(line,file);
}

String GetObjectName(LONG type)
{
  return C4DOS.Ge->GetObjectName(type);
}

String GetTagName(LONG type)
{
  return C4DOS.Ge->GetTagName(type);
}

LONG GetObjectType(const String &name)
{
  return C4DOS.Ge->GetObjectType(name);
}

LONG GetTagType(const String &name)
{
  return C4DOS.Ge->GetTagType(name);
}

Bool GeGetMemoryStat(BaseContainer &stat)
{
	return C4DOS.Ge->GeGetMemoryStat(stat);
}


Bool PopupEditText(LONG screenx,LONG screeny, LONG width, LONG height,const String &changeme,LONG flags,PopupEditTextCallback *func, void *userdata)
{
	return C4DOS.Ge->PopupEditText(screenx,screeny,width,height,changeme,flags,func,userdata);
}

void StartEditorRender(Bool active_only, Bool raybrush, LONG x1, LONG y1, LONG x2, LONG y2, BaseThread *bt, BaseDraw *bd, Bool newthread)
{
	C4DOS.Ge->StartEditorRender(active_only,raybrush,x1,y1,x2,y2,bt,bd,newthread);
}

String FormatNumber(const GeData &val, LONG format, LONG fps, Bool bUnit)
{
	return C4DOS.Ge->FormatNumber(val,format,fps,bUnit);
}

GeData StringToNumber(const String &text, LONG format, LONG fps)
{
	return C4DOS.Ge->StringToNumber(text,format,fps);
}

void GeDebugOut(const CHAR* s, ...)
{
	va_list arp;
	va_start(arp, s);

	CHAR t[2048];

	vsprintf(t, s, arp);
	C4DOS.Ge->GeDebugOut("%s",t);

	va_end(arp);

}

String GeGetDegreeChar()
{
	return C4DOS.Ge->GeGetDegreeChar();
}

String GeGetPercentChar()
{
	return C4DOS.Ge->GeGetPercentChar();
}

void CallCommand(LONG id, LONG subid)
{
	if (!GeIsMainThread()) return;
	BaseContainer msg(COREMSG_CINEMA_EXECUTEEDITORCOMMAND);
	msg.SetLong(COREMSG_CINEMA_EXECUTEEDITORCOMMAND, id);
	msg.SetLong(COREMSG_CINEMA_EXECUTESUBID,subid);
	SendCoreMessage(COREMSG_CINEMA, msg, 0);
}

String GetCommandName(LONG id)
{
	if (!GeIsMainThread()) return String();
	BaseContainer msg(COREMSG_CINEMA_GETCOMMANDNAME);
	msg.SetLong(COREMSG_CINEMA_GETCOMMANDNAME, id);
	return SendCoreMessage(COREMSG_CINEMA, msg, 0).GetString();
}

Bool IsCommandEnabled(LONG id)
{
	if (!GeIsMainThread()) return FALSE;
	BaseContainer msg(COREMSG_CINEMA_GETCOMMANDENABLED);
	msg.SetLong(COREMSG_CINEMA_GETCOMMANDENABLED, id);
	return SendCoreMessage(COREMSG_CINEMA, msg, 0).GetLong();
}

Bool IsCommandChecked(LONG id)
{
	if (!GeIsMainThread()) return FALSE;
	BaseContainer msg(COREMSG_CINEMA_GETCOMMANDCHECKED);
	msg.SetLong(COREMSG_CINEMA_GETCOMMANDCHECKED, id);
	return SendCoreMessage(COREMSG_CINEMA, msg, 0).GetLong();
}

IpConnection*	GeIpOpenListener(ULONG ipAddr, LONG port, BaseThread* thread, LONG timeout, Bool dontwait, LONG* ferr)
{
	return C4DOS.Ge->IpOpenListener(ipAddr,port,thread,timeout,dontwait,ferr);
}

IpConnection*	GeIpWaitForIncoming(IpConnection* listener, BaseThread* connection, LONG *ferr)
{
	return C4DOS.Ge->IpWaitForIncoming(listener,connection,ferr);
}

IpConnection* GeIpOpenOutgoing(const CHAR* hostname, BaseThread* thread, LONG initial_timeout, LONG timeout, Bool dontwait, LONG* ferr)
{
	return C4DOS.Ge->IpOpenOutgoing((CHAR*)hostname,thread,initial_timeout,timeout,dontwait,ferr);
}

void GeIpCloseConnection(IpConnection *&ipc)
{
	if (ipc) C4DOS.Ge->IpCloseConnection(ipc);
	ipc=NULL;
}

void GeIpKillConnection(IpConnection *ipc)
{
	C4DOS.Ge->IpKillConnection(ipc);
}

LONG GeIpBytesInInputBuffer(IpConnection* ipc)
{
	return C4DOS.Ge->IpBytesInInputBuffer(ipc);
}

LONG GeIpReadBytes(IpConnection* ipc, void* buf, LONG size)
{
	return C4DOS.Ge->IpReadBytes(ipc,buf,size);
}

LONG GeIpSendBytes(IpConnection* ipc, const void* buf, LONG size)
{
	return C4DOS.Ge->IpSendBytes(ipc,(void*)buf,size);
}

void GeIpGetHostAddr(IpConnection* ipc, CHAR *buf, LONG bufsize)
{
	C4DOS.Ge->IpGetHostAddr(ipc,buf,bufsize);
}

void GeIpGetRemoteAddr(IpConnection* ipc, CHAR *buf, LONG bufsize)
{
	C4DOS.Ge->IpGetRemoteAddr(ipc,buf,bufsize);
}

Bool SendMailAvailable()
{
	return C4DOS.Ge->SendMailAvailable();
}

Bool SendMail(const String &t_subject, const String *t_to, const String *t_cc, const String *t_bcc, Filename *t_attachments,const String &t_body, LONG flags)
{
	return C4DOS.Ge->SendMail(t_subject,t_to,t_cc,t_bcc,t_attachments,t_body,flags);
}

Bool GetSystemEnvironmentVariable(const String &varname, String &result)
{
	return C4DOS.Ge->GetSystemEnvironmentVariable(varname,result);
}

LONG GetShortcutCount()
{
	return C4DOS.Ge->GetShortcutCount();
}

BaseContainer GetShortcut(LONG index)
{
	return C4DOS.Ge->GetShortcut(index);
}

Bool AddShortcut(const BaseContainer &bc)
{
	return C4DOS.Ge->AddShortcut(bc);
}

Bool RemoveShortcut(LONG index)
{
	return C4DOS.Ge->RemoveShortcut(index);
}

Bool LoadShortcutSet(const Filename &fn, Bool add)
{
	return C4DOS.Ge->LoadShortcutSet(fn,add);
}

Bool SaveShortcutSet(const Filename &fn)
{
	return C4DOS.Ge->SaveShortcutSet(fn);
}

LONG FindShortcutsFromID(LONG pluginid, LONG *indexarray, LONG maxarrayelements)
{
	return C4DOS.Ge->FindShortcutsFromID(pluginid,indexarray,maxarrayelements);
}

LONG FindShortcuts(const BaseContainer &scut, LONG *idarray, LONG maxarrayelements)
{
	return C4DOS.Ge->FindShortcuts(scut,idarray,maxarrayelements);
}

void SystemCoffeeGuiPrefsChanged()
{
	#define COREMSG_GUIPREFSCHANGED 200000144
	SendCoreMessage(COREMSG_CINEMA, COREMSG_GUIPREFSCHANGED);
}

void InsertCreateObject(BaseDocument *doc, BaseObject *op, BaseObject *activeobj)
{
  C4DOS.Ge->InsertCreateObject(doc, op, activeobj);
}

void CopyToClipboard(const String &text)
{
	(*C4DOS.Ge->CopyToClipboard)(text);
}
