#include "WimpLib:Throwback.h"

#include <stdio.h>
#include <string.h>
#include "WimpLib:Log.h"
#include "WimpLib:mem.h"
#include "WimpLib:Task.h"
#include "WimpLib:Utils.h"

#define Active  0x1
#define Started 0x2

static const char* File = 0;
static int Status = Active;


void Throwback_Start(const char* file)
{
	mem_free(File);

	File = mem_allocstring(file);
}

static void Throwback_ErrorsIn(void)
{
	if ((Status & Active)
	&&  !(Status & Started))
	{
		Msg msg;

		// ThrowbackStart
		msg.hdr.size = sizeof(msg.hdr);
		msg.hdr.ref = 0;
		msg.hdr.action = 0x42580;
		Task_SendMsg(&msg, HTask_None);

		// ErrorsIn
		msg.hdr.size = sizeof(msg.hdr);
		msg.hdr.ref = 0;
		msg.hdr.action = 0x42582;
		snprintf(msg.data.chars, sizeof(msg.data.chars), "%s", File);
		msg.hdr.size += strlen(msg.data.chars) + 1;
		Task_SendMsg(&msg, HTask_None);

		Status |= Started;
	}
}

void Throwback_Stop(void)
{
	if (Status & Started)
	{
		Msg msg;

		// ThrowbackEnd
		msg.hdr.size = sizeof(msg.hdr);
		msg.hdr.ref = 0;
		msg.hdr.action = 0x42584;
		Task_SendMsg(&msg, HTask_None);
		Status ^= Started;
	}

	mem_free(File);
	File = NULL;
}

void Throwback_Error(int line, int col, const char* pformat, ...)
{
	va_list arg;

	va_start(arg, pformat);
	Throwback_VError(line, col, pformat, arg);
	va_end(arg);
}

void Throwback_VError(int line, int col, const char* pformat, va_list arg)
{
	Throwback_ErrorsIn();

	if ((Status & Active)
	&&  (Status & Started))
	{
		Msg msg;
		char* p = &msg.data.chars[8];

		// ErrorsDetails
		msg.hdr.size = sizeof(msg.hdr) + 8;
		msg.hdr.ref = 0;
		msg.hdr.action = 0x42583;
		msg.data.words[0] = line;
		msg.data.words[1] = 2;
		if (col > 0)
			p += snprintf(p, 10, "Col %3d: ", col);
		vsnprintf(p, 256 - (p - (char*) &msg), pformat, arg);
		msg.hdr.size += strlen(&msg.data.chars[8]) + 1;
		Task_SendMsg(&msg, HTask_None);
	}
	else
	{
		FILE* file = Log_GetFile();

		if (file == NULL) return;

		if (col > 0)
			fprintf(file, "Line %5d, Col %3d: ", line, col);
		else
			fprintf(file, "Line %5d: ", line);
		vfprintf(file, pformat, arg);
		fprintf(file, "\n");

		fclose(file);
	}
}
