#if defined(__DOS__)
#include <i86.h>
#endif
#include <stdarg.h>
#include "system/xstdio.h"
#include "system/xstring.h"
#include "system/xstddef.h"
#include "debug/mono.h"

static char *screen = (char *)0x0b0000;
static int xpos = 0;
static int ypos = 0;
static int minx = 0;
static int maxx = 79;
static int miny = 0;
static int maxy = 24;

#if defined(__DOS__)

static int checked = FALSE;
static int present = FALSE;
static int debug_init()
{
	union REGS r;

	if( checked)
		return( present);

	r.h.ah = 0x1a;
	r.h.al = 0x00;
	int386( 0x10, &r, &r);
	if( r.h.al != 0x1a)
		checked = TRUE, present = FALSE;
	else if( r.h.bh == 0x01)
		checked = TRUE, present = TRUE;

  if( present)
    debug_clrscr();

	return( present);
}

#else

static int debug_init()
{
	return( TRUE);
}

#endif


void debug_clrscr()
{
	int x,y;

	if( !debug_init())
		return;

	for( y=miny; y<=maxy; y++)
		for( x=minx; x<=maxx; x++)
			screen[ y*80*2 + x*2] = ' ', screen[ y*80*2 + x*2 + 1] = 0x07;

	xpos = ypos = 0;
}

void debug_setrange( int _minx, int _maxx, int _miny, int _maxy)
{
	if( (_minx >= 0) && (_minx <= 79))
		minx = _minx;
	if( (_maxx >= 0) && (_maxx <= 79))
		if( _maxx > minx)
			maxx = _maxx;
	if( (_miny >= 0) && (_miny <= 24))
		miny = _miny;
	if( (_maxy >= 0) && (_maxy <= 24))
		if( _maxy > miny)
			maxy = _maxy;
}


void debug_setpos( int x, int y)
{
	if( !debug_init())
		return;

	xpos = x, ypos = y;
}

void debug_print( char *str)
{
	if( !debug_init())
		return;

	while( *str != '\0')
	{
		if( xpos > maxx)
			xpos = minx, ypos++;
    else if( xpos < minx)
      xpos = minx;
    if( ypos > maxy)
		{
      int x,y;
			for( y=miny; y<maxy; y++)
				for( x=minx; x<=maxx; x++)
					screen[ y*80*2 + x*2] = screen[ (y+1)*80*2 + x*2], screen[ y*80*2 + x*2 + 1] = screen[ (y+1)*80*2 + x*2 + 1];

      for( x=minx; x<=maxx; x++)
        screen[ 80*maxy*2 + x*2] = ' ', screen[ 80*maxy*2 + x*2 + 1] = 0x07;

			ypos = maxy;
		}
    else if( ypos < miny)
      ypos = miny;
    if( *str == '\n')
			ypos++, xpos = 0;
		else if( *str == '\r')
			xpos = 0;
    else if( *str == '\b')
      xpos--;
		else
		{
			screen[ (ypos * 80 * 2 + xpos * 2)] = *str;
			xpos++;
		}
		str++;
	}
}

void debug_printf( char *str, ...)
{
	va_list values;
	char newstr[1024];

	if( !debug_init())
		return;

	va_start( values, str );
	vsprintf( newstr, str, values);
	va_end( values);
	debug_print( newstr);
}

void debug_printfxy( int x, int y, char *str, ...)
{
	va_list values;
	char newstr[1024];
	int _xpos,_ypos;
	int _minx,_maxx;
	int _miny,_maxy;

	if( !debug_init())
		return;

	va_start( values, str );
	vsprintf( newstr, str, values);
	va_end( values);


	_xpos = xpos, _ypos = ypos;
	_minx = minx, _maxx = maxx;
	_miny = miny, _maxy = maxy;

	xpos = x, ypos = y;
	minx = 0, maxx = 79;
	miny = 0, maxy = 24;

	debug_print( newstr);

	xpos = _xpos, ypos = _ypos;
	minx = _minx, maxx = _maxx;
	miny = _miny, maxy = _maxy;
}



