/***************************************************************************
 *
 *  INVESTMENT INTELLIGENCE SYSTEMS CORPORATION
 *
 *	array.c
 *	@(#)array.c	3.3.1.3 98/09/01
 *
 *	This boundin provides an example of how to obtain information from
 *	Wingz arrays in a boundin. The user passes an array and an
 *	appropriate number of elements. The functions return the information
 *	within the array.
 *
 *	array:ReturnArrayEle1(array, position1)
 *	array:ReturnArrayEle2(array, position1, position2)
 *
 *	Consult the array.scz script for a working example.
 *
 ***************************************************************************
 */

#if defined(WIN32)
#include <windows.h>
#endif

#define numfuncs        2
#include "Boundin.h"

IATFUNC ReturnArrayEle1(PVAL, PVAL);
IATFUNC ReturnArrayEle2(PVAL, PVAL);


/* BDROUT defines the Wingz/Boundin interface */
BDROUT rout =
{
	numfuncs, XFDEF(0),
	{
		{ XFDEF(ReturnArrayEle1),	"\017ReturnArrayEle1",	2 | NORMAL},
		{ XFDEF(ReturnArrayEle2),	"\017ReturnArrayEle2",	3 | NORMAL}
	}
};

/* Function descriptions (appear in function glossary) */
BDFUNCLIST =
{
	(PCHAR)"Array Boundin",
	(PCHAR)"ReturnArrayEle1(1D_array, position)",
	(PCHAR)"Returns an array element of a 1D array",
	RETARRAY,

	(PCHAR)"Array Boundin",
	(PCHAR)"ReturnArrayEle1(2D_array, position1, position2)",
	(PCHAR)"Returns an array element of a 2D array",
	RETARRAY,

	0, 0, 0, 0
};


/* Point of entry */
BDMAINFUNC(BoundinCalls * calls)
{
    return &rout;
}

/* The following function is used in the Windows environment. */
/* It is required to build a dynamic link library (DLL). */
#if defined(WIN32)
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
	return TRUE;
}
#endif


/* This function returns an array element of a 1 dimensional array. */
/* The array is in parg[0] and the element specification is in parg[1]. */
IATFUNC ReturnArrayEle1(PVAL pret, PVAL parg)
{
	unsigned short   dims;
	VAL              tmpVal;

	/* Make sure it is an array. */
	if (parg[0].flag == ARRAY)
	{
		/* Make sure it is a 1 dimensional array. */
		if (parg[0].val.array.dims == 1)
		{
			/* Make sure 2nd arg is number and in range of array. */
			if (parg[1].flag == NUMERIC && parg[1].val.numeric > 0 &&
					(USHORT)parg[1].val.numeric <= parg[0].val.array.d1)
			{
				/* In C, arrays start at 0. */
				dims = parg[1].val.numeric - 1;

				/* Get the array element. */
				if (!xfGetArrayEl(&parg[0], &dims, &tmpVal))
				{
					xfSetErr(pret, BADARRAY);
					return;
				}
				pret->flag = tmpVal.flag;
				pret->val = tmpVal.val;
				return;
			}
			else
			{
				xfSetErr(pret, BADINDEX);
				return;
			}
		}
		else
		{
			xfSetErr(pret, WRONGDIMS);
			return;
		}
	}
	else
	{
		xfSetErr(pret, NOTARRAY);
		return;
	}
}


/* This function returns an array element of a 2 dimensional array. */
/* The array is in parg[0] and the element specifications are in parg[1] */
/* and parg[2]. */
IATFUNC ReturnArrayEle2(PVAL pret, PVAL parg)
{
	unsigned short  dims[2];
	VAL             tmpVal;

	if (parg[0].flag == ARRAY)
	{
		if (parg[0].val.array.dims == 2)
		{
			if (parg[1].flag == NUMERIC && parg[2].flag == NUMERIC &&
					parg[1].val.numeric > 0 &&
					(USHORT)parg[1].val.numeric <= parg[0].val.array.d1 &&
					parg[2].val.numeric > 0 &&
					(USHORT)parg[2].val.numeric <= parg[0].val.array.d2)
			{
				/* In C, arrays start at 0. */
				dims[0] = parg[1].val.numeric - 1;
				dims[1] = parg[2].val.numeric - 1;

				/* Get the array element. */
				if (!xfGetArrayEl(&parg[0], dims, &tmpVal))
				{
					xfSetErr(pret, BADARRAY);
					return;
				}
				pret->flag = tmpVal.flag;
				pret->val = tmpVal.val;
				return;
			}
			else
			{
				xfSetErr(pret, BADINDEX);
				return;
			}
		}
		else
		{
			xfSetErr(pret, WRONGDIMS);
			return;
		}
	}
	else
	{
		xfSetErr(pret, NOTARRAY);
		return;
	}
}
