
/*
  File: include/ioutils/Interface_Prefs.h
  Description: Sonique 2 preferences system header
  Part of the Mantis project
  (c) 2002 Lycos Inc.

  This file is distributed for the sole purpose of allowing you to write
  software to interface with Sonique 2 and other Mantis programs. It is
  not to be modified or used for any other purpose without written
  authorization.

  If you redistribute this file, it must be in the original package
  complete with all other files provided, including the usage agreement.

  Do not remove this notice.
*/

#ifndef _INTERFACE_PREFS_H__
#define _INTERFACE_PREFS_H__

#ifdef DEBUG_INCLUDE_ORDER
#pragma message("Including " __FILE__ "\n" )
#endif

#if _MSC_VER > 1000
#pragma once
#endif

#include "mgeneric.h"
#include "charstring.h"
#include "Interface_ErrorSys.h"


// {62A288C1-1596-4277-8418-C8A567A72D3E}
DEFINE_MID( MID_PREFS_STORAGE, 0x62a288c1, 0x1596, 0x4277, 0x84, 0x18, 0xc8, 0xa5, 0x67, 0xa7, 0x2d, 0x3e);


typedef enum  EPrefTypes
{
	preftype_astring	= 1,
	preftype_wstring	= 2,
	preftype_int		= 3,
	preftype_uint		= 4,
	preftype_mid		= 5,
	preftype_data		= 6
}EPrefTypes;

typedef enum EPrefOpenMode
{

	prefopen_open_mask	= 0x0001,
	prefopen_open		= 0x0000,
	prefopen_cancreate	= 0x0001,// can create the section path if it doesn't already exist, (will open existing without erasing if it already does exist)
	prefopen_scramble	= 0x1000 // not supported yet
}EPrefOpenMode;



template <class CHARTYPE, class NAMETYPE>
class TMXMLItem;
typedef TMXMLItem<wchar_t,char> MXMLItem;
class MPreferences : public MGeneric
{
public:
	// Open section must be called successfuly before any other function is called
	virtual MRESULT		__stdcall	OpenSection( const wchar_t* wcSection, EPrefOpenMode mode = prefopen_cancreate)								= 0;
	virtual MRESULT		__stdcall	Close()																										= 0;
	virtual MPreferences& __stdcall	operator =( const MPreferences& Other )																		= 0;

	virtual MRESULT		__stdcall	Save()																										= 0;

