#ifndef __C4DGENERAL_H
#define __C4DGENERAL_H

#include "c4d_string.h"
#include "operatingsystem.h"

class Filename;
class GeDialog;
class GeUserArea;

#define UNIT_NONE	0 
#define UNIT_KM		1 
#define UNIT_M		2 
#define UNIT_CM		3 
#define UNIT_MM		4 
#define UNIT_UM		5 
#define UNIT_NM		6 
#define UNIT_MILE	7 
#define UNIT_YARD	8 
#define UNIT_FEET	9 
#define UNIT_INCH	10

#define ANGLE_DEG	0 
#define ANGLE_RAD 1

class Parser
{
	private:
		Parser(void);
	public:
		Bool AddVar(const String &str, Real *value);
		Bool Eval(const String &str, LONG *error, Real *res, LONG unit, LONG angletype, LONG basis);

		static Parser *Alloc(void);
		static void Free(Parser *&pr);
};

struct SerialInfo
{
	String nr,name,organization,street,city,country;
};

void GeGetSerialInfo(LONG type, SerialInfo *si);
LONG GeGetVersionType(void);
void GeShowMouse(LONG v);
void GeGetSysTime(LONG *year, LONG *month, LONG *day, LONG *hour, LONG *minute, LONG *second);
inline LONG GeGetTimer(void) { return C4DOS.Ge->GetTimer(); }
String GeGetLineEnd(void);
LONG GeGetDefaultFPS(void);
LONG GeOutString(const String &str, LONG flags);
LONG GeGetCurrentOS(void);
LONG GeGetByteOrder(void);
void GeGetGray(LONG *r, LONG *g, LONG *b);
Bool GeChooseColor(Vector *col);
Bool GeOpenHTML(const String &webaddress);
Bool GeChooseFont(BaseContainer *bc);
Bool GeRegisterPlugin(LONG type, LONG id, const String &str, void *data, LONG datasize);
void GePrint(const String &str);
Bool GeGetMovieInfo(const Filename &fn, LONG *frames, LONG *fps);
Bool RenameDialog(String *str);
inline LONG GetC4DVersion(void) { return C4DOS.version; }

inline void lSwap (void *adr, LONG cnt=1) { C4DOS.Ge->lSwap(adr,cnt); }
inline void wSwap (void *adr, LONG cnt=1) { C4DOS.Ge->wSwap(adr,cnt); }
inline void lIntel(void *adr, LONG cnt=1) { C4DOS.Ge->lIntel(adr,cnt); }
inline void wIntel(void *adr, LONG cnt=1) { C4DOS.Ge->wIntel(adr,cnt); }
inline void lMotor(void *adr, LONG cnt=1) { C4DOS.Ge->lMotor(adr,cnt); }
inline void wMotor(void *adr, LONG cnt=1) { C4DOS.Ge->wMotor(adr,cnt); }

void SetMousePointer(LONG);
Bool ShowBitmap(const Filename &fn);
Bool ShowBitmap(BaseBitmap *bm);
void StopAllThreads(void);
void StatusClear(void);
void StatusSetSpin(void);
void StatusSetBar(LONG p);
void StatusSetText(const String &str);
void SpecialEventAdd(LONG messageid, ULONG p1=0, ULONG p2=0);
void EventAdd(LONG flags=0);
Bool GeSyncMessage(LONG messageid, LONG destid=0,ULONG p1=0, ULONG p2=0);
Bool DrawViews(LONG flags);
Bool SendModelingCommand(LONG command, ModelingCommandData &data);
Filename GetGlobalTexturePath(LONG i);
void SetGlobalTexturePath(LONG i, const Filename &fn);
Bool GenerateTexturePath(const Filename &docpath, const Filename &srcname, const Filename &suggestedfolder, Filename *dstname);
Bool IsInSearchPath(const Filename &texfilename, const Filename &docpath);
void FlushTexture(const Filename &docpath, const String &name);
void FlushUnusedTextures(void);
BaseContainer GetWorldContainer(void);
BaseContainer *GetWorldContainerInstance(void);
void SetWorldContainer(const BaseContainer &bc);
Vector GetWorldColor(LONG i);
void ErrorStringDialog(LONG type, Real x, Real y, LONG is);
Bool ReadPluginInfo(LONG pluginid, void *buffer, LONG size);
Bool WritePluginInfo(LONG pluginid, void *buffer, LONG size);
BaseContainer *GetWorldPluginData(LONG id);
Bool SetWorldPluginData(LONG id, const BaseContainer &bc, Bool add=TRUE);

class Registry
{
	private:
		Registry();
	public:
		LONG GetMainID(void);
		LONG GetSubID(void);
		void *GetData(void);
};

Bool GeRegistryAdd(LONG sub_id, LONG main_id, void *data);
Bool GeRegistryRemove(LONG sub_id, LONG main_id);
Registry *GeRegistryFind(LONG sub_id, LONG main_id);
Registry *GeRegistryFindLast(LONG main_id);
Registry *GeRegistryFindFirst(LONG main_id);
Registry *GeRegistryFindPrev(Registry *last);
Registry *GeRegistryFindNext(Registry *last);
Bool GeRegistryGetAutoID(LONG *id);
Bool GePluginMessage(LONG id, void *data);

Bool CheckIsRunning(LONG type);

void FindInManager(BaseList2D *bl);
void GeSleep(LONG milliseconds);

void GeBoom(void);

#ifdef _DEBUG
#define GeAssert(expr) { if (!(expr)) { GeDebugOut(#expr); GeBreak(); } }
#else
#define GeAssert(expr) {  }
#endif

void _GeDebugBreak(LONG line, const CHAR *file); // Break
#define GeBreak() _GeDebugBreak(__LINE__, __FILE__)

void GeDebugOut(const CHAR* s,...);		// Warning to Console

class LassoSelection
{
	private:
		LassoSelection();
	public:
		Bool	Start(GeDialog &dlg, LONG mode, LONG start_x=NOTOK, LONG start_y=NOTOK, LONG start_button=NOTOK,LONG sx1=NOTOK, LONG sy1=NOTOK, LONG sx2=NOTOK, LONG sy2=NOTOK);
		Bool  Start(GeUserArea &ua, LONG mode, LONG start_x=NOTOK, LONG start_y=NOTOK, LONG start_button=NOTOK,LONG sx1=NOTOK, LONG sy1=NOTOK, LONG sx2=NOTOK, LONG sy2=NOTOK);

		Bool	CheckSingleClick();
		Bool	Test(LONG x, LONG y);
		Bool	TestPolygon(const Vector &pa, const Vector &pb, const Vector &pc, const Vector &pd); 
		LONG	GetMode();

		static LassoSelection *Alloc();
		static void Free(LassoSelection *&ls);		
};

GeData SendCoreMessage(LONG coreid, const BaseContainer &msg, LONG eventid=0);
#define COREMSG_CINEMA												'CMci'	// request to C4D core

BaseContainer GlGetFeatures();
#define COREMSG_CINEMA_GETOPENGLFEATURES			'gOGL'
	#define OPENGL_SUPPORT_DUALPLANE_ARB									1001
	#define OPENGL_SUPPORT_DUALPLANE_KTX									1002
	#define OPENGL_EXTENSION_STRING												1003
	#define OPENGL_SUPPORT_GL_EXT_SEPARATE_SPECULAR_COLOR	1004

#endif
