roh/conf/area/
roh/game/talk/
roh/help/
roh/monsters/ocean/
roh/objects/ocean/
roh/player/
roh/rooms/area/1/
roh/rooms/misc/
roh/rooms/ocean/
roh/src-2.44b/
/*
 * xml.h
 *	 Prototypes and anything global needed to read/write xml files
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License
 *    http://creativecommons.org/licenses/by-nc-sa/3.0/
 *
 * 	Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell
 * 	   Contributions by Tim Callahan, Jonathan Hseu
 *  Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman
 *
 */

#ifndef XML_H_
#define XML_H_

#include <map>

#include "boost/lexical_cast.hpp"
using boost::lexical_cast;
using boost::bad_lexical_cast;

class Anchor;
class Guild;
class Ban;
class GuildCreation;
class Monster;
class Player;
class BaseRoom;
class Stat;
class Object;
class Room;
class Creature;

//**********************
//  Defines Section
//**********************

#define OBJ		1
#define PLY		2
#define CRT		3
#define ROOM	4

#define BIT_ISSET(p,f)    ((p)[(f)/8] & 1<<((f)%8))
#define BIT_SET(p,f)      ((p)[(f)/8] |= 1<<((f)%8))
#define BIT_CLEAR(p,f)      ((p)[(f)/8] &= ~(1<<((f)%8)))

#define NODE_NAME(pNode, pName)			(!strcmp((char *)(pNode)->name, (pName) ))

namespace xml {
	// copyToBString - will make store the string into a temp cstr, set the string
	// and then free the temp cstr
	void copyToBString(bstring &to, xmlNodePtr node);

	bstring getBString(xmlNodePtr node);

	// getProp -- You MUST free the return value
	bstring getProp(xmlNodePtr node, const char *name);

	// getIntProp -- Properly frees the return valueusing toInt
	int getIntProp(xmlNodePtr node, const char *name);

	// getCString -- You MUST free the return value
	char* getCString(xmlNodePtr node);

	//***************************************************************************************
	// XML_COPY_* - These functions will copy the given type to the variable 'to'
	//***************************************************************************************

	// copyPropToCString -- This will properly free the return value using doStrCpy
	void copyPropToCString(char* to, xmlNodePtr node, bstring name);
	//#define copyPropToCString(to, node, name)	doStrCpy( (to) , getProp( (node) , (name) ))

	// copyPropToBString -- This will properly free the value
	void copyPropToBString(bstring& to, xmlNodePtr node, bstring name);

	// copyToCString -- Properly frees the return value using doStrCpy
	void copyToCString(char* to, xmlNodePtr node);
	//#define copyToCString(to, node)	doStrCpy( (to), getCString( (node) ))

	// XML_DUP_STRING_CHILD -- Will return strdup of a string -- you MUST free it
	void dupeToCString(char* to, xmlNodePtr node);

		// copyToBool -- Properly frees the return value using toBoolean
	void copyToBool(bool& to, xmlNodePtr node);

	// copyToColor -- Properly frees the return value using toColor
	void copyToColor(Color& to, xmlNodePtr node);


	//*******************************************************************************
	// XML_NEW_* will always save (even if blank or 0) and will still let you
	// get the return value from xmlNewChild
	// ###  IMPORTANT  ### -- Name and Value must NOT include any bad xml characters
	// like &, <, >, etc.
	//********************************************************************************

	xmlAttrPtr newProp(xmlNodePtr node, bstring name, const bstring value);

	template <class Type>
	bstring numToStr(const Type& value) {
		std::ostringstream str;
		str << value;
		return(str.str());
	}

	template <class Type>
	xmlAttrPtr newNumProp(xmlNodePtr node, bstring name, const Type& value) {
		return( xmlNewProp( node, BAD_CAST (name.c_str()), BAD_CAST(numToStr(value).c_str())));
	}

	template <class Type>
	xmlNodePtr newNumChild(xmlNodePtr node, bstring name, const Type& value) {
		return(xmlNewChild( node, NULL, BAD_CAST (name.c_str()), BAD_CAST numToStr(value).c_str()));
	}

	template <class Type>
	xmlNodePtr saveNonZeroNum(xmlNodePtr node, bstring name, const Type& value) {
		xmlNodePtr toReturn = NULL;
		// precision for floats
		if((int)(value*10000)) {
			toReturn = xmlNewChild( (node), NULL, BAD_CAST (name.c_str()), BAD_CAST numToStr(value).c_str());
		}
		return(toReturn);
	}

	template <class Type>
	Type toNum(char *fromStr) {
		Type toReturn = 0;
		if(!fromStr)
			return(toReturn);

		try {
			toReturn = lexical_cast<Type>(fromStr);
		} catch (bad_lexical_cast &) {
			toReturn = 0;

		}

		free(fromStr);
		return (toReturn);
	}

	template <class Type>
	Type toNum(xmlNodePtr node) {
		return(toNum<Type>(getCString(node)));
	}

	template <class Type>
	void copyToNum(Type& to, xmlNodePtr node) {
		to = toNum<Type>(getCString(node));
	}

	template <class Type>
	void loadNumArray(xmlNodePtr curNode, Type array[], const char* nodeName, int maxProp) {
		xmlNodePtr childNode = curNode->children;
		int i;

		while(childNode) {
			if(NODE_NAME(childNode , nodeName)) {
				i = xml::getIntProp(childNode, "Num");
				if(i < maxProp)
					array[i] = xml::toNum<Type>(childNode);
			}
			childNode = childNode->next;
		}
	}

