#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmdlib.h"

#ifndef __IDBSP__
#define __IDBSP__

#define MAX(a,b) ( (a) > (b) ) ? (a) : (b)
#define MIN(a,b) ( (a) < (b) ) ? (a) : (b)

typedef struct
	{
	int                 count;
	int                 size;
	void               *data;
	}
STORAGE;

#include <math.h>
#include <limits.h>
#include <float.h>
/*#include "cmdlib.h" */
#include "doomdata.h"
#include "wadfile.h"
/* #include "doomdata.h" */

/*
   #define SHORT(x)        NXSwapLittleShortToHost((short)x)
   #define LONG(x)         NXSwapLittleLongToHost((long)x)
 */

/*
   #define SHORT(x) LittleShort((short)x)
   #define LONG(x)  LittleLong((long)x)
 */
/*
   #define SHORT(x) BigShort((short)x)
   #define LONG(x) BigLong((long)x)
 */
/*
   #define SHORT(x) (short)(x)
   #define LONG(x) (long)(x)
 */

#ifndef PI
#define PI   3.14159265359
#endif

#define         MAXVERTEX               8192
#define         MAXTOUCHSECS    16
#define         MAXSECTORS              2048
#define         MAXSUBSECTORS   2048

typedef struct
	{
	float               x;
	float               y;
	}
NXPoint;

typedef struct
	{
	float               width;
	float               height;
	}
NXSize;

typedef struct
	{
	NXPoint             origin;
	NXSize              size;
	}
NXRect;

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

   map file types

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

typedef struct
	{
	int                 floorheight,
	                    ceilingheight;
	char                floorflat[9],
	                    ceilingflat[9];
	int                 lightlevel;
	int                 special,
	                    tag;
	}
sectordef_t;

typedef struct
	{
	int                 firstrow;
	int                 firstcollumn;
	char                toptexture[9];
	char                bottomtexture[9];
	char                midtexture[9];
	sectordef_t         sectordef;	/* on the viewers side */
	int                 sector;	/* only used when saving doom map */
	}
worldside_t;

typedef struct
	{
	NXPoint             p1,
	                    p2;
	int                 special,
	                    tag;
	int                 flags;
	worldside_t         side[2];
	}
worldline_t;

#define ML_BLOCKMOVE    1
#define ML_TWOSIDED             4	   /* backside will not be present at all if not two sided */

typedef struct
	{
	NXPoint             origin;
	int                 angle;
	int                 type;
	int                 options;
	int                 area;
	}
worldthing_t;

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

   internal types

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

typedef struct
	{
	NXPoint             pt;
	float               dx,
	                    dy;
	}
divline_t;

typedef struct bspstruct_s
	{
/*      id                                              lines_i;                // if non NULL, the node is */
	STORAGE            *lines_i;
	divline_t           divline;	/* terminal and has no children */
	float               bbox[4];
	struct bspstruct_s *side[2];
	}
bspnode_t;


typedef struct
	{
	NXPoint             p1,
	                    p2;
	int                 linedef,
	                    side,
	                    offset;
	boolean             grouped;	/* internal error check */
	}
line_t;


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

   idbsp

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

extern WADFILE      wad_i;

/*extern        boolean         draw; */
void                progress(void);
short               LittleShort(short l);
short               BigShort(short l);
long                LittleLong(long l);
long                BigLong(long l);
void                AddFromFile(char *resname, int size, char *fname);
void                FreeGlobalStorage(void);

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

   doomload

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

extern STORAGE     *linestore_i,
                   *thingstore_i;

/* void LoadDoomMap (char *mapname); */
void                LoadDoomMap(FILE * file);


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

   drawing

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

extern STORAGE     *window_i,
                   *view_i;
extern float        scale;
extern NXRect       worldbounds;

void                EraseWindow(void);
void                DrawMap(void);

/*void DrawLineStore (id lines_i); */
void                DrawLineStore(STORAGE * lines_i);
void                DrawDivLine(divline_t * div);
void                DrawLineDef(maplinedef_t * ld);


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

   buildbsp

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

extern int          cuts;		/* number of new lines generated by BSP process */
extern bspnode_t   *startnode;

void                BuildBSP(void);
void                DivlineFromWorldline(divline_t * d, line_t * w);
int                 PointOnSide(NXPoint * p, divline_t * l);
void                ExecuteSplit(STORAGE * lines_i, line_t * spliton, STORAGE * frontlist_i,
	STORAGE * backlist_i);


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

   savebsp

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

extern STORAGE     *secstore_i;
extern STORAGE     *mapvertexstore_i;
extern STORAGE     *subsecstore_i;
extern STORAGE     *maplinestore_i;
extern STORAGE     *nodestore_i;
extern STORAGE     *mapthingstore_i;
extern STORAGE     *ldefstore_i;
extern STORAGE     *sdefstore_i;

void                SaveDoomMap(void);

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

   saveblocks

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

void                SaveBlocks(void);

/* extern short *datalist; */

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

   savesectors

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

void                ProcessSectors(void);
void                BuildSectordefs(void);

/* extern short **vertexsublist; */

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

   saveconnect

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

void                ProcessConnections(void);
void                OutputConnections(void);

#endif
