//
// SWIG Typemap library
// Ben van Klinken
// 26 July 2005
//
// COM implementation
//
%{

 #include "stdafx.h"

 template<typename ctype> 
 class COMArrayToCArray{
 public:
  static HRESULT toArray(SAFEARRAY* arr, ctype** _ret){
	  LONG lb=0; ::SafeArrayGetLBound(arr,1,&lb);
	  LONG ub=0; ::SafeArrayGetUBound(arr,1,&ub);
	  ctype* ret = _CL_NEWARRAY(ctype,ub-lb);
	
	  HRESULT result=S_OK;
	  for ( LONG i=lb;i<ub+1;i++ ){
			ctype obj = NULL; SafeArrayGetElement(arr,&i,&obj);
			if ( obj == NULL ) return S_FALSE; //__ReportError( _T("An element is empty") );
		
			ret[i] = obj;
	  }
	
	   *_ret = ret;
	   return result;
	}
 };

 template<typename ctype, typename axtype> 
 class COMObjArrayToCArray{
 public:
  static HRESULT toArray(SAFEARRAY* arr, ctype** _ret){
	  LONG lb=0; ::SafeArrayGetLBound(arr,1,&lb);
	  LONG ub=0; ::SafeArrayGetUBound(arr,1,&ub);
	  ctype* ret = _CL_NEWARRAY(ctype,ub-lb);
	
	  HRESULT result=S_OK;
	  for ( LONG i=lb;i<ub+1;i++ ){
			axtype* obj = NULL; SafeArrayGetElement(arr,&i,&obj);
			if ( obj == NULL ) return S_FALSE; //__ReportError( _T("An element is empty") );
			if ( obj->__object == NULL ) return S_FALSE; //__ReportError( _T("An element is not initialised") );
		
			ret[i] = obj->__object;
	   }
	
	   *_ret = ret;
	   return result;
	}
 };



%}

// Proxy classes (base classes, ie, not derived classes)
%typemap(axbody) SWIGTYPE %{
 static char* getClassName(){ return "$axclassname"; }
 static char* getClassSymName(){ return "$symname"; }
%}

// ------------------------------------------------------------------------
// Pointer and reference handling
//
// These mappings provide support for input/output arguments and common
// uses for C/C++ pointers and C++ references.
// ------------------------------------------------------------------------


// IN & OUTPUT typemaps.
//C types
	%typemap(ctype) 	bool,							const bool		   		  "bool"
	%typemap(ctype) 	wchar_t, 					const wchar_t					"wchar_t"
	%typemap(ctype) 	char, 						const char						"char"
	%typemap(ctype) 	unsigned char,		const unsigned char 	"uint8_t"
	%typemap(ctype) 	long, 						const long  					"int32_t"
	%typemap(ctype) 	long long, 				const long long  		  "int64_t"
	%typemap(ctype) 	float, 						const float			  		"float"
	%typemap(ctype) 	double, 					const double			  	"double"
	%typemap(ctype) 	SWIGTYPE*,				const SWIGTYPE*      	"$*axclassname"
	%typemap(ctype) 	SWIGTYPE&,				const SWIGTYPE&      	"$*axclassname"
	
	%typemap(ctype) 	TCHAR*, 					const TCHAR*				  "TCHAR*"
	%typemap(ctype) 	wchar_t*, 				const wchar_t*			  "wchar_t*"
	%typemap(ctype) 	char*, 						const char*						"char*"
	
	%typemap(ctype) 	char** 			  													"char**"
	%typemap(ctype) 	const char** 			  										"const char**"
	%typemap(ctype) 	wchar_t**																"wchar_t**"
	%typemap(ctype) 	const wchar_t** 		  									"const wchar_t**"
	%typemap(ctype) 	unsigned char*	 												"uint8_t*"
	%typemap(ctype) 	const char** 	  												"const uint8_t*"
	%typemap(ctype) 	long* 																	"int32_t*"
	%typemap(ctype) 	const long* 		  											"const int32_t*"
	%typemap(ctype) 	SWIGTYPE**	 														"$*axclassname*"
	%typemap(ctype) 	const SWIGTYPE**												"const $*axclassname*"
	
	
