//
// BZ2 Network Manager (MPVehicles) .cpp source code
//
// Subsection: Code that reads in the MPVehicles.txt file 
//
// Copyright 1998 Pandemic Studios, LLC
//
// NM 8/14/98

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include "..\Shared\DLLBase.h"
#include "MPVehicles.h"

namespace MPVehicleManager {
	// Max # of vehicles that can be in the list. Do *NOT* put this over
	// 32 without expanding the # of bits used to send this across the
	// network. ivar4 is used to encode this
	const int MAX_MP_VEHICLES=32;

		// Max name of an XSI filename
	const U32 MAX_MP_XSINAMELEN=64;
	// Max name of an ODF filename
	const U32 MAX_MP_ODFNAMELEN=16;
	// Max string len of the ascii description of a vehicle
	const U32 MAX_MP_DESCNAMELEN=128;

	struct OneMPVehicle {
		char XSIName[MAX_MP_XSINAMELEN];
		char ODFName[MAX_MP_ODFNAMELEN];
		char DescName[MAX_MP_DESCNAMELEN];
	};

	// Read in list of things
	OneMPVehicle MPVehicleList[MAX_MP_VEHICLES];
	// Size of the above array.
	int NumMPVehicleEntries=0;

	static bool Initialized=false;
	// Read in and initialize the list of vehicles
	void Init(void)
		{
			if(Initialized)
				return;

			// Ensure everything cleared before reading
			NumMPVehicleEntries=0;
			memset(MPVehicleList,0x00,sizeof(MPVehicleList));

			FILE *fp;
			fp=fopen("MPVehicles.txt","r");
			if(!fp) {
				assert(0);
				return; // Can't find vehicle list file. Bug out.
			}

			// Biggest line we can read at once out of file
			const int MAX_MPV_LINE_LEN=1024;
			char CurLine[MAX_MPV_LINE_LEN+2];
			bool GotLine;
			int Offset,Offset2,CopyLen;

			// Slurp in lines until eof
			while (fgets(CurLine,MAX_MPV_LINE_LEN,fp)!=NULL) {
				GotLine=false;
				if((strlen(CurLine)>3) && (CurLine[0]!='/') && (CurLine[1]!='/')) {
					Offset=0;
					U32 LineLen=strlen(CurLine);
					if((CurLine[LineLen-1]=='\n') || (CurLine[LineLen-1]=='\r'))
						CurLine[LineLen-1]='\0'; // trim off newline

					// Find space delimiter to end of xsi name
					while((CurLine[Offset]!=' ') && (CurLine[Offset]!='\0'))
						Offset++;
					CopyLen=Offset;
					if(CopyLen>(MAX_MP_XSINAMELEN-1))
						CopyLen=MAX_MP_XSINAMELEN-1;
					strncpy(MPVehicleList[NumMPVehicleEntries].XSIName,CurLine,CopyLen);

					// Skip forward over spaces
					while(CurLine[Offset]==' ')
						Offset++;
					Offset2=Offset; // Store top of odf
					while((CurLine[Offset]!=' ') && (CurLine[Offset]!='\0'))
						Offset++;
					CopyLen=Offset-Offset2;
					if(CopyLen>(MAX_MP_ODFNAMELEN-1))
						CopyLen=MAX_MP_ODFNAMELEN-1;
					strncpy(MPVehicleList[NumMPVehicleEntries].ODFName,CurLine+Offset2,CopyLen);

					// Skip forward over spaces
					while(CurLine[Offset]==' ')
						Offset++;
					strncpy(MPVehicleList[NumMPVehicleEntries].DescName,CurLine+Offset,MAX_MP_DESCNAMELEN);
						
					if((strlen(MPVehicleList[NumMPVehicleEntries].XSIName)>4) &&
						 (strlen(MPVehicleList[NumMPVehicleEntries].ODFName)>4) &&
						 (strlen(MPVehicleList[NumMPVehicleEntries].DescName)>0))
						GotLine=true;
					// Ensure the odf exists
				}

				// Advance on to next entry if successful
				if((GotLine) && (NumMPVehicleEntries<MAX_MP_VEHICLES))
					NumMPVehicleEntries++;
			} // While loop going over lines

			fclose(fp);
			Initialized=true;
		}

	// Do any memory cleanups necessary
	void Cleanup(void)
		{
			// Do nothing for now; have a static array above
		}

	// Given a bitfield (hopefully only 1 bit on) saying which vehicle
	// is present, return the odf for that slot
	char *GetVehicleODFFromBitfield(unsigned long Bits)
		{
			// Find first bit set on, and return slot for that
			for(int i=0;i<NumMPVehicleEntries;i++)
				if(Bits & (1<<i)) {
					return MPVehicleList[i].ODFName;
				}
			return "player"; // Default; this BETTER be present
		}

	// Load/save the read-in list of vehicles out to disk
	void Save(bool MissionSave)
		{
			if (MissionSave)
				return;

			Write(&NumMPVehicleEntries,1);
			for(int i=0;i<NumMPVehicleEntries;i++) {
				Write(MPVehicleList[i].ODFName,sizeof(MPVehicleList[i].ODFName));
			}

		}

	void Load(bool MissionSave)
		{
			if (MissionSave)
				return;

			Read(&NumMPVehicleEntries,1);
			for(int i=0;i<NumMPVehicleEntries;i++) {
				Read(MPVehicleList[i].ODFName,sizeof(MPVehicleList[i].ODFName));
			}
		}


} // 	namespace MPVehicleManager
