//-----------------------------------------------------------------------------
//
//  $Logfile:: /Source/gl_rmisc.c                                             $
// $Revision:: 3                                                              $
//   $Author:: Burgermac                                                      $
//     $Date:: 8/21/01 6:07 PM                                                $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
//

#include "gl_local.h"
#include "client.h"

void GL_Strings_f( void );

/*
==================
R_InitParticleTexture
==================
*/
byte	dottexture[8][8] =
{
	{0,0,0,0,0,0,0,0},
	{0,0,1,1,0,0,0,0},
	{0,1,1,1,1,0,0,0},
	{0,1,1,1,1,0,0,0},
	{0,0,1,1,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0},
};

void R_InitParticleTexture (void)
{
	int	x,y;
	byte data[8][8][4];
	
	//
	// also use this for bad textures, but without alpha
	//
	for (x=0 ; x<8 ; x++) {
		for (y=0 ; y<8 ; y++) {
			data[y][x][0] = (byte)(dottexture[x&3][y&3]*255);
			data[y][x][1] = 0; // dottexture[x&3][y&3]*255;
			data[y][x][2] = 0; //dottexture[x&3][y&3]*255;
			data[y][x][3] = 255;
		}
	}
	r_notexture = GL_LoadPic ("***r_notexture***", &data[0][0][0], NULL, 8, 8, it_wall, 0, false, false);
	r_particletexture = GL_FindImage ("pics/particle.tga", it_pic);
}


/*
==============================================================================

						SCREEN SHOTS

==============================================================================
*/

typedef struct _TargaHeader {
	unsigned char 	id_length, colormap_type, image_type;
	unsigned short	colormap_index, colormap_length;
	unsigned char	colormap_size;
	unsigned short	x_origin, y_origin, width, height;
	unsigned char	pixel_size, attributes;
} TargaHeader;


/*
==================
GL_ScreenShot_f
==================
*/
void GL_ScreenShot_f (void)
{
	byte		*buffer;
	char		picname[80];
	char		checkname[MAX_OSPATH];
	int			i, c, temp;
	FILE		*f;

	// create the scrnshots directory if it doesn't exist
	Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Playerdir());
	Sys_Mkdir (checkname);

//
// find a file name to save it to
//
	for (i=0 ; i<=999 ; i++)
	{
		Com_sprintf (picname, sizeof(picname), "%s%03d.tga", scr_shotname->string, i );
		Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Playerdir(), picname );

		f = fopen (checkname, "rb");
		if (!f)
			break;	// file doesn't exist
		fclose (f);
	}

	if (i==1000)
	{
		ri.Con_Printf (PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n");
		return;
 	}

	buffer = (byte*)malloc(vid.width*vid.height*3 + 18);
	memset (buffer, 0, 18);
	buffer[2] = 2;		// uncompressed type
	buffer[12] = vid.width&255;
	buffer[13] = vid.width>>8;
	buffer[14] = vid.height&255;
	buffer[15] = vid.height>>8;
	buffer[16] = 24;	// pixel size

	qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );

	// swap rgb to bgr
	c = 18+vid.width*vid.height*3;
	for (i=18 ; i<c ; i+=3)
	{
		temp = buffer[i];
		buffer[i] = buffer[i+2];
		buffer[i+2] = temp;
	}

	f = fopen (checkname, "wb");
	fwrite(buffer, 1, c, f);
	fclose (f);

	free(buffer);
	ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname);
}

/*
** GL_Strings_f
*/
void GL_Strings_f( void )
{
	ri.Con_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string );
	ri.Con_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string );
	ri.Con_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string );
	ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string );
}

/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
	qglClearColor (1,0, 0.5 , 0.5);
	qglCullFace(GL_FRONT);
	qglEnable(GL_TEXTURE_2D);

	qglEnable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.666);

	qglDisable (GL_DEPTH_TEST);
	qglDisable (GL_CULL_FACE);
	qglDisable (GL_BLEND);

	qglColor4f (1,1,1,1);

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglShadeModel (GL_FLAT);

	GL_TextureMode( gl_texturemode->string );
	GL_SkinTextureMode( gl_skintexturemode->string );
	GL_TextureAlphaMode( gl_texturealphamode->string );
	GL_TextureSolidMode( gl_texturesolidmode->string );


	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	GL_TexEnv( GL_REPLACE );

	if ( qglPointParameterfEXT )
	{
		float attenuations[3];

		attenuations[0] = gl_particle_att_a->value;
		attenuations[1] = gl_particle_att_b->value;
		attenuations[2] = gl_particle_att_c->value;

		qglEnable( GL_POINT_SMOOTH );
		qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, gl_particle_min_size->value );
		qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, gl_particle_max_size->value );
		qglPointParameterfvEXT( GL_DISTANCE_ATTENUATION_EXT, attenuations );
	}

	if ( qglColorTableEXT && gl_ext_palettedtexture->value )
	{
		qglEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
	}
	GL_UpdateSwapInterval();
}