//COM types
	%typemap(axtype) 	bool,							const bool		   		  "VARIANT_BOOL"
	%typemap(axtype) 	wchar_t, 					const wchar_t					"WCHAR"
	%typemap(axtype) 	char, 						const char						"CHAR"
	%typemap(axtype) 	unsigned char,		const unsigned char 	"BYTE"
	%typemap(axtype) 	long, 						const long  					"LONG"
	%typemap(axtype) 	long long, 				const long long  		  "double"
	%typemap(axtype) 	float, 						const float			  		"float"
	%typemap(axtype) 	double, 					const double			  	"double"
	%typemap(axtype) 	SWIGTYPE*,				const SWIGTYPE*      	"C$*symname"
	%typemap(axtype) 	SWIGTYPE&,				const SWIGTYPE&      	"C$*symname"
	
	%typemap(axtype) 	wchar_t*, 				const wchar_t*			  "BSTR"
	%typemap(axtype) 	char*, 						const char*						"BSTR"
	
	%typemap(axtype) 	TCHAR**,			  	const TCHAR** 			  "SAFEARRAY*"
	%typemap(axtype) 	char**,			  		const char** 			  	"SAFEARRAY*"
	%typemap(axtype) 	wchar_t**,				const wchar_t** 		  "SAFEARRAY*"
	%typemap(axtype) 	unsigned char*, 	const unsigned char*  "SAFEARRAY*"
	%typemap(axtype) 	long*, 						const long* 		  	  "SAFEARRAY*"
	%typemap(axtype) 	SWIGTYPE**, 			const SWIGTYPE**			"SAFEARRAY*"
	
	
//COM header types
	%typemap(axhtype) 	bool,							const bool		   		  "VARIANT_BOOL"
	%typemap(axhtype) 	wchar_t, 					const wchar_t					"WCHAR"
	%typemap(axhtype) 	char, 						const char						"CHAR"
	%typemap(axhtype) 	unsigned char,		const unsigned char 	"BYTE"
	%typemap(axhtype) 	long, 						const long  					"LONG"
	%typemap(axhtype) 	long long, 				const long long  		  "double"
	%typemap(axhtype) 	float, 						const float			  		"float"
	%typemap(axhtype) 	double, 					const double			  	"double"
	%typemap(axhtype) 	SWIGTYPE*,				const SWIGTYPE*      	"I$*symname"
	%typemap(axhtype) 	SWIGTYPE&,				const SWIGTYPE&      	"I$*symname"
	
	%typemap(axhtype) 	wchar_t*, 				const wchar_t*			  "BSTR"
	%typemap(axhtype) 	char*, 						const char*						"BSTR"
	
	%typemap(axhtype) 	TCHAR**,			  	const TCHAR** 			  "SAFEARRAY*"
	%typemap(axhtype) 	char**,			  		const char** 			  	"SAFEARRAY*"
	%typemap(axhtype) 	wchar_t**,				const wchar_t** 		  "SAFEARRAY*"
	%typemap(axhtype) 	unsigned char*, 	const unsigned char*  "SAFEARRAY*"
	%typemap(axhtype) 	long*, 						const long* 		  	  "SAFEARRAY*"
	%typemap(axhtype) 	SWIGTYPE**, 			const SWIGTYPE**			"SAFEARRAY*"
	
//COM idl types
	%typemap(idltype) 	bool,							const bool		   		  "VARIANT_BOOL"
	%typemap(idltype) 	wchar_t, 					const wchar_t					"WCHAR"
	%typemap(idltype) 	char, 						const char						"CHAR"
	%typemap(idltype) 	unsigned char,		const unsigned char 	"BYTE"
	%typemap(idltype) 	long, 						const long  					"LONG"
	%typemap(idltype) 	long long, 				const long long  		  	"double"
	%typemap(idltype) 	float, 						const float			  		"float"
	%typemap(idltype) 	double, 					const double			  	"double"
	%typemap(idltype) 	SWIGTYPE*,				const SWIGTYPE*      	"I$*symname"
	%typemap(idltype) 	SWIGTYPE&,				const SWIGTYPE&      	"I$*symname"
	
	%typemap(idltype) 	wchar_t*, 				const wchar_t*			  "BSTR"
	%typemap(idltype) 	char*, 						const char*						"BSTR"
	
	%typemap(idltype) 	TCHAR**,			  	const TCHAR** 			  "SAFEARRAY(BSTR)"
	%typemap(idltype) 	char**,			  		const char** 			  	"SAFEARRAY(BSTR)"
	%typemap(idltype) 	wchar_t**,				const wchar_t** 		  "SAFEARRAY(BSTR)"
	%typemap(idltype) 	unsigned char*, 	const unsigned char* 	"SAFEARRAY(BYTE)"
	%typemap(idltype) 	long*, 						const long* 		  	  "SAFEARRAY(LONG)"
	%typemap(idltype) 	SWIGTYPE**, 			const SWIGTYPE**			"SAFEARRAY(VARIANT)"


