/*
				FUNCS.C - functions for reading the WAD file and writing the DWD file
*/
#include "wad_dwd.h"

int ParseSpecificLevels(char *arg, char *levels[])
{
	int count = 0;
	int i;

	if ((strlen(arg)) <= 7)
		Error("\nNo values given for -level directive\n");

	if (!strchr(arg, ','))
		levels[count++] = arg + 7;
	else
	{
		levels[count++] = strtok(arg + 7, ",");
		while (levels[count++] = strtok(NULL, ","))
			if (count > MAX_SPECIFIC)
				break;
		--count;
	}

	return count;
}

boolean TestSpecificLevel(char *lev, char *levels[], int num)
{
	int i;
	for (i = 0; i < num; ++i)
		if (!strcmp(lev, levels[i]))
			return true;

	return false;
}

void *ReadWAD(FILE *f, long num, size_t size)
{
	int numread;
	void *p;

	p = (void *)SafeCalloc(num, size);
	if ((numread=fread(p, size, num, f)) != num)
		{
		free(p);
		Error("ReadWAD: read only %d of intended %d items\n",numread, num);
		}

	return p;
}

void *ReadStorage(FILE *f, lumpinfo_t *dir, long *num, size_t size)
{
	fseek(f, dir->filepos, SEEK_SET);
	*num = dir->size / size;

	return ReadWAD(f, *num, size);
}

#if 0
void WriteSideAndSector(FILE *f, mapsidedef_t *s, mapsector_t *sec)
{
	char topt[9], bott[9], midt[9], fpic[9], cpic[9];

	strncpy(topt, s->toptexture, 8);
	topt[8] = '\0';
	strncpy(bott, s->bottomtexture, 8);
	bott[8] = '\0';
	strncpy(midt, s->midtexture, 8);
	midt[8] = '\0';
	strncpy(fpic, sec->floorpic, 8);
	fpic[8] = '\0';
	strncpy(cpic, sec->ceilingpic, 8);
	cpic[8] = '\0';
/*
	fprintf(f, "    %d (%d : %s / %s / %s )\n",
					s->textureoffset, s->rowoffset, topt, bott, midt);
*/
	fprintf(f, "    %d (%d : %s / %s / %s )\n",
					s->rowoffset, s->textureoffset, topt, bott, midt);

	fprintf(f, "    %d : %s %d : %s %d %d %d\n",
					sec->floorheight, fpic, sec->ceilingheight,
					cpic, sec->lightlevel, sec->special, sec->tag);
}
#endif

void WriteSide(FILE *f, mapsidedef_t *s)
{
	char topt[9], bott[9], midt[9];

	strncpy(topt, s->toptexture, 8);
	topt[8] = '\0';
	strncpy(bott, s->bottomtexture, 8);
	bott[8] = '\0';
	strncpy(midt, s->midtexture, 8);
	midt[8] = '\0';

	fprintf(f, "    %d (%d : %s / %s / %s ) %d\n",
					s->rowoffset, s->textureoffset, topt, bott, midt, s->sector);
}

void WriteSector(FILE *f, mapsector_t *sec)
{
	char fpic[9], cpic[9];

	strncpy(fpic, sec->floorpic, 8);
	fpic[8] = '\0';
	strncpy(cpic, sec->ceilingpic, 8);
	cpic[8] = '\0';

	fprintf(f, "%d : %s %d : %s %d %d %d\n",
					sec->floorheight, fpic, sec->ceilingheight,
					cpic, sec->lightlevel, sec->special, sec->tag);
}

void WriteSectors(FILE *f, long num, mapsector_t *s)
{
	int i;

	fprintf(f,"sectors:%d\n",num);
	for (i=0; i<num; i++, s++)
		WriteSector(f, s);
}

/*
void WriteLines(FILE *f, long num, maplinedef_t *lines, mapvertex_t *vertexes,
								mapsidedef_t *sides, mapsector_t *sectors)
*/
void WriteLines(FILE *f, long num, maplinedef_t *lines, mapvertex_t *vertexes,
								mapsidedef_t *sides)
{
	int i;
	mapsidedef_t *s;
	maplinedef_t *l;

	l = lines;
	fprintf(f,"\nlines:%d\n",num);

	for (i=0; i<num; i++, l++)
		{
		fprintf(f, "(%d,%d) to (%d,%d) : %d : %d : %d\n",
						vertexes[l->v1].x, vertexes[l->v1].y,
						vertexes[l->v2].x, vertexes[l->v2].y,
						l->flags, l->special, l->tag);
		s = &sides[l->sidenum[0]];
/*		WriteSideAndSector(f, s, &sectors[s->sector]); */
		WriteSide(f, s);
		if (l->flags & ML_TWOSIDED)
			{
			s = &sides[l->sidenum[1]];
/*			WriteSideAndSector(f, s, &sectors[s->sector]); */
			WriteSide(f, s);
			}
		}
}


void WriteThings(FILE *f, long num, mapthing_t *t)
{
	int i;

	fprintf(f,"\nthings:%d\n",num);
	for (i=0; i<num; i++, t++)
		fprintf(f, "(%i,%i, %d) :%d, %d\n", t->x, t->y, t->angle, t->type, t->options);
}

void WriteHeader(FILE *f)
{
	fprintf(f, "WorldServer version 4\n");
}

void ExtractResource(FILE *f, lumpinfo_t *l)
{
	FILE *d;
	char fname[12];
	void *p;
	long num;

  if (!l->size)
    return;

	memset(fname, 0, sizeof(fname));
	strncpy(fname, l->name, 8);
	strcat(fname, ".lmp");

	if ((d=fopen(fname,"wb")) == NULL)
		Error("Could not extract %s", fname);

	p = (void *)ReadStorage(f, l, &num, l->size);

	fwrite(p, l->size, 1, d);
	fclose(d);
	free(p);
}

void ExtractLevel(FILE *wad, FILE *dwd, lumpinfo_t *l)
{
	mapvertex_t *vertexes = NULL;
	mapsidedef_t *sidedefs = NULL;
	maplinedef_t *linedefs = NULL;
	mapsector_t *sectors = NULL;
	mapthing_t *things = NULL;
	long numthings, numvertexes, numlines, numsides, numsectors;

	things = (mapthing_t *)ReadStorage(wad, ++l, &numthings, sizeof(mapthing_t));
	linedefs = (maplinedef_t *)ReadStorage(wad, ++l, &numlines, sizeof(maplinedef_t));
	sidedefs = (mapsidedef_t *)ReadStorage(wad, ++l, &numsides, sizeof(mapsidedef_t));
	vertexes = (mapvertex_t *)ReadStorage(wad, ++l, &numvertexes, sizeof(mapvertex_t));
	l += 4;
	sectors = (mapsector_t *)ReadStorage(wad, l, &numsectors, sizeof(mapsector_t));
	WriteSectors(dwd, numsectors, sectors);
	WriteLines(dwd, numlines, linedefs, vertexes, sidedefs);
	WriteThings(dwd, numthings, things);
	free(vertexes);
	free(sidedefs);
	free(linedefs);
	free(sectors);
}