void GL_UpdateSwapInterval( void )
{
	if ( gl_swapinterval->modified )
	{
		gl_swapinterval->modified = false;

		if ( !gl_state.stereo_enabled )
		{
#ifdef _WIN32
			if ( qwglSwapIntervalEXT )
				qwglSwapIntervalEXT( gl_swapinterval->value );
#endif
		}
	}
}

static vec3_t	*gl_portal_points = NULL;
static int		*gl_portals = NULL;
static int		gl_numportals;

/*
** GL_LoadPortals
*/
#define	MAX_MOD_KNOWN	512
extern model_t	mod_known[MAX_MOD_KNOWN];
void GL_LoadPortals( void )
{
	int i, total, j, num;
	void *buf;
	const char *tempbuf;
	const char *token;
	char name[128];

	if ( ri.Cmd_Argc() < 2 )
	{
		char tempname[128];
		strcpy( tempname, mod_known[0].name );
		if ( strlen( COM_FileExtension( tempname ) ) )
			COM_StripExtension( tempname, name );
		else
			strcpy( name, tempname );
	}
	else
	{
		char tempname[128];
		strcpy( tempname, ri.Cmd_Argv(1) );
		if ( strlen( COM_FileExtension( tempname ) ) )
			COM_StripExtension( tempname, name );
		else
			strcpy( name, tempname );
	}
	COM_DefaultExtension ( name, ".prt" );

	ri.FS_LoadFile (name, &buf);
	if (!buf)
	{
		ri.Con_Printf (PRINT_ALL, "GL_LoadPortals: Could not find %s\n", name);
		return;
	}
	if (gl_portals)
		free(gl_portals);
	if (gl_portal_points)
		free(gl_portal_points);
	gl_numportals = 0;

	// count up the portals
	tempbuf = (const char *) buf;
	// skip header
	COM_GetToken( &tempbuf, true );
	// skip num areas
	COM_GetToken( &tempbuf, true );
	// read in num portals
	token = COM_GetToken( &tempbuf, true );
	gl_numportals = Sinatof( token );
	gl_portals = (int *)malloc( gl_numportals * sizeof( int ) );
	i = 0;
	total = 0;
	// count up the number of points
	while ( 1 )
	{
		token = COM_GetToken( &tempbuf, true );
		if (!token[0])
			break;
		gl_portals[i] = Sinatof( token );
		total += gl_portals[i];
		i++;
		while ( 1 )
		{
			token = COM_GetToken( &tempbuf, false );
			if (!token[0])
				break;
		}
	}
	gl_portal_points = (vec3_t *)malloc( total * sizeof( vec3_t ) );
	memset( gl_portal_points, 0, total * sizeof( vec3_t ) );

	num = 0;
	tempbuf = (const char *) buf;
	// skip header
	COM_GetToken( &tempbuf, true );
	// skip num areas
	COM_GetToken( &tempbuf, true );
	// read in num portals
	COM_GetToken( &tempbuf, true );
	for (i=0;i<gl_numportals;i++)
	{
		// get the number of points
		COM_GetToken( &tempbuf, true );
		// skip area 1
		COM_GetToken( &tempbuf, false );
		// skip area 2
		COM_GetToken( &tempbuf, false );
		for (j=0;j<gl_portals[i];j++)
		{
			// get (x
			token = COM_GetToken( &tempbuf, false );
			gl_portal_points[num][0] = Sinatof( &token[1] );
			// get y
			token = COM_GetToken( &tempbuf, false );
			gl_portal_points[num][1] = Sinatof( token );
			// get z
			token = COM_GetToken( &tempbuf, false );
			gl_portal_points[num][2] = Sinatof( token );
			// skip )
			token = COM_GetToken( &tempbuf, false );
			num++;
		}
	}
	ri.Con_Printf( PRINT_ALL, "GL_LoadPortals: %d portals loaded successfully\n", gl_numportals );
}

extern cvar_t *gl_showportals;
void GL_DrawPortals( void )
{
	int i, j, num;

	if (!gl_showportals->value)
		return;

	qglDisable (GL_TEXTURE_2D);
	if (gl_showportals->value == 2)
		qglDisable (GL_DEPTH_TEST);

	num = 0;
	qglColor4f( 1, 1, 1, 1 );
	for( i = 0; i < gl_numportals; i++ )
	{
		qglBegin (GL_LINES);
		for (j=0;j<gl_portals[i];j++)
		{
			qglVertex3fv( gl_portal_points[num+j] );
			qglVertex3fv( gl_portal_points[num + ( (j+1) % gl_portals[i] ) ] );
		}
		qglEnd ();
		num += gl_portals[i];
	}

	if (gl_showportals->value == 2)
		qglEnable (GL_DEPTH_TEST);
	qglEnable (GL_TEXTURE_2D);
}
