#include "system/xstdio.h"
#include "system/xstddef.h"
#include "system/xstring.h"
#include "formats/v3d.h"
#include "formats/vio.h"
#include "vmath/vmath.h"
#include "vmath/matrix.h"
#include "render16/rnddrv.h"
#include "drivers/drv16.h"
#include "misc/col.h"
//#include "debug/mono.h"


#if defined(__DOS__)
#define DRIVER vesa16DRV
#elif defined(__NT__)
#define DRIVER dxDRV
#endif

extern DRV DRIVER;
static DRV *drv = &DRIVER;
static BUFF *buff = NULL;

#define LIGHT

#if defined(LIGHT)
BYTE lighttab[ LIGHTLEVELS * 256];
#endif
RGB palette[256];


#define RENDER scpDRV;
//#define RENDER wfDRV;

extern RNDDRV RENDER;
static RNDDRV *render = &RENDER;

static int choice (void)
{
	int i,j,c_tab[256],mode;
	char tjenna[512];

	printf ("Vesadetection:\n");
	for (i=0,j=0;i<drv->modes;i++)
	{
		if ((drv->modelist[i].width==640) && (drv->modelist[i].height==480) && (drv->modelist[i].bpp>8))
		{
				printf ("mode: %2i, %4ix%3i - %2i bits per pixel.\n",j,drv->modelist[i].width,drv->modelist[i].height,drv->modelist[i].bpp);
				c_tab[j]=i;
				j++;
		}
	}

	printf ("--------------------\n");
	printf ("Mode: ");
	fflush (stdout);
	gets (tjenna);

	mode = atoi (tjenna);
	if ((mode>j) || (mode<0)) return -1;

	return c_tab[mode];
}

static int local_lighttable (BYTE light, BYTE ambient)
{
	int i,j;
	int col,c;
	float add;


//	if ((lighttab = (BYTE *)xmalloc (sizeof (BYTE) * LIGHTLEVELS * 256))==NULL) return FALSE;

	for (j=0;j<256;j++)
	{
		col = j;
		add = (col - ambient)/(float)(LIGHTLEVELS/2.0);
		for (i=0;i<LIGHTLEVELS/2.0;i++)
		{
			c = ambient + add*i;
			lighttab[j+i*256]=c;
		}
		add = (light - col) / (float)(LIGHTLEVELS/2.0);
		for (i=0;i<LIGHTLEVELS/2.0;i++)
		{
			c = col + add*i;
	//		if (c>255) c = 255;
			lighttab[j+(i+LIGHTLEVELS/2)*256]=c;

		}
	}
	return TRUE;
}
void close (void)
{
	drv->exit ();
	mathclose ();
}

void init (V3D *v3d)
{
  int i,s,config = 0;
	char smode[256];


//-----------------------------------------
	s = 0;
	mathinit ();
	if (!drv->setup ())
	{
    printf ("[!] Error: Driver setup failed!\n");
		exit (1);
	} else {
/*
           printf("þ Available modes:\n");
					 for( i=0; i<drv->modes; i++)
             printf("%2i - %dx%d\n",i, drv->modelist[i].width, drv->modelist[i].height);

					 if (drv->modes>1)
					 {
						 printf ("Choose:");
					 	 gets (smode);
						 s = 0;
						 s = atoi (smode);
					 }
*/
					 s = choice ();
					 printf ("Choice: %i\n",s);

				 }

	if (drv->modelist[s].bpp == 15) config = DRVCFG_15BITS;
	else if (drv->modelist[s].bpp == 16) config = DRVCFG_16BITS;
	else if (drv->modelist[s].bpp == 24) config = DRVCFG_24BITS;
	else if (drv->modelist[s].bpp == 32) config = DRVCFG_32BITS;

  if(!drv->init(drv->modelist[s].width, drv->modelist[s].height, DRVCFG_ZBUFFER | config))
  //if(!drv->init(640,480, DRVCFG_ZBUFFER))
	{
    printf("[!] Error: 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("[!] Error: Unable to initilize mousedriver.\n");
		exit(0);
	}
  */
  buff = drv->createbuff(((int)drv->width)>>1, ((int)drv->height)>>1);
	drv->setbuff( buff);

#if defined(LIGHT)
	buff->lighttab = lighttab;
#endif
//  drv->setpalette( palette);

}

void main ( int argc, char *argv[])
{
	V3D *v3d;
	RGBA cl_col={0,0,0,0};
  char path[256], *pathptr;
	int q = FALSE;
  int mode = 0;
	int man=1;
	int displace = 0;
  float speed = 0.1;
	float orgspeed = speed;
//	char *e;

  if( argc != 2)
    exit( 1);

  printf ("-> SAGA v5.0 Truecolor testing! <-\n");
  printf ("-----------------------------------\n");

  strcpy( path, argv[1]);
  pathptr = path + strlen( path) - 1;
  while( (pathptr != &path) && (*pathptr != '\\') && (*pathptr != '/'))
    *(pathptr--) = '\0';
  *pathptr = '\0';

  printf("File: %s, Path: %s\n", argv[1], path);

  if ((v3d = v3d_load( argv[1], path, path))==NULL)
	{
		printf ("[!] - %s\n",v3d_geterror ());
		exit (1);
	}
//  v3d_dump (v3d);
/*
#ifdef LIGHT
  v3d_setup( v3d, &palette, &lighttab);
#else
  v3d_setup( v3d, &palette, NULL);
#endif
*/
	local_lighttable (255,32);

	init (v3d);

  q=FALSE;

	render->setviewport (buff,v3d->activecamera);

	while (!q)
	{

    drv->vsync();

		drv->xmovebuff (0,0,displace,0,cl_col);
/*
		switch (displace)
		{
			case 0 : scrptr = &buff->image[0]; break;
			case 1 : scrptr = &buff->image[1]; break;
			case 2 : scrptr = &buff->image[buff->width+1]; break;
			case 3 : scrptr = &buff->image[buff->width]; break;
		}
*/
	 	displace = (displace+1) & 3;

    render->prepare (v3d);
		render->render (v3d);

		if (man) v3d -> framecounter += speed;

		while( drv->kbhit())
		{
			switch( drv->getkey())
			{
				case 0:
						switch (drv->getkey ())
						{
							case 77 : if (!man) v3d->framecounter+=speed; break; //v3d->activecamera->anim->first->value[ANIM_POS_Y]++; break;
							case 75 : if ((!man)&&(v3d->framecounter>0)) v3d->framecounter-=speed; break; //v3d->activecamera->anim->first->value[ANIM_POS_Y]--; break;
							case 72 : speed+=0.1; break; //v3d->activecamera->anim->first->value[ANIM_POS_Z]+=10; break;
							case 80 : if (speed>0) speed-=0.1; break; //v3d->activecamera->anim->first->value[ANIM_POS_Z]-=10; break;
						}
						break;
				case 'm' : if (man!=0)
									 {
									 		man = 0;
											orgspeed = speed;
									 }
									 else { man=1; speed=orgspeed;}
									 break;
				case ' ' : v3d->framecounter = 0; break;
				case 27: q = TRUE; 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);
#if defined(LIGHT)
					buff->lighttab = lighttab;
#endif
					break;
				}
			}
		}


	}
  close ();
}
