#include <aalib.h>
#include <stdlib.h>
#include <stdio.h>

aa_context *context = NULL;
unsigned char *buffer1;
unsigned char *buffer;
aa_palette palette;
aa_renderparams *params;
void (*kbd_handler) (int scancode, int press) = NULL;
static int scantokey[128];
unsigned char scanpressed[128]={0,};
int version=0;

struct vga_modeinfo {
	int width;
	int height;
	int bytesperpixel;
	int colors;
	int linewidth;		/* scanline width in bytes */
	int maxlogicalwidth;	/* maximum logical scanline width */
	int startaddressrange;	/* changeable bits set */
	int maxpixels;		/* video memory / bytesperpixel */
	int haveblit;		/* mask of blit functions available */
	int flags;		/* other flags */

	/* Extended fields: */

	int chiptype;		/* Chiptype detected */
	int memory;		/* videomemory in KB */
	int linewidth_unit;	/* Use only a multiple of this as parameter for set_logicalwidth and
				 * set_displaystart */
	char *linear_aperture;	/* points to mmap secondary mem aperture of card (NULL if
				 * unavailable) */
	int aperture_size;	/* size of aperture in KB if size>=videomemory. 0 if unavail */
	void (*set_aperture_page) (int page);
	/* if aperture_size<videomemory select a memory page */
	void *extensions;	/* points to copy of eeprom for mach32 */
	/* depends from actual driver/chiptype.. etc. */
} mode = {

	320, 240, 1, 256, 320, 320, 0, 64000, 0, 0, 0, 64000, 0, NULL, 0, NULL, NULL
};

int vga_init()
{
	return 1;
}

int vga_setmode(int x)
{
	if (x == 0 && context)
		return aa_close(context), free(buffer), 0;
	if (x == 6 && !context)
		if (context = aa_autoinit(&aa_defparams)) {
			if ((buffer = malloc(76800)) && (buffer1 = malloc(65536))) {
				params = aa_getrenderparams();
				params->bright = 100;
				params->contrast = 100;
				memset(aa_image(context), 0, aa_imgwidth(context) * aa_imgheight(context));
				fprintf(stderr,"%d,%d\n",aa_imgwidth(context),aa_imgheight(context));
				if (aa_imgwidth(context)>=320)
					version=10;
				else
					version=20;
				if (aa_imgheight(context)>=240)
					version+=1;
				else if (aa_imgheight(context)>=120)
					version+=2;
				else if (aa_imgheight(context)>=80)
					version+=3;
				else
					version+=4;
				return 0;
			} else
				exit((perror("malloc"), -1));
		}
	return fprintf(stderr, "aavga: vga_setmode(%d) failed!\n", x), 1;
}

void *vga_getgraphmem()
{
	return buffer1;
}

int page=0;

void vga_setpage(int i)
{
	int y, x;
	unsigned char *img = aa_image(context);

//		fprintf(stderr, "vga_setpage(%d) called...%d!=0!!\n", i, i);

	if(i==1)
	{
		memcpy(buffer,buffer1,65536);
	} else {
		memcpy(buffer+65536,buffer1,11264);
	}

	switch(version) {
		case 11:
			for (y = 0; y < 240; y++)
				memcpy(img+y*aa_imgwidth(context),buffer+y*320,320);
			break;
		case 12:
			for (y=0;y<120;y++)
				memcpy(img+y*aa_imgwidth(context),buffer+y*320*2,320);
			break;
		case 13:
			for (y=0;y<80;y++)
				memcpy(img+y*aa_imgwidth(context),buffer+y*320*3,320);
			break;
		case 14:
			for (y=0;y<60;y++)
				memcpy(img+y*aa_imgwidth(context),buffer+y*320*4,320);
			break;
		case 21:
			for (y = 0; y < 240; y++)
				for (x=0;x<160;x++)
					img[y*aa_imgwidth(context)+x]=buffer[y*320+x*2];
			break;
		case 22:
			for (y=0;y<120;y++)
				for (x=0;x<160;x++)
					img[y*aa_imgwidth(context)+x]=buffer[y*2*320+x*2];
			break;
		case 23:
			for (y=0;y<80;y++)
				for (x=0;x<160;x++)
					img[y*aa_imgwidth(context)+x]=buffer[y*3*320+x*2];
			break;
		case 24:
			for (y=0;y<60;y++)
				for (x=0;x<160;x++)
					img[y*aa_imgwidth(context)+x]=buffer[y*4*320+x*2];
			break;
		default:
			fprintf(stderr,"uh, version = %d!\n",version);
	}		
	aa_renderpalette(context, palette, params, 0, 0, aa_scrwidth(context), aa_scrheight(context));
	aa_flush(context);
}

int vga_lastmodenumber()
{
	return 6;
}

int vga_hasmode(int x)
{
	return (x == 6);
}

struct vga_modeinfo *vga_getmodeinfo(int x)
{
	return &mode;
}

int vga_getmodenumber(char *s)
{
	return 6;
}

int vga_getcolors()
{
	return 256;
}

int vga_setpalvec(int a, int b, int *n)
{
	int i;

	for (i = a; i < b; i++)
		aa_setpalette(palette, i, n[i * 3], n[i * 3 + 1], n[i * 3 + 2]);
}

void vga_waitretrace()
{
}

int vga_oktowrite()
{
	return 1;
}

int vga_getmousetype()
{
	return 0;
}

void vga_runinbackground(int x)
{
}

int mouse_init()
{
	return 1;
}

void mouse_seteventhandler(void *h)
{
}

void mouse_close()
{
}

int mouse_update()
{
	return 0;
}


