/*
 * bsp5.h
 * $Id: bsp5.h,v 1.9 2010-01-11 18:48:20 sezero Exp $
 *
 * Copyright (C) 1996-1997  Id Software, Inc.
 * Copyright (C) 1997-1998  Raven Software Corp.
 *
 * 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 2 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef __BSP5_H__
#define __BSP5_H__


typedef struct
{
	vec3_t	normal;
	double	dist;
	int		type;
} plane_t;


#include "map.h"

#define	MAX_THREADS	4

#define	ON_EPSILON	0.01
#define	BOGUS_RANGE	18000

// the exact bounding box of the brushes is expanded some for the headnode
// volume.  is this still needed?
#define	SIDESPACE	24

//============================================================================


typedef struct
{
	int		numpoints;
	vec3_t	points[8];		// variable sized
} winding_t;

#define MAX_POINTS_ON_WINDING	64

winding_t	*BaseWindingForPlane (plane_t *p);
void		CheckWinding (winding_t *w);
winding_t	*NewWinding (int points);
void		FreeWinding (winding_t *w);
winding_t	*CopyWinding (winding_t *w);
winding_t	*ClipWinding (winding_t *in, plane_t *split, qboolean keepon);
void		DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t **back);

//============================================================================
 
#define	MAXEDGES	32
#define	MAXPOINTS	28	// don't let a base face get past this
				// because it can be split more later

typedef struct visfacet_s
{
	struct visfacet_s	*next;

	int				planenum;
	int				planeside;	// which side is the front of the face
	int				texturenum;
	int				contents[2];	// 0 = front side

	struct visfacet_s	*original;		// face on node
	int				outputnumber;	// only valid for original faces after
							// write surfaces
	int				numpoints;
	vec3_t			pts[MAXEDGES];		// FIXME: change to use winding_t
	int				edges[MAXEDGES];
	int				Light;
} face_t;


typedef struct surface_s
{
	struct surface_s	*next;
	struct surface_s	*original;	// before BSP cuts it up
	int			planenum;
	int			outputplanenum;	// only valid after WriteSurfacePlanes
	vec3_t		mins, maxs;
	qboolean		onnode;		// true if surface has already been used
						// as a splitting node
	face_t		*faces;	// links to all the faces on either side of the surf
} surface_t;


//
// there is a node_t structure for every node and leaf in the bsp tree
//
#define	PLANENUM_LEAF		-1

typedef struct node_s
{
	vec3_t			mins,maxs;		// bounding volume, not just points inside

// information for decision nodes
	int				planenum;	// -1 = leaf node
	int				outputplanenum;	// only valid after WriteNodePlanes
	int				firstface;	// decision node only
	int				numfaces;	// decision node only
	struct node_s	*children[2];	// only valid for decision nodes
	face_t			*faces;	// decision nodes only, list for both sides

// information for leafs
	int				contents;	// leaf nodes (0 for decision nodes)
	face_t			**markfaces;	// leaf nodes only, point to node faces
	struct portal_s	*portals;
	int				visleafnum;	// -1 = solid
	int				valid;		// for flood filling
	int				occupied;	// light number in leaf for outside filling
} node_t;

//=============================================================================

// brush.c

#define	NUM_HULLS	6		// normal and +16

#define	NUM_CONTENTS	2		// solid and water

typedef struct brush_s
{
	struct brush_s	*next;
	vec3_t			mins, maxs;
	face_t			*faces;
	int				contents;
} brush_t;

typedef struct
{
	vec3_t		mins, maxs;
	brush_t		*brushes;	// NULL terminated list
} brushset_t;

extern	int			numbrushplanes;
extern	plane_t		planes[MAX_MAP_PLANES];

brushset_t	*Brush_LoadEntity (entity_t *ent, int hullnumber);
int		PlaneTypeForNormal (vec3_t normal);
int		FindPlane (plane_t *dplane, int *side);

//=============================================================================

// csg4.c

// build surfaces is also used by GatherNodeFaces
extern	face_t	*validfaces[MAX_MAP_PLANES];
surface_t	*BuildSurfaces (void);

face_t		*NewFaceFromFace (face_t *in);
surface_t	*CSGFaces (brushset_t *bs);
void		SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back);

//=============================================================================

// solidbsp.c

void	DivideFacet (face_t *in, plane_t *split, face_t **front, face_t **back);
void	CalcSurfaceInfo (surface_t *surf);
void	SubdivideFace (face_t *f, face_t **prevptr);
node_t	*SolidBSP (surface_t *surfhead, qboolean midsplit);

//=============================================================================

// merge.c

void	MergePlaneFaces (surface_t *plane);
face_t	*MergeFaceToList (face_t *face, face_t *list);
face_t	*FreeMergeListScraps (face_t *merged);
void	MergeAll (surface_t *surfhead);

//=============================================================================

// surfaces.c

extern	int		c_cornerverts;
extern	int		c_tryedges;
extern	face_t		*edgefaces[MAX_MAP_EDGES][2];

extern	int		firstmodeledge;
extern	int		firstmodelface;

void		SubdivideFaces (surface_t *surfhead);
surface_t	*GatherNodeFaces (node_t *headnode);
void		MakeFaceEdges (node_t *headnode);

//=============================================================================

// portals.c

typedef struct portal_s
{
	int			planenum;
	node_t		*nodes[2];		// [0] = front side of planenum
	struct portal_s	*next[2];
	winding_t	*winding;
} portal_t;

extern	node_t	outside_node;		// portals outside the world face this

void	PortalizeWorld (node_t *headnode);
void	WritePortalfile (node_t *headnode);
void	FreeAllPortals (node_t *node);

//=============================================================================

// region.c

void	GrowNodeRegions (node_t *headnode);

//=============================================================================

// tjunc.c

void	tjunc (node_t *headnode);

//=============================================================================

// writebsp.c

extern	int	LightValues[MAX_MAP_CLIPNODES];

void	WriteNodePlanes (node_t *headnode);
void	WriteClipNodes (node_t *headnode);
void	WriteDrawNodes (node_t *headnode);

void	BumpModel (int hullnumber);
int	FindFinalPlane (dplane_t *p);

void	BeginBSPFile (void);
void	FinishBSPFile (void);

//=============================================================================

// draw.c

void	Draw_ClearBounds (void);
void	Draw_AddToBounds (vec3_t v);
void	Draw_DrawFace (face_t *f);
void	Draw_ClearWindow (void);
void	Draw_SetRed (void);
void	Draw_SetGrey (void);
void	Draw_SetBlack (void);
void	DrawPoint (vec3_t v);

void	Draw_SetColor (int c);
void	SetColor (int c);
void	DrawPortal (portal_t *p);
void	DrawLeaf (node_t *l, int color);
void	DrawBrush (brush_t *b);

void	DrawWinding (winding_t *w);
void	DrawTri (vec3_t p1, vec3_t p2, vec3_t p3);

//=============================================================================

// outside.c

qboolean FillOutside (node_t *node);

//=============================================================================

extern	qboolean	drawflag;
extern	qboolean	nofill;
extern	qboolean	notjunc;
extern	qboolean	noclip;

extern	int		hullnum;
extern	qboolean	oldhullsize;	// if true, use original H2 sizes for hulls #5 and #6, not H2MP ones

extern	brushset_t	*brushset;

extern	int		valid;

extern	char	portfilename[1024];
extern	char	bspfilename[1024];
extern	char	pointfilename[1024];

extern	char	projectpath[1024];	// with a trailing slash, for finding wads

extern	qboolean	worldmodel;


//=============================================================================
// verbose printf

extern	qboolean	verbose;
void	qprintf (const char *fmt, ...) __attribute__((__format__(__printf__,1,2)));	// only prints if verbose


//=============================================================================
// misc functions

face_t		*AllocFace (void);
void		FreeFace (face_t *f);

struct portal_s	*AllocPortal (void);
void		FreePortal (struct portal_s *p);

surface_t	*AllocSurface (void);
void		FreeSurface (surface_t *s);

node_t		*AllocNode (void);
struct brush_s	*AllocBrush (void);

//=============================================================================

#endif	/* __BSP5_H__	*/

