
#ifndef __tagprivate_h__
#define __tagprivate_h__

#include <XFile.h>

#define DATUM_HEADER \
	short identifier

enum
{
	TAG_NAME_LENGTH= 31,
	TAG_FILE_NAME_LENGTH= 31,
	ENTRY_POINT_NAME_LENGTH= 63,
	TAG_FILE_URL_LENGTH= 63,

	MAXIMUM_ENCODED_PLUGIN_BUFFER_SIZE= 512,
	MAXIMUM_ENCODED_PLUGINS= 16, // i.e., maximum user-selectable plugins
	MAXIMUM_PATCH_VERSION= 16,
	MAXIMUM_PLUGIN_INDEXES= 256,
	PATCH_VERSION = 0x00000102
};

enum // tag file type
{
	// in the case of both plugin and foundation files, there needs to be a way to specify which
	// files are loaded in what order (plugins are user-configurable, the foundation is not).

	// preferences, saved games, recordings, etc. are each in a separate folder at
	// application root, but are still local.  all other local tags are placed in the
	// local folder within their appropriate subgroup folder.  local folders are
	// disabled during netgames.
	_tag_file_type_local,

	// these are preprocessed modifications or additions to the foundation (always monolithic).
	// these can be game-critical or not, depending on whether or not any of the tags they
	// contain are marked as such.  the PG version will be implemented by a plugin which
	// will not be game-critical.  patches are the same thing except they are not optional (i.e.,
	// a patch which is present must be loaded)
	_tag_file_type_plugin,
	_tag_file_type_patch,

	// these are the bungie shipping tags which can never be removed (always monolithic)
	// at least one of these is devoted to things which will be internationalized and do not
	// have any effect on the game (the interface).  only foundation tag files can be found
	// on the shipping CD.
	_tag_file_type_foundation,

	_tag_file_type_cache,

	NUMBER_OF_TAG_FILE_TYPES
};

enum // foundation tag files (copies on the hard drive are used before copies on the cd)
{
	_foundation_tag_file_small, // all the small tags (always installed)
	_foundation_tag_file_medium, // medium install
	_foundation_tag_file_large, // big single-shot things like premap screens and color maps (large install)
	_foundation_tag_file_small_interface, // all text and common interface artwork which need to be internationalized
	_foundation_tag_file_large_interface, // all big art files which need to be internationalized (large install)
	NUMBER_OF_FOUNDATION_TAG_FILES,

	// set bits represent foundation files without which the game cannot launch
	REQUIRED_FOUNDATION_TAG_FILE_FLAGS= 0
};

struct tag_file_header
{
	short type; // foundation, plugin or patch
	short version; // only important if this is a patch

	char name[TAG_FILE_NAME_LENGTH+1]; // taken from the filename, like local tags
	char url[TAG_FILE_URL_LENGTH+1]; // added during the file's creation

	short entry_point_count;
	short tag_count;
	unsigned long checksum;
	unsigned long flags;
	long size; // of entire file, including this header (zero until header is rewritten)

	unsigned long header_checksum; // with this field set to zero

	long unused[1];

	tag signature;

	// entry points
	// tag headers
};

struct tag_file_entry_point
{
	tag subgroup_tag;
	long team_count;

	long unused[1];

	unsigned long user_data;
	char name[TAG_FILE_NAME_LENGTH+1];

	char printed_name[ENTRY_POINT_NAME_LENGTH+1];
};


struct tag_header // 64 bytes
{
	DATUM_HEADER;
	byte flags;
	char type;

	char name[TAG_FILE_NAME_LENGTH+1];

	tag group_tag;
	tag subgroup_tag;
	long offset, size; // actual offset in the file, whether single or monolithic
	
	unsigned long user_data; // user defined
	short version; // user defined

	char foundation_tag_file_index; // where a tag will get put when the monolithic files are built
	char owner_index; // lower is more important (NONE means local folder); invalid on disk

	tag signature; // always 'blam'
};




struct tag_entry
{
	tag_entry *next, *prev;
	
	char name[TAG_NAME_LENGTH+1];
	tag_file *file;
	tag_group *group;
	tag id;
	unsigned offset;
	unsigned length;
	short version;
	bool dirty;
	const void *data;
	
	TTagEditForm *form;
};


enum tag_destination_type {
	_destination_small_install,
	_destination_large_install
};

enum tag_localization_type {
	_tag_universal,
	_tag_localized
};


struct tag_type_info {
	tag type;
	short version;	// important!
	const char *singular;
	const char *plural;
	tag_localization_type default_localization;
	tag_editor_proc editor;
	tag_editor_proc mod_key_editor;
	tag_creator_proc creator;
	tag_dependency_proc dependencies;
	tag_updater_proc updater;
};


struct tag_group
{
	tag_group *next, *prev;
	
	tag type;
	tag_entry *entries;
	tag_type_info *info;
	tag_file *file;
};


struct tag_file
{
	tag_file *next, *prev;
	tag_group *groups;
	
	XGFileSpecifier *filespec;
	bool readonly;
	
	bool needupdate;
	bool needrewrite;

	int loaded_type;
	int patch_version;
	
	TTagFileForm *form;
};

extern tag_type_info tagtypelist[];
tag_type_info *typeinfo( tag type );

extern tag_file *tag_file_list;

#endif