	// set default if the value is not already set
	// returns true if the default is set
	virtual MRESULT		__stdcall	PrepAString(	const wchar_t* wcName, const AString& asDefault )											= 0;
	virtual MRESULT		__stdcall	PrepAString(	const wchar_t* wcName, const Array<AString>& asDefault )									= 0;
	virtual MRESULT		__stdcall	PrepWString(	const wchar_t* wcName, const WString& wsDefault )											= 0;
	virtual MRESULT		__stdcall	PrepWString(	const wchar_t* wcName, const Array<WString>& wsDefault )									= 0;
	virtual MRESULT		__stdcall	PrepBool(		const wchar_t* wcName, bool bDefault )														= 0;
	virtual MRESULT		__stdcall	PrepBool(		const wchar_t* wcName, const Array<bool>& bDefault )										= 0;
	virtual MRESULT		__stdcall	PrepInt(		const wchar_t* wcName, int32 iDefault, int32 min = -0x7FFFFFFF-1, int32 max = 0x7FFFFFFF )	= 0;
	virtual MRESULT		__stdcall	PrepInt(		const wchar_t* wcName, const Array<int32>& iDefault, int32 min = -0x7FFFFFFF-1, int32 max = 0x7FFFFFFF ) = 0;
	virtual MRESULT		__stdcall	PrepUInt(		const wchar_t* wcName, uint32 uiDefault, uint32 min = 0, uint32 max = 0xFFFFFFFF )			= 0;
	virtual MRESULT		__stdcall	PrepUInt(		const wchar_t* wcName, const Array<uint32>& uiDefault, uint32 min = 0, uint32 max = 0xFFFFFFFF ) = 0;
	virtual MRESULT		__stdcall	PrepDouble(		const wchar_t* wcName, double lfDefault )													= 0;
	virtual MRESULT		__stdcall	PrepDouble(		const wchar_t* wcName, double lfDefault, double min, double max )							= 0;
	virtual MRESULT		__stdcall	PrepDouble(		const wchar_t* wcName, const Array<double>& lfDefault )										= 0;
	virtual MRESULT		__stdcall	PrepDouble(		const wchar_t* wcName, const Array<double>& lfDefault, double min, double max )				= 0;
	virtual MRESULT		__stdcall	PrepMID(		const wchar_t* wcName, const MID& midDefault )												= 0;
	virtual MRESULT		__stdcall	PrepMID(		const wchar_t* wcName, const Array<MID>& midDefault )										= 0;
	virtual MRESULT		__stdcall	PrepData(		const wchar_t* wcName, const Array<uint8>& pDefault )										= 0;
	virtual MRESULT		__stdcall	PrepXML(		const wchar_t* wcName, const MXMLItem* pXML )												= 0;

	
	// get bits
	// for the Array ones, if 'fromhere' is 0, the count of items stored is returned in nCount
	virtual MRESULT		__stdcall	GetAString(		const wchar_t* wcName, AString& toHere ) const												= 0;
	virtual MRESULT		__stdcall	GetAString(		const wchar_t* wcName, Array<AString>& toHere ) const										= 0;
	virtual MRESULT		__stdcall	GetWString(		const wchar_t* wcName, WString& toHere ) const												= 0;
	virtual MRESULT		__stdcall	GetWString(		const wchar_t* wcName, Array<WString>& toHere ) const										= 0;
	virtual MRESULT		__stdcall	GetBool(		const wchar_t* wcName, bool& toHere ) const													= 0;
	virtual MRESULT		__stdcall	GetBool(		const wchar_t* wcName, Array<bool>& toHere ) const											= 0;
    virtual MRESULT		__stdcall	GetInt(			const wchar_t* wcName, int32& toHere ) const												= 0;
	virtual MRESULT		__stdcall	GetInt(			const wchar_t* wcName, Array<int32>& toHere ) const											= 0;
    virtual MRESULT		__stdcall	GetUInt(		const wchar_t* wcName, uint32& toHere ) const												= 0;
	virtual MRESULT		__stdcall	GetUInt(		const wchar_t* wcName, Array<uint32>& toHere ) const										= 0;
	virtual MRESULT		__stdcall	GetDouble(		const wchar_t* wcName, double& toHere ) const												= 0;
	virtual MRESULT		__stdcall	GetDouble(		const wchar_t* wcName, Array<double>& toHere ) const										= 0;
	virtual MRESULT		__stdcall	GetMID(			const wchar_t* wcName, MID& toHere ) const													= 0;
	virtual MRESULT		__stdcall	GetMID(			const wchar_t* wcName, Array<MID>& toHere ) const											= 0;
	virtual MRESULT		__stdcall   GetData(		const wchar_t* wcName, Array<uint8>& toHere ) const											= 0;
	virtual MRESULT		__stdcall	GetXML(			const wchar_t* wcName, const MXMLItem*& pXML ) const										= 0;

	
	// set bits
	virtual MRESULT		__stdcall	SetAString(		const wchar_t* wcName, const AString& fromHere )											= 0;
	virtual MRESULT		__stdcall	SetAString(		const wchar_t* wcName, const Array<AString>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetWString(		const wchar_t* wcName, const WString& fromHere )											= 0;
	virtual MRESULT		__stdcall	SetWString(		const wchar_t* wcName, const Array<WString>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetBool(		const wchar_t* wcName, bool fromHere )														= 0;
	virtual MRESULT		__stdcall	SetBool(		const wchar_t* wcName, const Array<bool>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetInt(			const wchar_t* wcName, int32 fromHere )														= 0;
	virtual MRESULT		__stdcall	SetInt(			const wchar_t* wcName, const Array<int32>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetUInt(		const wchar_t* wcName, uint32 fromHere )													= 0;
	virtual MRESULT		__stdcall	SetUInt(		const wchar_t* wcName, const Array<uint32>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetDouble(		const wchar_t* wcName, double fromHere )													= 0;
	virtual MRESULT		__stdcall	SetDouble(		const wchar_t* wcName, const Array<double>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetMID(			const wchar_t* wcName, const MID& fromHere )												= 0;
	virtual MRESULT		__stdcall	SetMID(			const wchar_t* wcName, const Array<MID>& fromHere )											= 0;
	virtual MRESULT		__stdcall   SetData(		const wchar_t* wcName, const Array<uint8>& fromHere )										= 0;
	virtual MRESULT		__stdcall	SetXML(			const wchar_t* wcName, const MXMLItem* pXML )												= 0;


	// remove bits
	virtual MRESULT		__stdcall	Remove( const wchar_t* wcName )																				= 0;
	virtual MRESULT		__stdcall	RemoveSection()																								= 0;
	
	// utils
	// added Escape and Unescape jmc101802)
	virtual MRESULT		__stdcall	Escape(			const wchar_t* wcString, WString& toHere ) const											= 0;
	virtual MRESULT		__stdcall	Unescape(		const wchar_t* wcString, WString& toHere ) const											= 0;

	//convienentinlines
	AString GetAString( const wchar_t* wcName ) const
	{
		AString as;
		GetAString( wcName, as );
		return as;
	}

	WString GetWString( const wchar_t* wcName ) const
	{
		WString ws;
		GetWString( wcName, ws );
		return ws;
	}

   	bool	GetBool( const wchar_t* wcName ) const
	{
		bool b;
		if( GetBool( wcName, b ) != M_OK )
			b = false;
		return b;
	}

	int32	GetInt( const wchar_t* wcName ) const
	{
		int32 i;
		if( GetInt( wcName, i ) != M_OK )
			i = 0;
		return i;
	}

	uint32	GetUInt( const wchar_t* wcName ) const
	{ 
		uint32 ui;
		if( GetUInt( wcName, ui ) != M_OK )
			ui = 0;
		return ui;
	}

	MID	GetMID( const wchar_t* wcName ) const
	{
		MID mid;
		if( GetMID( wcName, mid ) != M_OK )
			memset(&mid,0,sizeof(mid));

		return mid;
	}

	// added Escape and Unescape jmc101802
	WString Escape( const wchar_t* wcName ) const
	{
		WString ws;
		Escape( wcName, ws );
		return ws;
	}
	WString Unescape( const wchar_t* wcName ) const
	{
		WString ws;
		GetWString( wcName, ws );
		return ws;
	}

};



enum {
	ERR_PREFS_ALREADYOPEN,
	ERR_PREFS_BADSECTION,
	ERR_PREFS_SECTION_NOTOPEN,
	ERR_PREFS_NOSUCHITEM,
	ERR_PREFS_INVALIDDATA,
	ERR_PREFS_STORAGE_FAILED,
	ERR_PREFS_PREP_DEFAULT_UNUSED,
	ERR_PREFS__NUM,

};

#define ERR_PREFS__MODULE "Preference System"


inline MError* GetPrefSystemErrors(MError* Errors)
{
	Errors[ERR_PREFS_ALREADYOPEN].Name		= "section is already open";
	Errors[ERR_PREFS_BADSECTION].Name		= "section name was invalid (prefs may not have properly opened)";
	Errors[ERR_PREFS_SECTION_NOTOPEN].Name	= "section is not open";
	Errors[ERR_PREFS_NOSUCHITEM].Name		= "no such item in section";
	Errors[ERR_PREFS_INVALIDDATA].Name		= "data for item was not valid for type";
	Errors[ERR_PREFS_STORAGE_FAILED].Name	= "failed to save";
	return Errors;
}


#ifdef DEBUG_INCLUDE_ORDER
#pragma message("Done including " __FILE__ "\n" )
#endif

#endif // _INTERFACE_PREFS_H__
