#include <stdarg.h>
#include <stdio.h>			// vsprintf
#include "bgraphic.h"

Graphics::Graphics()
{
	// detect the graphics card installed
	int gdriver = VGA;
	int gmode = VGAHI;

	initgraph (&gdriver, &gmode, ".");
	if (graphresult() != grOk)
	{
		Terminate();
		cerr << "\nUnable to open graphics device";
		exit(1);
	}

	// compute the screen dimensions
	struct viewporttype screen;
	getviewsettings (&screen);
	screen_width  = abs (screen.right - screen.left);
	screen_height = abs (screen.top   - screen.bottom);

	// compute the size of a character
	font_width  = textwidth ("A");
	font_height = textheight("A");

	settextjustify (LEFT_TEXT, TOP_TEXT);
	settextstyle (DEFAULT_FONT, HORIZ_DIR, 1);
}

void Graphics::DrawDot(int color, int x, int y)
{
	putpixel(x, y, color);
}


void Graphics::DrawBox(int color, int style, BOX_TYPE* box)
{
	int polygon [10];
	polygon [0] = box->x1;
	polygon [1] = box->y1;
	polygon [2] = box->x1;
	polygon [3] = box->y2;
	polygon [4] = box->x2;
	polygon [5] = box->y2;
	polygon [6] = box->x2;
	polygon [7] = box->y1;
	polygon [8] = box->x1;
	polygon [9] = box->y1;

	setlinestyle(style, 1, 1);
	setcolor(color);
	drawpoly(5, polygon);
}


void Graphics::DrawCircle(int color,
			  int style,
			  int x, int y, int radius)
{
	setcolor(color);
	setlinestyle(style, 1, 1);
	ellipse(x, y, 0, 360, radius, radius);
}


void Graphics::DrawLine(int color, int style, BOX_TYPE* box)
{
	setcolor(color);
	setlinestyle(style, 1, 1);
	moveto(box->x1, box->y1);
	lineto(box->x2, box->y2);
}



void Graphics::FillBox(int color, BOX_TYPE* box)
{
	setcolor(color);
	setlinestyle(SOLID_LINE, 1, 1);
	setfillstyle(SOLID_FILL, color);

	bar (box->x1, box->y1, box->x2, box->y2);

//	int polygon [8];
//	polygon [0] = box->x1;
//	polygon [1] = box->y1;
//	polygon [2] = box->x1;
//	polygon [3] = box->y2;
//	polygon [4] = box->x2;
//	polygon [5] = box->y2;
//	polygon [6] = box->x2;
//	polygon [7] = box->y1;

//	fillpoly(4, polygon);

}


void Graphics::FillCircle(int color, int x, int y, int radius)
{
	setcolor(color);
	setlinestyle(SOLID_LINE, 1, 1);
	fillellipse(x, y, radius, radius);
}


void Graphics::PutString(int color, int x, int y, char* string)
{
	setcolor(color);
	settextjustify(LEFT_TEXT, TOP_TEXT);
	setfillstyle (EMPTY_FILL, WHITE);
	bar (x, y, x + textwidth(string), y + font_height);
	outtextxy(x, y, string);
}

char buffer[160], buf2[160];
void Graphics::hprintf (int color, int color2, int x, int y, char *fmt, ...)
{
	va_list argptr;

    buffer[0] = '\0';

	va_start(argptr, fmt);
	vsprintf(buffer, fmt, argptr);
	va_end(argptr);

	settextjustify (LEFT_TEXT, TOP_TEXT);
	setfillstyle (EMPTY_FILL, WHITE);
	bar (x, y, x + textwidth(buffer), y + font_height);

	setcolor (color);

	int xpos = x;
	char *p, *q;

	q=buf2;
	for(p=buffer; *p; p++)
	{
		if (*p=='^')
		{
			p++;
			if (*p=='^')
				*q++ = *p;
			else
			{
				*q = 0;
				outtextxy(xpos,y,buf2);
				xpos += textwidth(buf2);

				q=buf2;
				*q++ = *p;
				*q=0;
				setcolor(color2);
				outtextxy(xpos,y,buf2);
				setcolor(color);
				xpos += textwidth(buf2);

				q=buf2;
			}
		}
		else *q++ = *p;
	}
	*q=0;
	if (*buf2) outtextxy(xpos,y,buf2);
}

void Graphics::printf (int color, int x, int y, char *fmt, ...)
{
	va_list argptr;

    buffer[0] = '\0';

	va_start(argptr, fmt);
	vsprintf(buffer, fmt, argptr);
	va_end(argptr);

	settextjustify (LEFT_TEXT, TOP_TEXT);
	setfillstyle (EMPTY_FILL, WHITE);
	bar (x, y, x + textwidth(buffer), y + font_height);

	setcolor (color);
	outtextxy (x, y, buffer);
}

void Graphics::clreol (int x, int y)
{
	setfillstyle(SOLID_FILL, BLACK);
	bar (x,y, screen_width, y + font_height);
}
void Graphics::clrscr ()
{
	cleardevice();
}

void Graphics::SetFont (int font, int size)
{
	settextstyle (font, HORIZ_DIR, size);
	font_width  = textwidth ("A");				// recalculate
	font_height = textheight("A");
}

void Graphics::Terminate()
{
	// exit graphics mode
	closegraph();
}

Graphics::~Graphics()
{
	// close the graphics mode
	Terminate();
}