	xmlNodePtr newBoolChild(xmlNodePtr node, const bstring name, const bool value);
	xmlNodePtr newStringChild(xmlNodePtr node, const bstring name, const bstring value = "");

	//***************************************************************************************
	// saveNonZero/Null will only save if it is non 0 and also escape any bad XML characters
	//***************************************************************************************

	xmlNodePtr saveNonNullString(xmlNodePtr node, bstring name, const bstring value);

	xmlChar* ConvertInput(const char *in, const char *encoding);
	char *doStrCpy(char *dest, char *src);
	char *doStrDup(char *src);
	xmlDocPtr loadFile(const char *filename, const char *expectedRoot);
	int	saveFile(const char * filename, xmlDocPtr cur);

} // End xml namespace



//******************
//  Load Section
//******************

bool loadMonster(int index, Monster** pMonster);
bool loadMonster(const CatRef cr, Monster** pMonster);
bool loadMonsterFromFile(const CatRef cr, Monster **pMonster, bstring filename="");
bool loadObject(int index, Object** pObject);
bool loadObject(const CatRef cr, Object** pObject);
bool loadObjectFromFile(const CatRef cr, Object** pObject);
bool loadRoom(int index, Room **pRoom);
bool loadRoom(const CatRef cr, Room **pRoom);
bool loadRoomFromFile(const CatRef cr, Room **pRoom, bstring filename="");

bool loadPlayer(const char* name, Player** player, LoadType loadType=LS_NORMAL);

void readCreaturesXml(xmlNodePtr curNode, void* parent, int type);
void readObjectsXml(xmlNodePtr curNode, void* parent, int type);

void loadCarryArray(xmlNodePtr curNode, Carry array[], const char* name, int maxProp);
void loadCatRefArray(xmlNodePtr curNode, std::map<int, CatRef>& array, const char* name, int maxProp);
void loadCatRefArray(xmlNodePtr curNode, CatRef array[], const char* name, int maxProp);
void loadStringArray(xmlNodePtr curNode, void* array, int size, const char* name, int maxProp);
void loadBits(xmlNodePtr curNode, char *bits);
void loadDaily(xmlNodePtr curNode, struct daily* pDaily);
void loadDailys(xmlNodePtr curNode, struct daily* pDailys);
void loadCrLastTime(xmlNodePtr curNode, struct crlasttime* pCrLastTime);
void loadCrLastTimes(xmlNodePtr curNode, std::map<int, crlasttime>& pCrLastTimes);
void loadLastTime(xmlNodePtr curNode, struct lasttime* pLastTime);
void loadLastTimes(xmlNodePtr curNode, struct lasttime* pLastTimes);
void loadSavingThrow(xmlNodePtr curNode, struct saves* pSavingThrow);
void loadSavingThrows(xmlNodePtr curNode, struct saves* pSavingThrows);
void loadRanges(xmlNodePtr curNode, Player *pPlayer);


//**********************
//  Save Section
//**********************
//int saveRoomToFile(Room* pRoom, int permOnly);
//int saveCreature(Creature * pCreature);
//int savePlayerToFile(Creature * player);
//int saveObject(Object* pObject);

int saveObjectsXml(xmlNodePtr parentNode, otag* op, int permOnly);
int savePetsXml(xmlNodePtr parentNode, ctag* cp);
int saveCreaturesXml(xmlNodePtr parentNode, ctag* cp, int permOnly);
//int saveCreatureXml(xmlNodePtr rootNode, Creature * pCreature, int permOnly, LoadType saveType);
int saveExitsXml(xmlNodePtr curNode, xtag *xp);

Ban *parseBan(xmlNodePtr cur);

Guild* parseGuild(xmlNodePtr cur);
GuildCreation* parseGuildCreation(xmlNodePtr cur);
void parseGuildMembers(xmlNodePtr cur, int guildId);

xmlNodePtr saveDaily(xmlNodePtr parentNode, int i, struct daily pDaily);
xmlNodePtr saveCrLastTime(xmlNodePtr parentNode, int i, struct crlasttime pCrLastTime);
xmlNodePtr saveLastTime(xmlNodePtr parentNode, int i, struct lasttime pLastTime);
xmlNodePtr saveSavingThrow(xmlNodePtr parentNode, int i, struct saves pSavingThrow);
xmlNodePtr saveAnchor(xmlNodePtr parentNode, int i, Anchor* pAnchor);
xmlNodePtr saveBits(xmlNodePtr parentNode, const char* name, int maxBit, const char *bits);
xmlNodePtr saveBit(xmlNodePtr parentNode, int bit);
xmlNodePtr saveLongArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const long array[], int arraySize);
xmlNodePtr saveULongArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const unsigned long array[], int arraySize);
xmlNodePtr saveCatRefArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const std::map<int, CatRef>& array, int arraySize);
xmlNodePtr saveCarryArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const Carry array[], int arraySize);
xmlNodePtr saveCatRefArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const CatRef array[], int arraySize);
xmlNodePtr saveShortIntArray(xmlNodePtr parentNode, const char* rootName, const char* childName, const short array[], int arraySize);



int saveFactions(xmlNodePtr rootNode, Creature* pCreature);
int saveSkills(xmlNodePtr rootNode, Creature* pCreature);
#endif /*XML_H_*/