//simple assignment
%define INOUT_TYPEMAP(TYPE)
	%typemap(in) TYPE, const TYPE
	%{ $1 = ($1_ltype)$input; %}
	
	%typemap(out) TYPE, const TYPE
	%{ *$result = $1; %}
%enddef
	INOUT_TYPEMAP( wchar_t )
	INOUT_TYPEMAP( unsigned char )
	INOUT_TYPEMAP( long )
	INOUT_TYPEMAP( float )
	INOUT_TYPEMAP( double )
#undef INOUT_TYPEMAP


//special assignments
%typemap(in) bool, const bool
%{ $1 = ($input==0?false:true); %}
%typemap(out) bool, const bool
%{ *$result = ($1?-1:0); %}


%typemap(in) long long, const long long
%{ $1 = (int64_t)$input; %}
%typemap(out) long long, const long long
%{ *$result = (double)$1; %}


%typemap(in) SWIGTYPE*, const SWIGTYPE*, SWIGTYPE&, const SWIGTYPE&
%{ 
	$1 = ((C$symname*)$input)->__object;
%}
%typemap(out) SWIGTYPE*, const SWIGTYPE*, SWIGTYPE&, const SWIGTYPE&
%{ c$result = new CComObject<C$symname>; 
 c$result->setObject($1); 
 *$result=c$result;
 $1->__cl_addref();
 c$result->AddRef();
%}
%typemap(newfree) SWIGTYPE*, const SWIGTYPE*
%{ c$result->__object->__cl_decref();
%}


%typemap(in) TCHAR*, const TCHAR*, 
             wchar_t*, const wchar_t*
%{ $1 = ($1_ltype)$input; %}
%typemap(out) TCHAR*, const TCHAR*, 
             wchar_t*, const wchar_t*
%{ *$result = ::SysAllocString($1); %} 
%typemap(newfree) TCHAR*, const TCHAR*, 
             			wchar_t*, const wchar_t*
%{ _CLDELETE_CARRAY($1);
%}

%typemap(in) char*, const char*
%{ $1 = STRDUP_TtoA($input); %}
%typemap(freearg) char*, const char*
%{ _CLDELETE_CaARRAY($1); %}
%typemap(out) char*, const char*
%{ 
	TCHAR* tmp_$result = STRDUP_AtoT($1);
  *$result = ::SysAllocString(tmp_$result); 
  _CLDELETE_CaARRAY(tmp_$result);
%}
%typemap(newfree) char*, const char*
%{ _CLDELETE_CaARRAY($1);
%}

%typemap(in) TCHAR**, char**, 
  wchar_t**, unsigned char*, 
  long*
%{  
	 HRESULT $1_cres = COMArrayToCArray<$&1_ltype>::toArray($input, &$1);
	 if ( $1_cres != S_OK ) return $1_cres;
%}
%typemap(in) const TCHAR**,
	const char**, 	const wchar_t**, 	const unsigned char*,
	const long*
%{  
	 HRESULT $1_cres = COMArrayToCArray<const $&1_ltype>::toArray($input, &$1);
	 if ( $1_cres != S_OK ) return $1_cres;
%}
%typemap(in) SWIGTYPE**
%{  
	 HRESULT $1_cres = COMObjArrayToCArray<$&1_ltype, C$symname>::toArray($input, &$1);
	 if ( $1_cres != S_OK ) return $1_cres;
%}
%typemap(in) const SWIGTYPE**
%{  
	 HRESULT $1_cres = COMObjArrayToCArray<const $&1_ltype, C$symname>::toArray($input, &$1);
	 if ( $1_cres != S_OK ) return $1_cres;
%}
%typemap(out) TCHAR**, const TCHAR**,
	char**, const char**,
	wchar_t**, const wchar_t**,
	unsigned char*, const unsigned char*,
	long*, const long*,
	SWIGTYPE**, const SWIGTYPE**
%{  
	
%}

#undef size_t
#define size_t long long


/*todo:

%typemap(arginit) int *data {
   $1 = NULL;
}
%typemap(check) int positive {
   if ($1 <= 0) {
       SWIG_exception(SWIG_ValueError,"Expected positive value.");
   }
}
*/
