//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005-2014 Simon Howard
// Copyright(C) 2015-2018 Fabian Greffrath
//
// 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.
//

#ifndef __CRISPY_MAPFORMAT__
#define __CRISPY_MAPFORMAT__

#include "doomtype.h"

// BSP node structure.

// Indicate a leaf.
#define NF_SUBSECTOR_VANILLA 0x8000
#define NF_SUBSECTOR         0x80000000

#define NO_INDEX ((unsigned short) -1) // [crispy] extended nodes
#define FIX_NO_INDEX(x)                                                        \
    if (x == 0xffff)                                                           \
    {                                                                          \
        x = -1;                                                                \
    }

typedef PACKED_STRUCT({
    // Partition line from (x,y) to x+dx,y+dy)
    short x;
    short y;
    short dx;
    short dy;
    // Bounding box for each child,
    // clip against view frustum.
    short bbox[2][4];
    // If NF_SUBSECTOR its a subsector,
    // else it's a node of another subtree.
    unsigned short children[2];
}) mapnode_t;

// SubSector, as generated by BSP.
typedef PACKED_STRUCT({
    unsigned short numsegs;
    // Index of first one, segs are stored sequentially.
    unsigned short firstseg;
}) mapsubsector_t;

// LineSeg, generated by splitting LineDefs
// using partition lines selected by BSP builder.
typedef PACKED_STRUCT({
    unsigned short v1;
    unsigned short v2;
    short angle;
    unsigned short linedef;
    short side;
    short offset;
}) mapseg_t;

//
// [crispy] allow loading of maps with DeePBSPV4 nodes
//

typedef PACKED_STRUCT({
    short x;
    short y;
    short dx;
    short dy;
    short bbox[2][4];
    int children[2];
}) mapnode_deepbspv4_t;

typedef PACKED_STRUCT({
    unsigned short numsegs;
    int firstseg;
}) mapsubsector_deepbspv4_t;

typedef PACKED_STRUCT({
    int v1;
    int v2;
    unsigned short angle;
    unsigned short linedef;
    short side;
    unsigned short offset;
}) mapseg_deepbspv4_t;

//
// [crispy] allow loading of maps with ZDBSP node formats
//

typedef PACKED_STRUCT({
    short x;
    short y;
    short dx;
    short dy;
    short bbox[2][4];
    int children[2];
}) mapnode_xnod_t;

typedef PACKED_STRUCT({
    // Segs are strictly sorted
    unsigned int numsegs;
}) mapsubsector_xnod_t;

typedef PACKED_STRUCT({
    unsigned int v1;
    unsigned int v2;
    unsigned short linedef;
    unsigned char side;
}) mapseg_xnod_t;

//
// [crispy] support XGL formats
//
typedef PACKED_STRUCT({
    unsigned int vertex, partner;
    unsigned short linedef;
    unsigned char side;
}) mapseg_xgln_t;

typedef PACKED_STRUCT({
    unsigned int vertex, partner;
    unsigned int linedef;
    unsigned char side;
}) mapseg_xgl2_t;

typedef PACKED_STRUCT({
    int x;
    int y;
    int dx;
    int dy;
    short bbox[2][4];
    int children[2];
}) mapnode_xgl3_t;

//
// [crispy] General map format loading
//

typedef enum bspformat_t
{
    NFMT_DOOMBSP,
    NFMT_DEEPBSPV4,
    NFMT_XNOD,
    NFMT_XGLN,
    NFMT_XGL2,
    NFMT_XGL3,
} bspformat_t;

typedef struct mapformat_t
{
    bspformat_t bsp;
    boolean compressed;
    boolean hexen;
} mapformat_t;

extern mapformat_t P_CheckMapFormat(int lumpnum);

extern void P_LoadSegs(int lump);
extern void P_LoadSubsectors(int lump);
extern void P_LoadNodes(int lump);

extern void P_LoadSegs_DeePBSPV4(int lump);
extern void P_LoadSubsectors_DeePBSPV4(int lump);
extern void P_LoadNodes_DeePBSPV4(int lump);

extern void P_LoadNodes_ZDBSP(int lump, mapformat_t format);

#endif // __CRISPY_MAPFORMAT__
