/*	XDataUtil.h
 *
 *		The data manipulation utilities. I wrote my own because I'm
 *	one of those obnoxious types who likes to know what's going on.
 */

/**********************************************************************

  YAAF is Copyright 1997-1999 by William Woody.

  Redistribution and use in source and binary forms, with or without 
  modification, are permitted provided that the following conditions 
  are met:

  Redistributions of source code must retain the above copyright notice, 
  this list of conditions and the following disclaimer.

  Neither the name of the copyright holder or other contributors may
  be used to promote products derived from this software without
  specific written prior permission.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
  SOFTWARE.
  
  Contact:   woody@alumni.caltech.edu
  Web page:  http://www.pandawave.com/yaaf/

**********************************************************************/

#ifndef PandaWave_XDATAUTIL
#define PandaWave_XDATAUTIL

#include <XConfig.h>
#include <XTypes.h>
#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif


/************************************************************************/
/*																		*/
/*	short/long compression												*/
/*																		*/
/************************************************************************/

/*$	MAKEDWORD
 *
 *		This macro concatenates two word-sized objects into a long-word
 *	sized object.
 */

#define MAKEDWORD(x,y)	(((unsigned long)(unsigned short)(x)) << 16 |	\
						 ((unsigned long)(unsigned short)(y)))

/*$	GETLOWORD
 *
 *		This macro returns the low order word from a long-word, and is
 *	the inverse of the MAKEDWORD macro.
 */

#define GETLOWORD(x)	((unsigned short)((x) & 0xFFFF))


/*$	GETHIWORD
 *
 *		This macro returns the high order word from a long-word, and is
 *	the inverse of the MAKEDWORD macro.
 */

#define GETHIWORD(x)	((unsigned short)((x) >> 16))

/************************************************************************/
/*																		*/
/*	Endian byte order utilities											*/
/*																		*/
/************************************************************************/

/*
 *	Byte order swap
 */

extern uint16			SwapWord(uint16);
extern uint32			SwapLong(uint32);
extern float			SwapFloat(float);
extern double			SwapDouble(double);

/**@name Support--Network byte order conversion*/
//@{

#if OPT_NATIVEORDER == 1

/*$	ESwapWord
 *
 *		This macro swaps the word order for a non-network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 */

#define	ESwapWord(x)	SwapWord(x)

/*$	ESwapLong
 *
 *		This macro swaps the word order for a non-network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 */

#define	ESwapLong(x)	SwapLong(x)

/*$	ESwapFloat
 *
 *		This macro swaps the word order for a non-network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 * 
 *		This is reliant on the size of a float being 4 bytes. This
 *	also relies on the double being in IEEE format; use with caution.
 */

#define	ESwapFloat(x)	SwapFloat(x)

/*$	ESwapDouble
 *
 *		This macro swaps the word order for a non-network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 *
 *		This is reliant on the size of a double being 8 bytes. This
 *	also relies on the double being in IEEE format; use with caution.
 */

#define	ESwapDouble(x)	SwapDouble(x)

/*$	NSwapWord
 *
 *		This macro swaps the word order for a network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 */

#define	NSwapWord(x)	(x)

/*$	NSwapLong
 *
 *		This macro swaps the word order for a network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 */

#define	NSwapLong(x)	(x)

/*$	NSwapFloat
 *
 *		This macro swaps the word order for a network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 * 
 *		This is reliant on the size of a float being 4 bytes. This
 *	also relies on the double being in IEEE format; use with caution.
 */

#define	NSwapFloat(x)	(x)

/*$	NSwapDouble
 *
 *		This macro swaps the word order for a network order word
 *	to the native order of the target environment. Depending on the
 *	setting of OPT_NATIVEORDER, this either swaps or does not swap
 *	the bytes in word.
 *
 *		This is reliant on the size of a double being 8 bytes. This
 *	also relies on the double being in IEEE format; use with caution.
 */

#define	NSwapDouble(x)	(x)

#else

#define	ESwapWord(x)	(x)
#define	ESwapLong(x)	(x)
#define	ESwapFloat(x)	(x)
#define	ESwapDouble(x)	(x)

#define	NSwapWord(x)	SwapWord(x)
#define	NSwapLong(x)	SwapLong(x)
#define	NSwapFloat(x)	SwapFloat(x)
#define	NSwapDouble(x)	SwapDouble(x)

#endif

//@}

/************************************************************************/
/*																		*/
/*	Resource Support													*/
/*																		*/
/************************************************************************/

#if OPT_XWIN

/**@name Support--X Windows Resource Support
 *
 *		These routines are actually generated by the YAAF X Windows
 *	resource compiler tool, and linked into the application.
 */

//@{

/*$	GetResourceData
 *
 *		This is an X specific routine used for getting resources.
 *
 *		A note about this routine. While I am declaring it in this header,
 *	the GetResourceData routine itself is actually generated by the
 *	RCompile tool, along with the resource data that is associated with
 *	this program.
 *
 *		If you fail to compile the resources into a resource.c file and
 *	link it in with the rest of your YAAF program, this routine will show
 *	up as missing. Likewise, if there is a problem with your resources
 *	(like duplicate resources), you will have problems compiling the
 *	resource.c file.
 */

extern void *GetResourceData(long resType, short resID);

/*	GetResourceSize
 *
 *		This is an X specific routine used for getting the size of
 *	a resource.
 *
 *		A note about this routine. While I am declaring it in this header,
 *	the GetResourceData routine itself is actually generated by the
 *	RCompile tool, along with the resource data that is associated with
 *	this program.
 *
 *		If you fail to compile the resources into a resource.c file and
 *	link it in with the rest of your YAAF program, this routine will show
 *	up as missing. Likewise, if there is a problem with your resources
 *	(like duplicate resources), you will have problems compiling the
 *	resource.c file.
 */

extern long  GetResourceSize(long resType, short resID);

//@}

#endif // OPT_XWIN

/************************************************************************/
/*																		*/
/*	Internationalization												*/
/*																		*/
/************************************************************************/

extern short GetResourceMessage(short res, short index, char *smsg, char *lmsg);

/************************************************************************/
/*																		*/
/*	Complex formatting													*/
/*																		*/
/************************************************************************/

extern void yformat(char *out, const char *msg, ...);
extern void vyformat(char *out, const char *msg, va_list vlist);


#ifdef __cplusplus
}
#endif

#endif /* PandaWave_XDATAUTIL */
