/* DEC	*_SimpleAux(ndays,intr,princ,intamt,opt,diy)
 *
 * ARGUMENT
 *	int	*ndays;		number of days
 *	DEC	*intr;			annual interest	rate
 *	DEC	*princ;			principal amount
 *	DEC	*intamt			accrued	interest amount
 *	int	opt;			variable to solve for
 *	int	diy;			days in	year (360 or 365)
 *
 * DESCRIPTION
 *	Give three of the above	variables, solves for the fourth.  opt is
 *   either GM_N, GM_I,	GM_PV, or GM_INTR, according to	the variable to	solve
 *   for.  Three source	pointers are inputs, the fourth	is the destination
 *   pointer.  princ and intamt	are rounded to 2 decimal places, ndays is
 *   rounded up	to an integer, and intr	is calculated to maximum precision.
 *	This function does the calculations for	SimpleInterest360 &
 *   SimpleInterest365.
 *
 * SIDE	EFFECTS
 *	If successful, the output pointer is modified, otherwise none.
 *	error flag is set in this routine.
 *
 * RETURNS
 *	variable if successful,	otherwise GM_NULL.
 *
 * POSSIBLE ERRORS
 *	GM_NULLPOINTER
 *	GM_ARGVAL
 *
 * ALGORITHM
 *	intrate	= princ	* intr * ndays / (100 *	diy)
 *
 * AUTHOR
 *  Jared Levy
 *   Copyright (C) 1987-1990 Greenleaf Software	Inc.  All rights reserved.
 *
 * MODIFICATIONS
 *
 *
 */

#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"

DEC	*_SimpleAux(ndays,intr,princ,intamt,opt,diy)
int	*ndays;
DEC	*intr;
DEC	*princ;
DEC	*intamt;
int	opt;
int	diy;
{
	DEC	dday, *day=&dday, dhdiy, *hdiy=&dhdiy;
	DEC	dtemp, *temp=&dtemp, dt2, *t2=&dt2;

/* check for invalid opt */
	if ((opt!=GM_N)	&& (opt!=GM_I) && (opt!=GM_PV) && (opt!=GM_INTR)) {
		_MacErr(GM_ARGVAL);
		return(GM_NULL);
	}

/* check for null pointers */
	if (!ndays || !intr || !princ || !intamt)  {
		_MacErr(GM_NULLPOINTER);
		return(GM_NULL);
	}
	if ((opt!=GM_I&&_MacBad(intr)) || (opt!=GM_PV&&_MacBad(princ))
		|| (opt!=GM_INTR&&_MacBad(intr)))  {
		_MacErr(GM_INIT);
		return(GM_NULL);
	}

/* change ndays	to DEC */
	if (opt!=GM_N)
		(void) ConvLongToDecimal(day, (long) *ndays);

	(void) ConvLongToDecimal(hdiy, 100L * (long) diy);

/* solved for interest accrued */
	if (opt==GM_INTR)  {
		(void) _MulDec80Bit(temp, princ, intr);
		(void) _MulDec80Bit(temp, temp,	day);
		(void) _DivRndDec80Bit(intamt, temp, hdiy, 2);
		return(intamt);
	}

/* check for zero variables */
	if ((opt!=GM_N)	&& (*ndays==0))	 {
		_MacErr(GM_ARGVAL);
		return(GM_NULL);
	}

	if ((opt!=GM_I)	&& _MacIsDecZ(intr))  {
		_MacErr(GM_ARGVAL);
		return(GM_NULL);
	}

	if ((opt!=GM_PV) && _MacIsDecZ(princ))	{
		_MacErr(GM_ARGVAL);
		return(GM_NULL);
	}

/* solve for principal */
	if (opt==GM_PV)	 {
		(void) _MulDec80Bit(temp, intamt, hdiy);
		(void) _DivDec80Bit(temp, temp,	intr);
		(void) _DivRndDec80Bit(princ, temp, day, 2);
		return(princ);
	}

/* solve for interest rate */
	if (opt==GM_I)	{
		(void) _MulDec80Bit(temp, intamt, hdiy);
		(void) _DivDec80Bit(temp, temp,	princ);
		(void) _DivDec80Bit(intr, temp,	day);
		(void) _Sq5UnsTo4Uns(intr);
		return(intr);
	}

/* solve for number of days */
/*	if (opt==GM_N)	*/
		(void) _MulDec80Bit(temp, intamt, hdiy);
		(void) _DivDec80Bit(temp, temp,	intr);
		(void) _DivDec80Bit(temp, temp,	princ);
		(void) _TruncateDec80Bit(t2, temp, 0);
		if (!CompareDecimal(t2,	temp)==0)
			_AddDec80Bit(t2, t2, &decOne);
		if (t2->dc.sl[1] || _MacIsDecN(t2) || (t2->dc.sl[0]&0x8000)
			|| t2->dc.sl[2]	|| t2->dc.sl[3]	|| t2->dc.msd)	{
				_MacErr(GM_ARGVAL);
				return(GM_NULL);
			}
			*ndays = (int) t2->dc.sl[0];
		return(GM_NULL);

}