#ifndef DOOM
#define DOOM

#ifdef __TSC__
#pragma link (doom)
#endif

#include <windows.h>

// Helper functions for reading large blocks of data.
DWORD lread (int FileHandle,VOID FAR * pv,DWORD ul);
DWORD lwrite (int FileHandle,VOID FAR * pv,DWORD ul);


struct Header
{
	char	Signature [4];
	long 	NumberOfEntries;
	long  	DirectoryPointer;
};


struct DirectoryEntry
{
	long	ResourcePointer;
	long 	ResourceSize;
	char	ResourceName [8];
};


struct Thing
{
	int		X;
	int		Y;
	int		Angle;
	int		Type;
	int		Bitset;
};


struct Vertex
{
	int		X;
	int		Y;
};


struct LineDef
{
	int		FromVertex;
	int		ToVertex;
	int		Bitset;
	int		Types;
	int		Trigger;
	int		Sidedef1;
	int		Sidedef2;
};


struct SideDef
{
	int		X;
	int		Y;
	char	Above [8];
	char	Below [8];
	char	Wall [8];
	int		Sector;
};


struct Sector
{
	int		FloorHeight;
	int		CeilingHeight;
	char	FloorTexture [8];
	char	CeilingTexture [8];
	int		Brightness;
	int		Special;
	int		Trigger;
};


struct Seg
{
	int		FromVertex;
	int		ToVertex;
	int		Angle;
	int		Linedef;
	int		Direction;
	int		Distance;
};


struct SSector
{
	int		NoOfSegs;
	int		StartSeg;
};


struct Node
{
	int		XStart;
	int		YStart;
	int		XOffset;
	int		YOffset;
	int		YSQ1Right1;
	int		YSQ1Right2;
	int		XSQ1Right1;
	int		XSQ1Right2;
	int		YSQ2Right1;
	int		YSQ2Right2;
	int		XSQ2Right1;
	int		XSQ2Right2;
	int		Bitset1;
	int		Bitset2;
};


class DoomObject
{
	public:
		DoomObject ();
		~DoomObject ();
		DoomObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		
	public:
		int		NoOfObjects;
		int		NoOfSpareObjects;
		HANDLE	MemHandle;
		char *	MemPointer;
};


class DoomThingObject : public DoomObject
{
	public:
		DoomThingObject ();
		DoomThingObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		int Add (int EntryNo,int X,int Y);
		void Delete (int EntryNo);
		
	public:
		Thing *		Data;
};


class DoomVertexObject : public DoomObject
{
	public:
		DoomVertexObject ();
		DoomVertexObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		int Add (int X,int Y);
		void Delete (int EntryNo);
		
	public:
		Vertex *	Data;
};


class DoomSideDefObject : public DoomObject
{
	public:
		DoomSideDefObject ();
		DoomSideDefObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		int Add ();
		void Delete (int EntryNo);
		
	public:
		SideDef *	Data;
};


class DoomLineDefObject : public DoomObject
{
	public:
		DoomLineDefObject ();
		DoomLineDefObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		int Add (int FromVertex,int ToVertex);
		void Delete (int EntryNo);
		
	public:
		LineDef *	Data;
};


class DoomSectorObject : public DoomObject
{
	public:
		DoomSectorObject ();
		DoomSectorObject (int FileHandle,DirectoryEntry * Entry);
		virtual void SaveObject (int FileHandle,DirectoryEntry * Entry);
		int Add ();
		void Delete (int EntryNo);
		
	public:
		Sector *	Data;
};


// These allow easy across across the objects. Good for control !
extern DoomVertexObject *		VertexPointer;
extern DoomLineDefObject *		LineDefPointer;
extern DoomThingObject *		ThingPointer;
extern DoomSideDefObject *		SideDefPointer;
extern DoomSectorObject *		SectorPointer;

#endif
