#pragma once

#include "stdint.h"
//typedef Int32			LONG;
//typedef UInt32		ULONG;

#if   (API_VERSION < 15000)

//typedef bool					Bool	;	///< boolean type, possible values are only false/true, 8 bit

//typedef CHAR					Char	;
//typedef UCHAR					UChar	;
typedef char					Char	;	///< signed 8 bit character
typedef unsigned char			UChar	;	///< unsigned 8 bit character

//typedef SWORD					Int16	;
//typedef UWORD					UInt16	;
typedef short int				Int16	;
typedef unsigned short int		UInt16	;

typedef LONG					Int32	; //in R14 it is  long
typedef ULONG					UInt32	; //in R14 it is  unsigned long
//typedef signed int			Int32	;
//typedef unsigned int			UInt32	;

//typedef LLONG					Int64	;
//typedef LULONG				UInt64	;
typedef signed long long		Int64	;
typedef unsigned long long		UInt64	;

//typedef SReal					Float32	;
//typedef LReal					Float64	;
typedef float					Float32	;	///< 32 bit floating point value (float)
typedef double					Float64	;	///< 64 bit floating point value (double)

typedef Real					Float	;

#define	SetInt32			SetLong				
#define	SetUInt32			SetULong			
#define	SetInt64			SetLLong			
#define	SetUInt64			SetLULong	
#define	SetFloat			SetReal				

#define	GetInt32			GetLong				
#define	GetUInt32			GetULong			
#define	GetInt64			GetLLong			
#define	GetUInt64			GetLULong			
#define	GetFloat			GetReal				

#define	ReadInt16			ReadWord			
#define	ReadUInt16			ReadUWord			
#define	ReadInt32			ReadLong			
#define	ReadUInt32			ReadULong			
#define	ReadInt64			ReadLLong			
#define	ReadUInt64			ReadLULong			
#define	ReadFloat			ReadReal			
#define	ReadFloat32			ReadSReal			
#define	ReadFloat64			ReadLReal			
#define	ReadVector32		ReadSVector			
#define	ReadVector64		ReadLVector			
#define	ReadMatrix32		ReadSMatrix			
#define	ReadMatrix64		ReadLMatrix			

#define	WriteInt16			WriteWord			
#define	WriteUInt16			WriteUWord			
#define	WriteInt32			WriteLong			
#define	WriteUInt32			WriteULong			
#define	WriteInt64			WriteLLong			
#define	WriteUInt64			WriteLULong			
#define	WriteFloat			WriteReal			
#define	WriteFloat32		WriteSReal			
#define	WriteFloat64		WriteLReal			
#define	WriteVector32		WriteSVector		
#define	WriteVector64		WriteLVector		
#define	WriteMatrix32		WriteSMatrix		
#define	WriteMatrix64		WriteLMatrix	

#endif

#if _MSC_VER < 1700
//#include "std/initializer_list.h"
#endif
//Print to C4D++ console.
/// bool RePrint(const String& str);

// Run Python Script
/// bool PyRun(const String& code);

// Run C++ Code using the same interpreter !
/// bool CppRun(const String& code, bool scoped=true);

// Search in Python SDK Documentation
bool PyHelp(const String& str) {
	return GeOpenHTML("www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/search.html?q="+str);
}

bool CppHelp(const String& str){
	return GeOpenHTML("www.cplusplus.com/search.do?q="+str);
}

inline BaseObject* object(){
	BaseDocument *doc = GetActiveDocument(); 
	if(!doc) throw __LINE__; //return nullptr;
	BaseObject* op = doc->GetActiveObject();
	if(!op) op = doc->GetFirstObject(); 
	if(!op) throw __LINE__; //return nullptr;
	return op;
}

inline BaseTag* tag(){
	BaseDocument *doc = GetActiveDocument();
	if(!doc) throw __LINE__; //return nullptr;
	BaseTag* tag = doc->GetActiveTag();
	if(!tag){
		BaseObject* op = doc->GetFirstObject();
		if(op) tag = op->GetFirstTag(); //???
	}
	if(!tag) throw __LINE__; //return nullptr;
	return tag;
}

inline BaseMaterial* material(){
	BaseDocument *doc = GetActiveDocument(); 
	if(!doc) throw __LINE__; //return nullptr;
	BaseMaterial* mt = doc->GetActiveMaterial();
	if(!mt) mt = doc->GetFirstMaterial(); //???
	if(!mt) throw __LINE__; //return nullptr;
	return mt;
}

inline RenderData* renderdata(){
	BaseDocument *doc = GetActiveDocument();
	if(!doc) throw __LINE__; //return nullptr;
	RenderData *rd = doc->GetActiveRenderData();
	if(!rd) rd = doc->GetFirstRenderData();
	if(!rd) throw __LINE__; //return nullptr;
	return rd;
}

/*inline PrefsDialogObject* prefs(LONG id){
	PrefsDialogObject* pr = (PrefsDialogObject*)FindPlugin(id, PLUGINTYPE_PREFS);
	if(!pr) return nullptr; 
	return pr;
}*/