/* doomload.m */
#include "idbsp.h"


int             linenum = 0;
STORAGE *linestore_i, *thingstore_i;

/*
=================
=
= ReadLine
=
=================
*/

/* worldline_t *ReadLine (FILE *file) */
worldline_t *ReadLine(FILE *file,worldline_t *line)
{
/*      worldline_t     *line; */
        NXPoint         *p1, *p2;
        worldside_t     *s;
        sectordef_t     *e;
        int                     i;

/*      line = malloc(sizeof(worldline_t)); */
      memset (line, 0, sizeof(worldline_t));

        p1 = &line->p1;
        p2 = &line->p2;

        if (fscanf (file,"(%f,%f) to (%f,%f) : %d : %d : %d\n"
                ,&p1->x, &p1->y,&p2->x, &p2->y,&line->flags
                , &line->special, &line->tag) != 7)
                Error ("Failed ReadLine");

        for (i=0 ; i<=  ( (line->flags&ML_TWOSIDED) != 0) ; i++)
        {
                s = &line->side[i];
                if (fscanf (file,"    %d (%d : %s / %s / %s )\n"
                        ,&s->firstrow, &s->firstcollumn, s->toptexture, s->bottomtexture, s->midtexture) != 5)
                        Error ("Failed ReadLine (side)");
                e = &s->sectordef;
                if (fscanf (file,"    %d : %s %d : %s %d %d %d\n"
                        ,&e->floorheight, e->floorflat, &e->ceilingheight
                        ,e->ceilingflat,&e->lightlevel, &e->special, &e->tag) != 7)
                        Error ("Failed ReadLine (sector)");
                if (!strcmp (e->floorflat,"-"))
                        printf ("WARNING: line %i has no sectordef\n",linenum);
        }

        linenum++;

        return line;
}

/*
=================
=
= ReadThing
=
=================
*/

/* worldthing_t *ReadThing (FILE *file) */
worldthing_t *ReadThing(FILE *file, worldthing_t *thing)
{
        int                             x,y;
/*      worldthing_t    *thing; */

/*      thing = malloc(sizeof(*thing)); */
        memset (thing, 0, sizeof(*thing));

        if (fscanf (file,"(%i,%i, %d) :%d, %d\n"
                ,&x, &y, &thing->angle, &thing->type, &thing->options) != 5)
                Error ("Failed ReadThing");

        thing->origin.x = x & -16;
        thing->origin.y = y & -16;

        return thing;
}

/*
==================
=
= LineOverlaid
=
= Check to see if the line is colinear and overlapping any previous lines
==================
*/

typedef struct
{
        float   left, right, top, bottom;
} bbox_t;

void BBoxFromPoints (bbox_t *box, NXPoint *p1, NXPoint *p2)
{
        if (p1->x < p2->x)
        {
                box->left = p1->x;
                box->right = p2->x;
        }
        else
        {
                box->left = p2->x;
                box->right = p1->x;
        }
        if (p1->y < p2->y)
        {
                box->bottom = p1->y;
                box->top = p2->y;
        }
        else
        {
                box->bottom = p2->y;
                box->top = p1->y;
        }
}

boolean LineOverlaid (worldline_t *line)
{
        int             j, count;
        worldline_t     *scan;
        divline_t       wl;
				bbox_t          linebox, scanbox;

        wl.pt = line->p1;
        wl.dx = line->p2.x - line->p1.x;
        wl.dy = line->p2.y - line->p1.y;

/*
        count = [linestore_i count];
        scan = [linestore_i elementAt:0];
*/
        count = linestore_i->count;
        scan = linestore_i->data;

        for (j=0 ; j<count ; j++, scan++)
        {
                if (PointOnSide (&scan->p1, &wl) != -1)
                        continue;
								if (PointOnSide (&scan->p2, &wl) != -1)
                        continue;
/* line is colinear, see if it overlapps */
                BBoxFromPoints (&linebox, &line->p1, &line->p2);
                BBoxFromPoints (&scanbox, &scan->p1, &scan->p2);

                if (linebox.right  > scanbox.left && linebox.left < scanbox.right)
                        return true;
                if (linebox.bottom < scanbox.top && linebox.top > scanbox.bottom)
                        return true;
        }
        return false;
}

/*
===================
=
= LoadDoomMap
=
===================
*/

/* id   linestore_i, thingstore_i; */

/* void LoadDoomMap (char *mapname) */
void LoadDoomMap(FILE *file)
{
/*      FILE            *file; */
/*				int                     i, version; */
				int	i;
				int                     linecount, thingcount;
				worldline_t     *line;
				worldthing_t *thing;

/*
				file = fopen (mapname,"r");
				if (!file)
								Error ("LoadDoomMap: couldn't open %s", mapname);
*/
/*
				if (!fscanf (file, "WorldServer version %d\n", &version) || version != 4)
								Error ("LoadDoomMap: not a version 4 doom map");
				printf ( "Loading version 4 doom map\n");
*/
/*
 read lines
*/
        if (fscanf (file,"\nlines:%d\n",&linecount) != 1)
                Error ("LoadDoomMap: can't read linecount");
        printf ("%i lines\n", linecount);
/*
        linestore_i = [[Storage alloc]
								initCount:              0
                elementSize:    sizeof(worldline_t)
                description:    NULL];
*/
        linestore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
        linestore_i->data = (worldline_t *)SafeCalloc(linecount,sizeof(worldline_t));
        linestore_i->size = sizeof(worldline_t);
				linestore_i->count = 0;

				line = linestore_i->data;
				printf("\n");
				for (i=0 ; i<linecount ; i++,linestore_i->count++,line++)
				{
/*              line = ReadLine (file); */
								printf("Reading line #%d\r",i);
								ReadLine(file,line);
								if (line->p1.x == line->p2.x && line->p1.y == line->p2.y)
								{
												printf ("WARNING: line %i is length 0 (removed)\n",i);
												continue;
								}

								if (LineOverlaid (line))
								{
												printf ("WARNING: line %i is overlaid (removed)\n",i);
												continue;
								}

/*
								[linestore_i addElement: line];
*/
/*
								linestore_i->count += 1;
								linestore_i->data = (worldline_t *)realloc(linestore_i->data,
																																																sizeof(worldline_t) * (linestore_i->count + 1));
								line = (worldline_t *)linestore_i->data + linestore_i->count;
*/
				}

/*
 read things
*/
        if (fscanf (file,"\nthings:%d\n",&thingcount) != 1)
                Error ("LoadDoomMap: can't read thingcount");
        printf ( "\n\n%i things\n", thingcount);
/*
        thingstore_i = [[Storage alloc]
                initCount:              0
                elementSize:    sizeof(worldthing_t)
                description:    NULL];
*/
        thingstore_i = (STORAGE *)SafeMalloc(sizeof(STORAGE));
        thingstore_i->data = (worldthing_t *)SafeCalloc(thingcount,sizeof(worldthing_t));
        thingstore_i->size = sizeof(worldthing_t);
        thingstore_i->count = thingcount;
/*
        for (i=0 ; i<thingcount ; i++)
                [thingstore_i addElement: ReadThing (file)];
*/
        thing = thingstore_i->data;
        for (i=0;i<thingcount;i++)
                {
                printf("Reading thing #%d\r",i);
                ReadThing(file,thing);
                thing++;
                }
/*
				fclose (file);
*/
}

