/* Copyright 2009 WiiGator. */
#include "types.h"
#include "usb.h"
#include "debugprintf.h"
#include "exception.h"
#include "strnlen.h"
#include "snprintf.h"
#include "plugin.h"
#include "stream.h"

#ifdef GEKKO_DEBUG

int stream_write_replacement1(
	void *stream,
	const char *text,
	unsigned long size)
{
#ifndef RELOAD_SUPPORT /* not enough memory */
	static char usbgecko_connected;
	static char usbgecko_checked;

	exception_init();

	if (!usbgecko_checked) {
		usbgecko_connected = usb_checkgecko();
		usbgecko_checked = 1;
#if defined(MIOS_PLUGIN) || defined(HIGH_PLUGIN) /* Only MIOS and high version have enough memory. */
		usb_flush();
#endif
	}
	if (usbgecko_connected) {
		usb_sendbuffersafe(text, size);
	}
#else
	jmpNr = 0;

	usb_sendbuffersafe(text, size);
#endif

	/* success: */
	return size;
}

#ifdef RELOAD_SUPPORT
int stream_write_replacement2(
	void *stream,
	const char *text,
	unsigned long size)
{
#ifdef HIGH_PLUGIN /* not enough memory */
	static char usbgecko_connected;
	static char usbgecko_checked;

	exception_init();

	if (!usbgecko_checked) {
		usbgecko_connected = usb_checkgecko();
		usbgecko_checked = 1;
#if defined(MIOS_PLUGIN) || defined(HIGH_PLUGIN) /* Only MIOS and high version have enough memory. */
		usb_flush();
#endif
	}
	if (usbgecko_connected) {
		usb_sendbuffersafe(text, size);
	}
#else
	jmpNr = 1;

	usb_sendbuffersafe(text, size);
#endif

	/* success: */
	return size;
}
#endif

#ifndef MIOS_PLUGIN /* AR is can only use game plugin. */
#ifdef ACTION_REPLAY
unsigned long ar_stream_write_replacement1(
	char **buffer,
	const char *format,
	void *args)
{
	static char usbgecko_connected;
	static char usbgecko_checked;
	const char *dst;
	unsigned long len;

	exception_init();

	dst = *buffer;

	if (!usbgecko_checked) {
		usbgecko_connected = usb_checkgecko();
		usbgecko_checked = 1;
	}
	len = ar_stream_write_orig1(buffer, format, args);
	if (usbgecko_connected) {

		usb_sendbuffersafe(dst, len);
	}
	return len;
}
#endif
#endif

#ifdef MIOS_PLUGIN
/** Replace printf function in MIOS. */
int printf_replacement1(const char *format, ...)
{
	char buf[128];
	int len;
	va_list ap;
	static char usbgecko_connected;
	static char usbgecko_checked;

	exception_init();

	/* XXX: Installation of exception handlers is too early for MIOS. */
	// exception_init();
#ifdef RELOAD_SUPPORT
	jmpNr = 0;
#endif

	//debug_printf("printf_replacement called by 0x%x\n", __builtin_return_address(0));

	va_start(ap, format);
	vsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	len = strnlen(buf, sizeof(buf));
	
	if (!usbgecko_checked) {
		usbgecko_connected = usb_checkgecko();
		usbgecko_checked = 1;
#ifdef MIOS_PLUGIN /* Only enough memory in MIOS plugin. */
		usb_flush();
#endif
	}
	if (usbgecko_connected) {
		usb_sendbuffersafe(buf, len);
	}

	/* success: */
	return len;
}
#endif

#endif

