//-----------------------------------------------------------------------------
//
//  $Logfile:: /Source/r_console3d.c                                          $
// $Revision:: 2                                                              $
//   $Author:: Burgermac                                                      $
//     $Date:: 12/27/00 5:59 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: 3D Game console
//

#include "r_local.h"

// Global console information.
conInfo_t consoleInfo;

#ifdef _MSC_VER
#pragma optimize("", off)
#endif

void R_DrawConsole (model_t *model, msurface_t *psurf)
{
	int j;
	vec3_t u = {0,0,0}, v = {0,0,0}, n= {0,0,0};
	float mins=99999, mint=99999, maxs=-99999, maxt=-99999;
	float surface_width, surface_height;
	vec3_t offset_origin, diff;
	float dist, delta;
	float s, t;

	// Set up a coordinate system based on this
	// entity's surface.

	if (!model)
		model = r_worldmodel;

	j = psurf - model->surfaces;
	if (j < 0 || j > model->numsurfaces)
		return;

	if (!psurf->texinfo)
		return;

	if (psurf->texinfo->flags & SURF_CONSOLE)
	{
		vec3_t origin, prevpoint, nextpoint, entorigin;
		glpoly_t *poly;
		entity_t *ent;
		model_t * mod;

		ent = psurf->entity;
		mod = ent->model;
		if (!mod)
			mod = r_worldmodel;

		if (mod == r_worldmodel)
		{
			VectorCopy(vec3_origin, entorigin);
		}
		else
		{
			vec3_t angles;

			VectorCopy(ent->origin, entorigin);
			VectorCopy(ent->angles, angles);
			angles[YAW] = -angles[YAW];
			angles[PITCH] = -angles[PITCH];
			AnglesToMat(angles, entity_rotation);
		}

		poly = BuildPolygon(mod, psurf);

		// Find texture coordinate extents
		for (j = 0; j < poly->numverts; j++)
		{
			s = poly->verts[j][3] - psurf->texturemins[0]/psurf->texinfo->image->width;
			t = poly->verts[j][4] - psurf->texturemins[1]/psurf->texinfo->image->height;
			mins = __min(mins,s);
			mint = __min(mint,t);
			maxs = __max(maxs,s);
			maxt = __max(maxt,t);
		}

		// Define the coordinate system of this surface.
		// Origin is defined at MINS,MAXT (0,1)
		for (j = 0; j < poly->numverts; j++)
		{
			s = poly->verts[j][3] - psurf->texturemins[0]/psurf->texinfo->image->width;
			t = poly->verts[j][4] - psurf->texturemins[1]/psurf->texinfo->image->height;

			#if 0
			ri.Con_Printf(PRINT_DEVELOPER,
					"vert:%d x:%2.0f y:%2.0f z:%2.0f s:%f t:%f\n mins:%f mint:%f maxs:%f maxt:%f\n", j,
					poly->verts[j][0],
					poly->verts[j][1],
					poly->verts[j][2],
					s,t,mins,mint,maxs,maxt);
			#endif
			if (s == mins && t == maxt) {
				VectorCopy(poly->verts[j], origin);
			} else if (s == maxs && t == maxt) {
				VectorCopy(poly->verts[j], nextpoint);
			} else if (s == mins && t == mint) {
				VectorCopy(poly->verts[j], prevpoint);
			}
		}
		if (mod != r_worldmodel)
		{
			R_EntityRotate(origin);
			R_EntityRotate(nextpoint);
			R_EntityRotate(prevpoint);
		}

		// Calculate distance from player to console surface
		VectorAdd(origin,entorigin,offset_origin);

		if (!(psurf->texinfo->flags & SURF_NOFILTER))
		{
			VectorSubtract(offset_origin, r_refdef.vieworg, diff);
			dist = DotProduct(diff, diff);
			if (dist > r_condist->value)
				return;
			// Set an appropriate alpha fade for the distance.
			if ((delta = r_condist->value - dist) < r_conthresh->value)
				consoleInfo.alpha = delta / r_conthresh->value;
			else
				consoleInfo.alpha = 1.0f;
		}
		else {
			consoleInfo.alpha = 1.0f;
		}

		// Calcluate u and v vectors
		VectorSubtract(nextpoint, origin, u);
		VectorSubtract(prevpoint, origin, v);

		// Get the surface normal
		VectorCopy(psurf->plane->normal, n);
		if (psurf->flags & SURF_PLANEBACK) {
			VectorScale(n, -1, n);
		}

		// get the origin of the surface
		VectorCopy(origin, consoleInfo.origin);
		VectorCopy(entorigin, consoleInfo.modelorigin);

		// Offset from the surface to avoid z-aliasing.
		{
			vec3_t offset = {0,0,0};
			VectorScale(n, r_conoffset->value, offset);
			VectorAdd(consoleInfo.origin, offset, consoleInfo.origin);
		}

		// Calculate the width and height of this surface.
		consoleInfo.surface_width  = surface_width = VectorNormalize(u);
		consoleInfo.surface_height = surface_height = VectorNormalize(v);

		VectorCopy(u, consoleInfo.u);
		VectorCopy(v, consoleInfo.v);
		VectorCopy(n, consoleInfo.n);

		// Callback to the client to process this console
		consoleInfo.onscreen = false;
		ri.CONSOLE_Process(psurf->texinfo->surf->groupname);
		consoleInfo.onscreen = true;
	}
}

#ifdef _MSC_VER
#pragma optimize("", on)
#endif
