#include <stdlib.h>     // abs()
#include <vga.h>
#include <vgagl.h>
#include <vgamouse.h>
#include "svgascreen.h"

#define GREY 20
#define RED  4 

SVGAScreen::SVGAScreen()
{
	//line = NULL;
	fontHeight = 8;
	fontWidth = 8;
	error = 0;
	grey  = GREY;
	red   = RED;
	white = vga_white();
	black = 0;
}

SVGAScreen::~SVGAScreen()
{
	close();
}

int SVGAScreen::start()
{
	int x=0, y=0;
	x = mouseX();
	y = mouseY();
	oldx = x;
	oldy = y;
	oldPixel = getPoint( x, y ); // Hintergrund der Maus speichern
	drawPoint( x, y, fgc );			 // Maus zeichnen

	while(1)
	{
	  int event;
		int key;
		event=vga_waitevent( VGA_MOUSEEVENT|VGA_KEYEVENT, NULL, NULL, NULL, NULL );

		x = mouseX();
		y = mouseY();

		drawPoint( oldx, oldy, oldPixel ); // alten Maushintergrund wiederherstellen
		oldPixel = getPoint( x, y );  // neuen Maushintergrund speichern
			
		//if( getKey() == 'q' )
		//	break;

		if( event&VGA_KEYEVENT )
		{
		  key=getKey();
			keyCallback( key );
		}
		if( event&VGA_MOUSEEVENT )
			mouseCallback();

		drawPoint( x, y, fgc );  // Maus zeichnen
		oldx = x;
		oldy = y;

	}
}

int SVGAScreen::open()
{
	int vgamode;

	vga_init();
	vgamode = vga_getdefaultmode();
	if (vgamode == -1)
		vgamode = G320x200x256;

	if (!vga_hasmode(vgamode))
	{
		//printf("Mode not available.\n");
		return -1;
	}
													
	vga_setmousesupport( 1 );
	vga_setmode(vgamode);

	bgc = vga_getpixel( 0, 0 );
	fgc = vga_white();

	//for( int i = 0; i < MAXLINE; i++ )
	//	savedLine[i] = bgc;

	gl_setcontextvga(vgamode);
	gl_enableclipping();
	gl_setwritemode(WRITEMODE_OVERWRITE | FONT_COMPRESSED);
	gl_setfont(8, 8, gl_font8x8);
	gl_setfontcolors(bgc, fgc);

				
						
	// return 0 if ok, -1 if error
	return 0;
}

int SVGAScreen::close()
{
	// return 0 if ok, -1 if error
	return vga_setmode(TEXT);
}

int SVGAScreen::mouseX()
{
	return mouse_getx();
}

int SVGAScreen::mouseX( int x)
{
	int x1 = mouseX();
	int y = mouseY();
	//drawPoint( oldx, oldy, oldPixel ); // alten Maushintergrund wiederherstellen
	//oldPixel = getPoint( x, y );  // Maushintergrund speichern
	mouse_setposition( x, y );
	//drawPoint( x, y, fgc );  // Maus zeichnen
	return x1;
}

int SVGAScreen::mouseY()
{
	return 	mouse_gety();
}

int SVGAScreen::mouseY( int y )
{
	int y1 = mouseY();
	int x = mouseX();
	//drawPoint( oldx, oldy, oldPixel ); // alten Maushintergrund wiederherstellen
	mouse_setposition( x, y );
	//oldPixel = getPoint( x, y );  // Maushintergrund speichern
	//drawPoint( x, y, fgc );  // Maus zeichnen
	return y1;
}

int SVGAScreen::mouseButton()
{
	switch( mouse_getbutton() )
	{
		case MOUSE_LEFTBUTTON:
			return MMOUSE_LEFTBUTTON;
		case MOUSE_MIDDLEBUTTON:
			return MMOUSE_MIDDLEBUTTON;
		case MOUSE_RIGHTBUTTON:
			return MMOUSE_RIGHTBUTTON;
	}
	return MMOUSE_UNKNOWNBUTTON;
}

int SVGAScreen::getChar()
{
	return vga_getch(); // waits for a key
}

int SVGAScreen::getKey()
{
	return vga_getkey(); // waits for a key
}

int SVGAScreen::drawPoint( int x, int y, Color color )
{
	savedPoint = vga_getpixel( x, y ); // Originalpunkt speichern
  vga_setcolor( color );
	return vga_drawpixel( x, y ); // neuen Punkt zeichnen
}

int SVGAScreen::clearPoint( int x, int y )
{
  vga_setcolor( savedPoint );
	return vga_drawpixel( x, y );
}


Color SVGAScreen::getPoint( int x, int y )
{
	return vga_getpixel( x, y );			
}

int SVGAScreen::drawLine( int x1, int y1, int x2, int y2, Color c )
{
	if( c == -1 )
		c = fgc;
	gl_line( x1, y1, x2, y2, c );
	return 0;
}

int SVGAScreen::print( int x, int y, char* text )
{
    gl_write( x, y, text );
		return 0;
}
int SVGAScreen::print( int x, int y, char c )
{
	char s[2];
	s[0] = c;
	s[1] = '\0';
	gl_write( x, y, s );
	return 0;
}

//void  setFgc( Color c ) { fgc = c; };
//Color getFgc( void ) { return fgc; };
//void  setBgc( Color c ) { bgc = c; };
//Color getBgc( void ) { return bgc; };

void SVGAScreen::clearScreen( void )
{
	vga_clear();
}

AreaBuffer* SVGAScreen::getArea( int x, int y, int width, int height )
{
	AreaBuffer* area = new char[width*height*BYTESPERPIXEL+1];
	gl_getbox( x, y, width, height, (void*) area );
	return area;
}

int SVGAScreen::putArea( int x, int y, int width, int height, AreaBuffer* buffer )
{
	gl_putbox( x, y, width, height, buffer );
	return 0;
}

int SVGAScreen::setArea( int x, int y, int width, int height, Color c )
{
  gl_fillbox( x, y, width, height, c );
	return 0;
}

int SVGAScreen::freeArea( AreaBuffer* buffer )
{
	delete [] buffer;
	return 0;
}
