#include "IStream.h"
#include "Utils.h"
#include "swis.h"

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

static _kernel_oserror err_block =
{0, ""};

const _kernel_oserror* ErrorFromString(unsigned int errnum, const char* pformat, ...)
{
	va_list arg;

	va_start(arg, pformat);
	err_block.errnum = errnum;
	vsnprintf(err_block.errmess, sizeof(err_block.errmess), pformat, arg);
	va_end(arg);

	return &err_block;
}

const _kernel_oserror* RMEnsure(const char* name, int vers, const char* path)
{
	const _kernel_oserror* e;
	int* addr;
	const char* help;
	int count;
	int found_vers = -1;

	// find module in RMA
	e = _swix(OS_Module, _INR(0,1)|_OUT(3), 18, name, &addr);

	if (!e)
	{
		// check version
		help = (char*) addr;
		help += addr[5];
		count = 0;
		while(count < 16)
		{
			count++;
			if (*help == 9)
			{
				count += 7;
				count &= ~7;
			}
			help++;
		}
		if (help[1] == '.')
			found_vers = (help[0] - '0') * 100
			           + (help[2] - '0') * 10
		        	   + (help[3] - '0');
	}

	if (found_vers >= vers)
		return NULL;

	// load module in RMA
	e = _swix(OS_Module, _INR(0,1), 1, path);
	if (e) return e;


	// find module in RMA
	e = _swix(OS_Module, _INR(0,1)|_OUT(3), 18, name, &addr);
	if (e) return e;

	// check version
	found_vers = -1;
	help = (char*) addr;
	help += addr[5];
	count = 0;
	while(count < 16)
	{
		count++;
		if (*help == 9)
		{
			count += 7;
			count &= ~7;
		}
		help++;
	}
	if (help[1] == '.')
		found_vers = (help[0] - '0') * 100
		           + (help[2] - '0') * 10
		           + (help[3] - '0');

	if (found_vers < vers)
		return ErrorFromString(ErrNum_CodecError, "Version %d.%02d of module %s is required.", vers / 100, vers % 100, name);

	return NULL;
}

int strnicmp(const char *a, const char* b, int n)
{
	int c = toupper(*a) - toupper(*b);

	while (*a && *b && (n > 1) && (c == 0))
	{
		a++;
		b++;
		n--;
		c = toupper(*a) - toupper(*b);
	}

	return c;
}

int stricmp(const char *a, const char* b)
{
	int c = toupper(*a) - toupper(*b);

	while (*a && *b && (c == 0))
	{
		a++;
		b++;
		c = toupper(*a) - toupper(*b);
	}

	return c;
}

char* String_StripBlanks(char* string)
{
	int len;
	int i;
	char* ret = string;

	/* strip trailing blanks */
	for (len = strlen(string); (len > 0) && (string[len - 1] <= ' '); len--)
		;

	/* count leading blanks */
	for (i = 0; (i < len) && (string[i] <= ' '); i++) ;

	/* remove leading blanks */
	if (i > 0)
	{
		len = len - i;
		memmove(string, string + i, len);
	}
	string[len] = 0;

	/* replace control characters by blanks */
	for(i = 1; i < len; i++)
	{
		if (iscntrl(string[i]))
		{
			string[i] = ' ';
			break;
	        }
	}

	return ret;
}
