#include "system/xstring.h"
#include "system/xmath.h"
#include "system/xstdio.h"
#include "drivers/drv16.h"
#include "formats/vio.h"
#include "formats/tga.h"
#include "formats/gif.h"
#include "misc/col.h"

#if defined(__DOS__)
#define DRIVER vesaDRV
#elif defined(__NT__)
#define DRIVER dx16DRV
#endif

extern DRV DRIVER;

RGB palette[ 256];
void blitta (XYZ p,BUFF *buff, RGBA *image, int width, int height)
{
	int sxs,ixs,xlen;
	int sys,iys,ylen,ypos,ypic;
	int i,j;

	if ( p.x >= buff->minx )
	{
		sxs = (int)p.x;
		ixs = 0;
		if ( (p.x + width) <= buff->maxx)
			xlen = width;
		else
			xlen = buff->maxx - (int)p.x;
	}
	else
	{
		sxs = 0;
		ixs = buff->minx - (int)p.x;
		if ( (p.x + width) <= buff->maxx)
			xlen = ((int)p.x + width) - buff->minx;
		else
			xlen = buff->maxx - buff->minx;
	}

	// Check Y

	if ( p.y >= buff->miny )
	{
		sys = (int)p.y;
		iys = 0;
		if ( (p.y + height) <= buff->maxy)
			ylen = height;
		else
			ylen = buff->maxy - (int)p.y;
	}
	else
	{
		sys = 0;
		iys = buff->miny - (int)p.y;
		if ( (p.y + height) <= buff->maxy)
			ylen = ((int)p.y + height) - buff->miny;
		else
			ylen = buff->maxy - buff->miny;
	}

	ypic= iys * width;
	ypos= sys * buff->width;
	for ( j=0; j<ylen; j++) // ZB
	{
		for (i=0;i< xlen; i++)	buff->image[sxs+i+ypos] = image[ixs+i+ypic];
		ypos+=buff->width;
		ypic+=width;
	}
}

int main( int argc, char *argv[])
{
  DRV *drv = &DRIVER;
	BUFF *buff;
  VIO *image;
  XYZ p = {0,0,0,0,0,0};
  int i,x = 0,y = 0,l = 32;
	int mode = 0;
	int quit = FALSE;

	if( argc != 2)
	{
		printf("Usage: showvio <image>\n");
		exit( 0);
	}

  if( !drv->setup())
	{
		printf("Driver setup failed(%s)\n", drv->geterror());
		exit( 1);
	}
	else
	{
		printf("Available modes:\n");
		for( i=0; i<drv->modes; i++)
			printf("%dx%d\n", drv->modelist[i].width, drv->modelist[i].height);
	}
	if( (image = vio_load( argv[1])) == NULL)
  	if( (image = tga_load( argv[1])) == NULL)
      if( (image = gif_load( argv[1])) == NULL)
      {
        printf("Error while loading %s.", argv[1]);
       exit(1);
     }

  printf("Loaded %dx%d image.\n", image->width, image->height);

  if ( image->flags & VIOFLAG_8BIT)
    printf("File contains a 256 color image.\n");
	if ( image->flags & VIOFLAG_16BIT)
		printf("File contains a 16bit truecolor image.\n");
  if ( image->flags & VIOFLAG_24BIT)
    printf("File contains a 24bit truecolor image.\n");
  if ( image->flags & VIOFLAG_32BIT)
    printf("File contains a 32bit truecolor image.\n");
  if ( image->flags & VIOFLAG_ZBUFFER)
    printf("File contains a z map.\n");

/*
	if (!(image->flags & VIOFLAG_8BIT))
  {
    printf("Creating 256 color image,"); fflush( stdout);
    vio_make8bit( image);
		printf("Done!\n");
  }

  makepalette( palette, image->palette, 256);
	remapdata( palette, image->palette, image->image8, image->width, image->height);

//  if( !drv->init(drv->modelist[mode].width, drv->modelist[mode].height, 0))
*/
  if( !drv->init(640,480, 0))
	{
		printf("Unable to initilize %s.(%s)\n", drv->name, drv->geterror());
		exit(0);
	}

  if ( !drv->mouseinit( 0, 0, drv->width - 1, drv->height - 1))
	{
		drv->exit();
		printf("Unable to initilize mousedriver.\n");
		exit(0);
	}

	buff = drv->createbuff( drv->width, drv->height);
	drv->setbuff( buff);

/*
  drv->setpalette( palette);
*/
	while( !quit)
  {
		drv->vsync();
    drv->copybuff( 0, 0);

    drv->getmousediff( &x, &y);

    p.x += (float)x, p.y += (float)y; p.l = (float)l;

    if( p.x < (drv->width - image->width))
      p.x = (float)(drv->width - image->width);
    if( p.x > 0)
      p.x = 0;

    if( p.y < (drv->height - image->height))
      p.y = (float)(drv->height - image->height);
    if( p.y > 0)
		  p.y = 0;


//    drv->blit( p, image->image16, image->zbuffer, image->width, image->height);
		blitta (p,drv->activebuff,image->image32,image->width,image->height);

		while( drv->kbhit())
		{
			switch( drv->getkey())
			{
				case 27: quit = TRUE; break;
				case '-': l--,l &= 63; break;
				case '+': l++,l &= 63; break;
				case 9:
				{
					mode++;
					if( mode >= drv->modes)
						mode = 0;
					drv->destroybuff( buff);
					drv->reinit( drv->modelist[mode].width, drv->modelist[mode].height);
					buff = drv->createbuff( drv->width, drv->height);
					drv->setbuff( buff);
					break;
				}
			}
		}
  }
  drv->exit();

  return( 0);
}


