/* testedb.c -- this tests some of the empire database access functions */

#include <stdio.h>

#include "edbproc.h"
#include "edbpriv.h"
#include "misc.h"
#include "file.h"
#include "xy.h"
#include "nsc.h"
#include "genitem.h"
#include "edb.h"
#include "collect.h"

#define BUFSZ 1024

/* these functions are not really supposed to be supported, but may be useful */
#ifdef Debug
extern void dumpUnknownTypes(Empire_Database *);
#endif
extern void dumpDict(Empire_Database *);
extern void dumpObject(Empire_Database *edb, void *thing);

char *coordString(int x, int y)
{
	static char buf[100];
	static char *p = buf;
	char *q;
	if (p>=buf+sizeof(buf)-10) p = buf;
	sprintf(p,"%d,%d", x, y);
	q = p;
	p += strlen(p)+1;
	return q;
}

char sectorDes(Empire_Database *edb, int descode)
{
	struct dchrstr *bld;
	bld = edb_getSectorBuild(edb, descode);
	return bld->d_mnem &0x7f;	
}


void showOneSectorBuild(void *context, void *object)
{
	Empire_Database *edb;
	int i,n;
	struct dchrstr *p;
	edb = (Empire_Database *) context;
	p = (struct dchrstr *) object;	
	printf("%-20s %c %3d mcost %3d off %3d def\n",
		p->d_name, p->d_mnem, p->d_mcst, p->d_ostr, p->d_dstr);
}


void showOneSector(void *context, void *object)
{
	Empire_Database *edb;
	int i,n;
	struct sctstr *sp, *q;
	edb = (Empire_Database *) context;
	sp = (struct sctstr *) object;	
	printf("%3d,%3d %c %3d %3d %3d %3d %3d\n",
		sp->sct_x, sp->sct_y, 
		sectorDes(edb, sp->sct_type),
		sp->sct_effic,
		sp->sct_min, sp->sct_gmin, 
		sp->sct_fertil, sp->sct_oil );
	q = edb_getSector(edb, sp->sct_x, sp->sct_y);
	if (q!=sp) {
		printf("edb_getSector failed for %s\n",
			coordString(sp->sct_x, sp->sct_y) );
	}
}

char *unitName(Empire_Database *edb, int unitCode)
{
	struct lchrstr *p;
	p=edb_getLandBuild(edb,unitCode);
	return p->l_name;
}

void showOneUnitType(void *context, void *object)
{
	Empire_Database *edb;
	int i,n;
	struct lchrstr *p;
	edb = (Empire_Database *) context;
	p = (struct lchrstr *) object;	
	printf("%-24s %3d lcm %3d hcm %3d guns %3d shells %3d tech $%4d\n",
		p->l_name, p->l_lcm, p->l_hcm, 
		p->l_gun, p->l_shell, p->l_tech,
		p->l_cost );
}

void showOneUnit(void *context, void *object)
{
	Empire_Database *edb;
	int i,n;
	struct lndstr *p, *q;
	edb = (Empire_Database *) context;
	p = (struct lndstr *) object;	
	printf("Unit #%3d at %-5s %-20s %3d%% eff %3d mob\n",
		p->lnd_uid,
		coordString(p->lnd_x,p->lnd_y),
		unitName(edb, p->lnd_type),
		p->lnd_effic,
		p->lnd_mobil);
	q = edb_getLand(edb, p->lnd_uid);
	if (q!=p) {
		printf("edb_getLand failed for %s\n", p->lnd_uid );
	}
}

void showAll(void *context, void *object)
{
	Empire_Database *edb;
	edb = (Empire_Database *) context;
	dumpObject(edb, object);
}

void dumpGlobals(Empire_Database *edb)
{
	Country *c;
	Version *v;
	printf("\nCountry Info\n\n");
	c = edb_getCountry(edb);
	dumpObject(edb, c);
	printf("\nVersion Info\n\n");
	v = edb_getVersion(edb);
	dumpObject(edb, v);
}




struct DumpTable {
	char *heading;
	EmpireObjectType obj;
	Edb_CallBack dumpfunc;
};

struct DumpTable things[] = {
	{ "Sector Build", V_Sector_Build,  showOneSectorBuild },
	{ "Sectors",      V_Sector_Data,   showOneSector },
	{ "UnitTypes",    V_Land_Build,    showOneUnitType },
	{ "Units",        V_Land_Data,     showOneUnit },
	{ "Nuke Build",   V_Nuke_Build,    showAll },
	{ "Nukes",        V_Nuke_Data,     showAll },
	{ "Planes Build", V_Plane_Build,   showAll },
	{ "Planes",       V_Plane_Data,    showAll },
	{ "Items",        V_Item_Class,    showAll },
	{ "Products",     V_Product_Class, showAll },
	{ 0, 0, NULL} };


Empire_Database *edb = 0;
int debug = 0;

char *defaultInput = "csync.dat";
char *fname = 0;
	
int parseArgs(int argc, char **argp)
{
	int i;
	char c, *p;
	for (i=1;i<argc;i++) {
		p = argp[i];
		if (*p == '-') {
		    p++;
		    while ((c=*p++)!=0) {
		    	switch (c) {
		    	    case 'd':
		    	    	debug++;
		    	    	break;
		    	    default:
		    	    	perror("bad command line arg");
		    	}
		    }
		}
		else if (fname)
			perror("too many arguments");
		else
		    fname = p;
	}

}

int main(int argc, char **argp)
{
	FILE *f;
	char buf[BUFSZ];
	struct DumpTable *p;

	parseArgs(argc, argp);

	if (!fname) fname = defaultInput;	
	f = fopen(fname,"r+");
	if (!f) {
		perror("cannot open csync.dat");
		exit(1);
	}
	edb = edb_new();
	while (fgets(buf, BUFSZ, f)) {
		edb_parse_c_sync(edb, buf);
	}
	fclose(f);

	dumpGlobals(edb);

/*
	dumpDict(edb);
*/

/*
	Dump out everything in the database
*/

	for (p=things;p->heading;p++) {
		printf("\n%s\n", p->heading);
		edb_enumerate(edb, p->obj, p->dumpfunc, edb);
	}

#ifdef Debug
	dumpUnknownTypes(edb);
#endif
	
	return 0;
}
