#include <stdio.h>
#include <stdlib.h>

#define INTEL

typedef unsigned char BYTE;

typedef long int int32;

typedef struct {
	int32 offset;
	int32 size;
} lump;

int32 littlelong(int32 l) {
#ifdef INTEL
	return l;
#else
	BYTE    b1,b2,b3,b4;

	b1 = l&255;
	b2 = (l>>8)&255;
	b3 = (l>>16)&255;
	b4 = (l>>24)&255;

	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
#endif
}

int32 biglong(int32 l) {
#ifndef INTEL
	return l;
#else
	BYTE    b1,b2,b3,b4;

	b1 = l&255;
	b2 = (l>>8)&255;
	b3 = (l>>16)&255;
	b4 = (l>>24)&255;

	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
#endif
}

#define NUMLUMPS 15

void main(int argc, char **argv) {
	int loop;
	int32 temp;
	lump lumps[15];
	BYTE *lumpdat[15];
	BYTE null=0;
	FILE *in,*out;
	if (argc != 2) {
		printf("Error, usage \"bspalign <bspfile>\"\n");
		exit(-1);
	}
	in=fopen(argv[1],"r+b");
	if (!in) {
		printf("Error opening input file!\n");
		exit(-1);
	}
	out=tmpfile();
	if (!out) {
		printf("Error opening temporary file!\n");
		exit(-1);
	}
	fread(&temp,sizeof(temp),1,in); //version number
	printf("File \"%s\" opened, BSP version %d\n",argv[1],littlelong(temp));
	fwrite(&temp,sizeof(temp),1,out);
	for (loop=0; loop < NUMLUMPS; loop++) {
		fread(&lumps[loop].offset,sizeof(int32),1,in);
		fread(&lumps[loop].size,sizeof(int32),1,in);
		lumps[loop].offset = littlelong(lumps[loop].offset);
		lumps[loop].size = littlelong(lumps[loop].size);
		printf("Lump %2d header read, offset %10d, size %10d\n",loop,lumps[loop].offset,lumps[loop].size);
	} //ok, finished with the header
	for (loop=0; loop < NUMLUMPS; loop++) {
		printf("Reading lump %d\n",loop);
		fseek(in,lumps[loop].offset,SEEK_SET);
		lumpdat[loop] = (BYTE*)malloc(lumps[loop].size);
		fread(lumpdat[loop],lumps[loop].size,1,in);
	}
	printf("Writing dummy header\n");
	for (loop=0; loop < NUMLUMPS; loop++) {
		lumps[loop].offset = littlelong(lumps[loop].offset);
		lumps[loop].size = littlelong(lumps[loop].size);
		fwrite(&lumps[loop].offset,sizeof(int32),1,out);
		fwrite(&lumps[loop].size,sizeof(int32),1,out);
		lumps[loop].offset = littlelong(lumps[loop].offset);
		lumps[loop].size = littlelong(lumps[loop].size);
	}
	for (loop=0; loop < NUMLUMPS; loop++) {
		printf("Writing lump %d to tempfile\n",loop);
		while (ftell(out)&3) fwrite(&null,1,1,out);
		lumps[loop].offset = ftell(out);
		fwrite(lumpdat[loop],lumps[loop].size,1,out);
		free(lumpdat[loop]);
	}
	fseek(in,sizeof(int32),SEEK_SET);
	fseek(out,sizeof(int32),SEEK_SET); //skip version number
	printf("Writing new header\n");
	for (loop=0; loop < NUMLUMPS; loop++) {
		lumps[loop].offset = littlelong(lumps[loop].offset);
		lumps[loop].size = littlelong(lumps[loop].size);
		fwrite(&lumps[loop].offset,sizeof(int32),1,in);
		fwrite(&lumps[loop].size,sizeof(int32),1,in);
		lumps[loop].offset = littlelong(lumps[loop].offset);
		lumps[loop].size = littlelong(lumps[loop].size);
	}
	for (loop=0; loop < NUMLUMPS; loop++) {
		printf("Writing lump %d back to file\n",loop);
		fseek(in,lumps[loop].offset,SEEK_SET);
		fseek(out,lumps[loop].offset,SEEK_SET);
		lumpdat[loop] = (BYTE*)malloc(lumps[loop].size);
		fread(lumpdat[loop],lumps[loop].size,1,out);
		fwrite(lumpdat[loop],lumps[loop].size,1,in);
		free(lumpdat[loop]);
	}
	
	if (fclose(in)) printf("Error closing BSP, how odd.\n");
	if (fclose(out)) printf("Couldn't close temp file.  Umm, that's usually bad.\n");


}