#ifdef BACKEND_GRX


#include "stdio.h"

#include "grx.h"
#include "../gui/gui.h"


typedef struct VideoModeS {
	int width;
	int height;
	int depth;
} VideoModeT;


// This is a total hack to prevent GRX from drawing the mouse pointer.
extern struct _GR_mouseInfo _GrMouseInfo;


SurfaceT *imageLoad(char *filename) {
	int32_t   x;
	int32_t   y;
	SurfaceT *image = 0;

	if (!GrQueryPng(filename, &x, &y)) {
		//***TODO*** Die
	}
	image = videoSurfaceCreate(x, y);
	GrLoadContextFromPng(image, filename, 0);

	return image;
}


void platformShutdown(void) {
	GrMouseEraseCursor();
	GrMouseUnInit();

	GrSetMode(GR_default_text);
}


void platformStartup(int16_t width, int16_t height, int16_t depth) {
	// Set up graphics environment.
	if (!GrSetMode(GR_width_height_bpp_graphics, width, height, depth)) {
		//***TODO*** Die
	}
	GrSetRGBcolorMode();
	__guiBaseColors   = GrAllocEgaColors();  // This does not need released.

	// Set up mouse.
	GrMouseInit();
	GrMouseEventEnable(1, 1);
	GrMouseSetCursorMode(GR_M_CUR_NORMAL);
	// This is a total hack to prevent GRX from drawing the mouse pointer.
	_GrMouseInfo.cursor = 0;
}


void videoModesShow(void) {
	VideoModeT         mode[256];
	int32_t            modeCount = 0;
	int32_t            i;
	GrFrameMode        fm;
	const GrVideoMode *mp;

	GrSetDriver(0);
	if (GrCurrentVideoDriver() == 0) {
		printf("No graphics driver found!\n");
		return;
	}

	for (fm=GR_firstGraphicsFrameMode; fm<=GR_lastGraphicsFrameMode; fm++) {
		mp = GrFirstVideoMode(fm);
		while (mp != 0) {
			if (mp->width >= 640 && mp->height >= 480 && mp->bpp >= 8) {
				mode[modeCount].width  = mp->width;
				mode[modeCount].height = mp->height;
				mode[modeCount].depth  = mp->bpp;
				modeCount++;
			}
			mp = GrNextVideoMode(mp);
		}
	}

	GrSetMode(GR_default_text);

	printf("Available graphics modes:\n\n");
	for (i=0; i<modeCount; i++) {
		printf("%4d x %4d %2d bpp\n", mode[i].width, mode[i].height, mode[i].depth);
	}

	GrKeyRead();

	return;
}


void videoSurfaceBlit(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source) {
	GrBitBlt(target, targetX, targetY, source, 0, 0, videoSurfaceWidthGet(source) - 1, videoSurfaceHeightGet(source) - 1, GrWRITE);
}


void videoSurfaceBlitWithTransparency(SurfaceT *target, int16_t targetX, int16_t targetY, SurfaceT *source, ColorT transparent) {
	GrBitBlt(target, targetX, targetY, source, 0, 0, videoSurfaceWidthGet(source) - 1, videoSurfaceHeightGet(source) - 1, GrIMAGE | transparent);
}


int16_t videoSurfaceHeightGet(SurfaceT *surface) {
	return surface->gc_ymax + 1;
}


int16_t videoSurfaceWidthGet(SurfaceT *surface) {
	return surface->gc_xmax + 1;
}


#endif  // BACKEND_GRX
