#include "standard.h"
#include "global.h"
#include "winmain.h"
#include "hwrender.h"
#include "drawprimitive.h"
#include "../game/lasers.h"


bool ClipLine(long &x1,long &y1,long &x2,long &y2,int sw,int sh)
{
	float clipper;
	int flag;

	if(x1 < 0 && x2 < 0) return false;
	if(y1 < 0 && y2 < 0) return false;

	if(x1 > sw && x2 > sw) return false;
	if(y1 > sh && y2 > sh) return false;


	if(x1 > sw)
	{
	   clipper = (float(sw) - x2) / float(x1-x2);
	   x1 = sw;
	   y1 = y2 + (y1 - y2) * clipper;
	}

	if(x2 > sw)
	{
	   clipper = (float(sw) - x1) / float(x2-x1);
	   x2 = sw;
	   y2 = y1 + (y2 - y1) * clipper;
	}

	if(x1 < 0)
	{
	   clipper = (float(0) - x1) / float(x2-x1);
	   x1 = 0;
	   y1 = y1 + (y2 - y1) * clipper;
	}

	if(x2 < 0)
	{
	   clipper = (float(0) - x2) / float(x1-x2);
	   x2 = 0;
	   y2 = y2 + (y1 - y2) * clipper;
	}
	

	if(y1 > sh)
	{
	   clipper = (float(sh) - y2) / float(y1-y2);
	   y1 = sh;
	   x1 = x2 + (x1 - x2) * clipper;
	}

	if(y2 > sh)
	{
	   clipper = (float(sh) - y1) / float(y2-y1);
	   y2 = sh;
	   x2 = x1 + (x2 - x1) * clipper;
	}

	if(y1 < 0)
	{
	   clipper = (float(0) - y1) / float(y2-y1);
	   y1 = 0;
	   x1 = x1 + (x2 - x1) * clipper;
	}

	if(y2 < 0)
	{
	   clipper = (float(0) - y2) / float(y1-y2);
	   y2 = 0;
	   x2 = x2 + (x1 - x2) * clipper;
	}

	return true;

}



void S_DrawLaserBeam(GAME_VECTOR *src,GAME_VECTOR *dest,uchar r,uchar g,uchar b)
{
	long x1,x2,y1,y2,z1,z2,r1,g1,b1,r2,g2,b2;
	long wx,wy,wz,dx,dy,dz,lp,segments;
	long result[3*200];
	long rgbs[3*200];	long screencoords[3*200];

	
	int sw = DXDisplayMode(App.DeviceInfoPtr,App.DXConfigPtr).w-1;
	int sh = DXDisplayMode(App.DeviceInfoPtr,App.DXConfigPtr).h-1;

	UpdateLaserShades();

	phd_PushMatrix();
	phd_TranslateAbs(src->x,src->y,src->z);

	dx = (src->x - dest->x);
	dz = (src->z - dest->z);

	dx = mSqrt((dx*dx)+(dz*dz));
	segments = dx>>9;	// In half blocks.

	if (segments < 8)
		segments = 8;
	else if (segments > 32)
		segments = 32;

	dx = (dest->x - src->x) / segments;
	dy = (dest->y - src->y) / segments;
	dz = (dest->z - src->z) / segments;

	wx = wy = wz = 0;

	for (lp=0;lp<segments+1;lp++)
	{
		sint32		*mptr;
		mptr = phd_mxptr; 

		x1 = (mptr[M00] * wx + mptr[M01] * wy + mptr[M02] * wz + mptr[M03]);
		y1 = (mptr[M10] * wx + mptr[M11] * wy + mptr[M12] * wz + mptr[M13]);
		z1 = (mptr[M20] * wx + mptr[M21] * wy + mptr[M22] * wz + mptr[M23]);
		
		float zv = f_persp/(float)z1;
		screencoords[(lp*3)+0] = short(float(x1 * zv + f_centerx));
		screencoords[(lp*3)+1] = short(float(y1 * zv + f_centery));
		screencoords[(lp*3)+2] = z1>>W2V_SHIFT;

		wx += dx;
		wy += dy;
		wz += dz;

		if (lp == 0 || lp == segments /*||  result[(lp*3)+Z] >= DPQ_START*/)
		{
			rgbs[(lp*3)+X] = 0;
			rgbs[(lp*3)+Y] = 0;
			rgbs[(lp*3)+Z] = 0;
		}
		else
		{
			long rnd,tr,tg,tb,tz;
//			tz = *scrz;
			tz = result[(lp*3)+Z];

			rnd = LaserShades[lp];

			if (r==255)
				tr = 32+rnd;
			else
				tr = rnd>>r;
			if (g==255)
				tg = 32+rnd;
			else
				tg = rnd>>g;
			if (b==255)
				tb = 32+rnd;
			else
				tb = rnd>>b;
/*
			if (tz > 0x4000)
			{
				tr -= (tr * (0x5000-tz)) >> 10;
				tg -= (tr * (0x5000-tz)) >> 10;
				tb -= (tr * (0x5000-tz)) >> 10;
			}
*/
			rgbs[(lp*3)+X] = tr;
			rgbs[(lp*3)+Y] = tg;
			rgbs[(lp*3)+Z] = tb;
		}
	}


	x1 = screencoords[0+X]; 
	y1 = screencoords[0+Y]; 
	z1 = screencoords[0+Z]; 
	r1 = rgbs[0];
	g1 = rgbs[1];
	b1 = rgbs[2];

	for (lp=0;lp<segments;lp++)
	{
		x2 = screencoords[((lp+1)*3)+X]; 
		y2 = screencoords[((lp+1)*3)+Y]; 
		z2 = screencoords[((lp+1)*3)+Z]; 
		r2 = rgbs[((lp+1)*3)+0];
		g2 = rgbs[((lp+1)*3)+1];
		b2 = rgbs[((lp+1)*3)+2];

		if (z1 > 32 && z2 > 32/* && z1 < 0xa00*/)
		{
			if(ClipLine(x1,y1,x2,y2,sw,sh))
			{
				if(x1 >= 0 && x1 <= sw && y1 >= 0 && y1 <= sh && x2 >= 0 && x2 <= sw && y2 >= 0 && y2 <= sh)
				{
	
					D3DTLVERTEX v[2];

					v[0].sx = float(x1);	
					v[0].sy = float(y1);	
					v[0].sz = f_a-f_boo*(one/(float)(z1<<W2V_SHIFT));

		
					v[1].sx = float(x2);	
					v[1].sy = float(y2);	
					v[1].sz = f_a-f_boo*(one/(float)(z2<<W2V_SHIFT));


					v[0].color = RGB_MAKE(r1,g1,b1);
					v[1].color = RGB_MAKE(r2,g2,b2);
	
					v[0].specular = 0;
					v[1].specular = 0;
	
					v[0].rhw = v[0].sz;
					v[1].rhw = v[1].sz;

					HWR_SetCurrentTexture(0);
					HWR_EnableZBuffer(true,true);
	
					DrawPrimitive(D3DPT_LINESTRIP,D3DVT_TLVERTEX,&v,2,D3DDP_DONOTCLIP);
					
	
					HWR_EnableZBuffer(false,false);

				}
			
			}
		}

		x1 = x2;
		y1 = y2;
		z1 = z2;
		r1 = r2;
		g1 = g2;
		b1 = b2;
	}

	phd_PopMatrix();
}