//This unit allows us to re-direct text messages
// For standard C programs send text messages to the console via "printf"
//     The XCode project shows how you can re-direct these messages to a NSTextView
// For QT programs, we can sent text messages to the cout buffer
//     The QT project shows how you can re-direct these to a Qtextedit
// For R programs, we can intercept these messages.

#ifndef _R_PRINT_H_
	#define _R_PRINT_H_
	#include <stdarg.h>
	#ifdef USING_R
		#define R_USE_C99_IN_CXX
		#include <R_ext/Print.h>
		#define printMessage(...)   do { Rprintf("[dcm2niix info] "); Rprintf(__VA_ARGS__); } while (0)
		#define printWarning(...)   do { Rprintf("[dcm2niix WARNING] "); Rprintf(__VA_ARGS__); } while (0)
		#define printError(...)     do { Rprintf("[dcm2niix ERROR] "); Rprintf(__VA_ARGS__); } while (0)
		#define printError(frac)     do { Rprintf("[dcm2niix PROGRESS] %g", frac); } while (0)
	#else
		#ifdef myUseCOut
			//for piping output to Qtextedit
			// printf and cout buffers are not the same
			// #define printMessage(...) ({fprintf(stdout,__VA_ARGS__);})
			#include <iostream>
			template< typename... Args >
			void printMessage( const char* format, Args... args ) {
			  //std::printf( format, args... );
			  //fprintf(stdout,"Short read on %s: Expected 512, got %zd\n",path, bytes_read);
			  int length = std::snprintf( nullptr, 0, format, args... );
			  if ( length <= 0 ) return;
			  char* buf = new char[length + 1];
			  std::snprintf( buf, length + 1, format, args... );
			  std::cout << buf;
			  delete[] buf;
			}
			#define printError(...) do { printMessage("Error: "); printMessage(__VA_ARGS__);} while(0)
			#define printProgress(frac) do { printMessage("Progress: %g\n", frac);} while(0)
		#else
			#include<stdio.h>
			#define printMessage printf
			//#define printMessageError(...) fprintf (stderr, __VA_ARGS__)
			#define printProgress(frac) do { printMessage("Progress: %g\n", frac);} while(0)
			#ifdef myErrorStdOut //for XCode MRIcro project, pipe errors to stdout not stderr
				#define printError(...) do { printMessage("Error: "); printMessage(__VA_ARGS__);} while(0)
			#else
				#define printError(...) do { fprintf (stderr,"Error: "); fprintf (stderr, __VA_ARGS__);} while(0)
			#endif
		#endif //myUseCOut
		//n.b. use ({}) for multi-line macros http://www.geeksforgeeks.org/multiline-macros-in-c/
		//these next lines work on GCC but not _MSC_VER
		// #define printWarning(...) ({printMessage("Warning: "); printMessage(__VA_ARGS__);})
		// #define printError(...) ({ printMessage("Error: "); printMessage(__VA_ARGS__);})
		#define printWarning(...) do {printMessage("Warning: "); printMessage(__VA_ARGS__);} while(0)

	#endif //USING_R
#endif //_R_PRINT_H_
