/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss or reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

#ifndef _BC_NANU_H
#define _BC_NANU_H

/** @addtogroup nanu */
/** @{ */

/**
*	Opaque pointer to the natural number pool state.
*/

typedef struct _bc_s_nanu	*BC_NANU;

/**
*	Structure for constants.
*/

typedef struct {

	const unsigned int	size;		//!< Length of the number in words
	const unsigned int	data[];		//!< The number in little-endian word order

} BC_NANU_CONS;

/**
*	Return codes
*/

enum {

	BC_NANU_NANU =	 0,			//!< Greetings, Earthling, it's all fine!
	BC_NANU_SUND =	-1,			//!< Stack underflow
	BC_NANU_SOVR =	-2,			//!< Stack overflow
	BC_NANU_NANN =	-3,			//!< Result is not a natural number
	BC_NANU_OMEM =	-4,			//!< Out of memory
	BC_NANU_SIZE =	-5,			//!< External object size is out of bounds
	BC_NANU_ITEM =	-6,			//!< Out of variable descriptors
	BC_NANU_NEXT =  -7			//!< Next unused error code
};

/**
*	Comparison conditions
*/

enum {

	BC_NANU_LT,					//!< Less than
	BC_NANU_LE,					//!< Less than or equal to
	BC_NANU_EQ,					//!< Equal to
	BC_NANU_GE,					//!< Greater than or equal to
	BC_NANU_GT,					//!< Greater than
	BC_NANU_NE					//!< Not equal to
};

/**
*	Size of the pool administrative data.
*
*	The macro returns the number of words that the library will reserve from
*	its memory pool for administrative purposes if the stack is set to \p depth
*	deep when calling the BC_NanuInit() function.
*/

#define	BC_NANU_POOL( depth )	(((depth)*2+10)

/** @} */

#ifndef NULL
#define NULL ((void *)0)
#endif

BC_NANU	BC_NanuInit( int *buff, unsigned short size, unsigned char deep );

int		BC_NanuCons( BC_NANU nanu, const BC_NANU_CONS *cons );
int		BC_NanuPush( BC_NANU nanu, const void *data, int size );
int		BC_NanuPull( BC_NANU nanu, void *data, int size );
int		BC_NanuSize( BC_NANU nanu );
int		BC_NanuTail( BC_NANU nanu );

int		BC_NanuDrop( BC_NANU nanu );
int		BC_NanuDupl( BC_NANU nanu );
int		BC_NanuSwap( BC_NANU nanu );
int		BC_NanuTuck( BC_NANU nanu );
int		BC_NanuOver( BC_NANU nanu );
int		BC_NanuPick( BC_NANU nanu, unsigned item );
int		BC_NanuRoll( BC_NANU nanu, int depth );

int		BC_NanuRadd( BC_NANU nanu );
int		BC_NanuRsub( BC_NANU nanu );
int		BC_NanuRmul( BC_NANU nanu );
int		BC_NanuRexp( BC_NANU nanu );
int		BC_NanuRdiv( BC_NANU nanu );
int		BC_NanuRmod( BC_NANU nanu );

int		BC_NanuMadd( BC_NANU nanu );
int		BC_NanuMsub( BC_NANU nanu );
int		BC_NanuMmul( BC_NANU nanu );
int		BC_NanuMexp( BC_NANU nanu );
int		BC_NanuMdiv( BC_NANU nanu );
int		BC_NanuMinv( BC_NANU nanu );

int		BC_NanuShft( BC_NANU nanu, int shift );
int		BC_NanuBgcd( BC_NANU nanu );
int		BC_NanuComp( BC_NANU nanu, int cond );

#endif

