/*
gl_draw.c - orthogonal drawing stuff
Copyright (C) 2010 Uncle Mike

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

#include "r_local.h"

/*
=============
R_GetImageParms
=============
*/
void R_GetTextureParms( int *w, int *h, int texnum )
{
	image_t *glt;

	glt = R_GetTexture( texnum );
	if( w )
		*w = glt->srcWidth;
	if( h )
		*h = glt->srcHeight;
}

/*
=============
Draw_StretchPicImplementation
=============
*/
static void R_DrawStretchPicImplementation( int x, int y, int w, int h, int s1, int t1, int s2, int t2, image_t *pic )
{
	unsigned int height;
	int          skip, v;
	qboolean     transparent = false;
	pixel_t      *buffer;

	if( x < 0 )
	{
		s1 += ( -x ) * ( s2 - s1 ) / w;
		x = 0;
	}
	if( x + w > vid.width )
	{
		s2 -= ( x + w - vid.width ) * ( s2 - s1 ) / w;
		w = vid.width - x;
	}
	if( y + h > vid.height )
	{
		t2 -= ( y + h - vid.height ) * ( t2 - t1 ) / h;
		h = vid.height - y;
	}

	if( !pic->pixels[0] || s1 >= s2 || t1 >= t2 )
		return;

	// gEngfuncs.Con_Printf ("pixels is %p\n", pic->pixels[0] );

	height = h;

	if( y < -h ) // out of display, out of bounds
		return;

	if( y < 0 )
	{
		skip = -y;
		height += y;
		y = 0;
	}
	else
		skip = 0;

	if( pic->alpha_pixels )
	{
		buffer = pic->alpha_pixels;
		transparent = true;
	}
	else
		buffer = pic->pixels[0];


#pragma omp parallel for schedule(static)
	for( v = 0; v < height; v++ )
	{
		int     alpha1 = vid.alpha;
		pixel_t *dest = vid.buffer + ( y + v ) * vid.rowbytes + x;
		uint    sv = ( skip + v ) * ( t2 - t1 ) / h + t1;
		uint    u, f, fstep;
		pixel_t *source = buffer + sv * pic->width + s1;

		f = 0;
		fstep = (( s2 - s1 ) << 16 ) / w;

		for( u = 0; u < w; u++ )
		{
			pixel_t src = source[f >> 16];
			int     alpha = alpha1;
			f += fstep;

			if( transparent )
			{
				alpha &= src >> ( 16 - 3 );
				src = src << 3;
			}

			if( alpha == 0 )
				continue;

			if( vid.color != COLOR_WHITE )
				src = vid.modmap[( src & 0xff00 ) | ( vid.color >> 8 )] << 8 | ( src & vid.color & 0xff ) | (( src & 0xff ) >> 3 );

			if( vid.rendermode == kRenderTransAdd )
			{
				pixel_t screen = dest[u];
				dest[u] = vid.addmap[( src & 0xff00 ) | ( screen >> 8 )] << 8 | ( screen & 0xff ) | (( src & 0xff ) >> 0 );
			}
			else if( vid.rendermode == kRenderScreenFadeModulate )
			{
				pixel_t screen = dest[u];
				dest[u] = BLEND_COLOR( screen, vid.color );
			}
			else if( alpha < 7 ) // && (vid.rendermode == kRenderTransAlpha || vid.rendermode == kRenderTransTexture ) )
			{
				pixel_t screen = dest[u];                    //  | 0xff & screen & src ;
				dest[u] = BLEND_ALPHA( alpha, src, screen ); // vid.alphamap[( alpha << 16)|(src & 0xff00)|(screen>>8)] << 8 | (screen & 0xff) >> 3 | ((src & 0xff) >> 3);
			}
			else
				dest[u] = src;

		}
	}
}


/*
=============
R_DrawStretchPic
=============
*/
void GAME_EXPORT R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum )
{
	image_t *pic = R_GetTexture( texnum );
	int     width = pic->width, height = pic->height;
//	GL_Bind( XASH_TEXTURE0, texnum );
	if( s2 > 1.0f || t2 > 1.0f )
		return;
	if( s1 < 0.0f || t1 < 0.0f )
		return;
	if( w < 1.0f || h < 1.0f )
		return;
	R_DrawStretchPicImplementation( x, y, w, h, width * s1, height * t1, width * s2, height * t2, pic );
}

void Draw_Fill( int x, int y, int w, int h )
{
	unsigned int height;
	int          v;
	pixel_t      src = vid.color;
	int          alpha = vid.alpha;

	if( x < 0 )
		x = 0;

	if( x + w > vid.width )
		w = vid.width - x;

	if( w <= 0 )
		return;

	if( y + h > vid.height )
		h = vid.height - y;

	if( h <= 0 )
		return;

	height = h;
	if( y < 0 )
	{
		if( h <= -y )
			return;
		height += y;
		y = 0;
	}

#pragma omp parallel for schedule(static)
	for( v = 0; v < height; v++ )
	{
		pixel_t *dest = vid.buffer + ( y + v ) * vid.rowbytes + x;
		uint    u;

		for( u = 0; u < w; u++ )
		{
			if( alpha == 0 )
				continue;

			if( vid.rendermode == kRenderTransAdd )
			{
				pixel_t screen = dest[u];
				dest[u] = vid.addmap[( src & 0xff00 ) | ( screen >> 8 )] << 8 | ( screen & 0xff ) | (( src & 0xff ) >> 0 );
			}
			else if( alpha < 7 ) // && (vid.rendermode == kRenderTransAlpha || vid.rendermode == kRenderTransTexture ) )
			{
				pixel_t screen = dest[u];                    //  | 0xff & screen & src ;
				dest[u] = BLEND_ALPHA( alpha, src, screen ); // vid.alphamap[( alpha << 16)|(src & 0xff00)|(screen>>8)] << 8 | (screen & 0xff) >> 3 | ((src & 0xff) >> 3);
			}
			else
				dest[u] = src;
		}
	}
}

/*
=============
GL_UpdateTexture
=============
*/
void GAME_EXPORT GL_UpdateTexture( int texnum, int cols, int rows, int width, int height, const byte *buffer, pixformat_t fmt )
{
}

/*
===============
R_Set2DMode
===============
*/
void GAME_EXPORT R_Set2DMode( qboolean enable )
{
	vid.color = COLOR_WHITE;
	vid.is2d = enable;
	vid.alpha = 7;

	if( enable )
	{
		RI.currententity = NULL;
		RI.currentmodel = NULL;
	}
}
