#ifndef __EDBPROC_H__
#define __EDBPROC_H__

#define NoSysFuncs
#undef Debug
#define TOOLKIT
#include "prototype.h"
#include "misc.h"
#include "collect.h"
#include "index.h"
#include "ship.h"
#include "land.h"
#include "plane.h"
#include "sect.h"
#include "nuke.h"
#include "item.h"
#include "product.h"
#include "other.h"

/* these typedefs are for convenience */

typedef struct plnstr Plane;
typedef struct plchrstr Plane_Build;
typedef struct shpstr Ship;
typedef struct mchrstr Ship_Build;
typedef struct lndstr Land;
typedef struct lchrstr Land_Build;
typedef struct nukstr Nuke;
typedef struct nchrstr Nuke_Build;
typedef struct sctstr Sector;
typedef struct dchrstr Sector_Build;
typedef struct natstr Country;
typedef struct cmapstr Cmap;
typedef struct bmapstr Bmap;
typedef struct gameinfo Version;


typedef struct pchrstr Product_Class;
typedef struct ichrstr Item_Class;

typedef struct EDB_Str {
	/* all of these should probably be private to the database manager */
	/* do not reference them directly from your program 		   */
	/* Use the various access routines instead... */
	
	Collection *plane_build, *land_build, *ship_build,
		    *sector_build, *nuke_build,
		   *item_class, *product_class;
	Collection *plane_data,  *land_data,  *ship_data,
		   *sector_data, *nuke_data;
	Index      *plane_data_index,  *land_data_index, 
		   *ship_data_index,   *sector_data_index,
		   *nuke_data_index,
	           *plane_build_index, *land_build_index, 
		   *ship_build_index,  *sector_build_index,
		   *nuke_build_index, 
		   *item_class_index,  product_class_index;
	Collection *game_data;
	Index	   *game_data_index;
	Collection *bmap_data;
	Index	   *bmap_data_index;
	Collection *map_data;
	Index	   *map_data_index;
	Collection *country_data;
	Index      *country_data_index;
	void *dictionary;	/* opaque to client */
} Empire_Database;


typedef struct {
	/* all of these should probably be private to the database manager */
	/* do not reference them directly from your program */
	struct genobject **results;
	int nresults;
	int cursor;
} Empire_Query;

typedef enum { V_Plane_Build, V_Land_Build, V_Ship_Build, V_Sector_Build, V_Nuke_Build,
	       V_Plane_Data,  V_Land_Data,  V_Ship_Data,  V_Sector_Data, V_Nuke_Data,
	       V_Item_Class, V_Product_Class,
	       V_Cmap_Data, V_Bmap_Data,
	       V_Country_Data, V_Version_Data
	     } EmpireObjectType;

typedef int (*Edb_ReadFunc) _PROTO((char *, int, int *));   /* buf, len, bytesread */
typedef int (*Edb_WriteFunc) _PROTO((char *, int, int *));  /* buf, len, byteswritten */
typedef void (*Edb_CallBack) _PROTO(( void *, void * ));    /* context, object */

#ifdef __cplusplus
extern "C" {

#endif


/* edb_new -- allocate a new database control structure */
Empire_Database *edb_new();

/* edb_delete -- destroy a database control structure and substructures */
void edb_delete(Empire_Database *);

/* High level functions to save/load the entire database... */
/* You supply the read/write function                       */


/* edb_save -- save the database */
int edb_save(Empire_Database  *edb, Edb_WriteFunc func);

/* edb_load -- load the database */
int edb_load(Empire_Database *edb, Edb_ReadFunc func);


/*  High level database query functions  */


/* edb_new_query -- perform a query operation on empire database */
Empire_Query *edb_new_query(Empire_Database *edb, char *query);

/* edb_first_item -- get first item in query result set */
void *edb_first_item(Empire_Query *eq);

/* edb_next_item -- get next item in query result set */
void *edb_next_item(Empire_Query *eq);

/* edb_free_query -- dispose of query result set */
void edb_free_query(Empire_Query *eq);



/* Low level database query functions */


/* edb_getPlaneBuild -- retrieve info about a particular plane type */
Plane_Build *edb_getPlaneBuild(Empire_Database *edb, int planeType);

/* edb_getLandBuild -- retrieve info about a particular land type */
Land_Build *edb_getLandBuild(Empire_Database *edb, int landType);

/* edb_getShipBuild -- retrieve info about a particular ship type */
Ship_Build *edb_getShipBuild(Empire_Database *edb, int shipType);

/* edb_getNukeBuild -- retrieve info about a particular nuke type */
Nuke_Build *edb_getNukeBuild(Empire_Database *edb, int nukeType);

/* edb_getSectorBuild -- retrieve info about a particular sector type */
Sector_Build *edb_getSectorBuild(Empire_Database *edb, int sectType);

/* edb_getItemClass -- retrieve info about a particular commod */
Item_Class *edb_getItemClass(Empire_Database *edb, int itemType);

/* edb_getProductClass -- retrieve info about a particular product */
Product_Class *edb_getProductClass(Empire_Database *edb, int productType);

/* edb_getPlane -- retrieve info about a particular plane */
Plane  *edb_getPlane(Empire_Database *edb, int planeNo);

/* edb_getLand -- retrieve info about a particular land unit */
Land   *edb_getLand(Empire_Database *edb, int unitNo);

/* edb_getShip -- retrieve info about a particular ship */
Ship   *edb_getShip(Empire_Database *edb, int shipNo);

/* edb_getNuke -- retrieve info about a particular nuke */
Nuke   *edb_getNuke(Empire_Database *edb, int nukeNo);

/* edb_getSector -- retrieve info about a particular sector */
Sector *edb_getSector(Empire_Database *edb, int x, int y);

/* edb_getCountry -- retrieve country info */
Country *edb_getCountry(Empire_Database *edb);

/* edb_getVersion -- retrieve game version info */
Version *edb_getVersion(Empire_Database *edb);

/* edb_getMap -- retrieve map info */
Cmap *edb_getCmap(Empire_Database *edb, int x, int y);

/* edb_getBmap -- retrieve map info */
Bmap *edb_getBmap(Empire_Database *edb, int row);

/* edb_enumerate -- enumerate all of a particular type of thing */
void edb_enumerate(Empire_Database *edb, EmpireObjectType itemType,
		   Edb_CallBack func, void *context);


/* edb_parse_c_sync -- process a C_SYNC message and update the database */
void edb_parse_c_sync(Empire_Database *edb, s_char *msg);

/* edb_print_c_sync -- construct C_SYNC message for an object */
void edb_print_c_sync(Empire_Database *edb, s_char *buf, void *object);


#ifdef __cplusplus
}
#endif

#endif
