

#include <windows.h>
#include <math.h>
#include "SNDLLCommons.h"


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call){
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}


extern "C" short calcMain(short id, bool alt, double theStack[10],  DLLEXTRAS* extras){
	short rtnState = 0;
	short i;
	double displaytorad = 1;
	double temp;

	// degrees or radians
	if (extras->flags[DEGFLAG])
		displaytorad =  (PI/180.0);// deg rad converstions



	switch (id) {



		// x*x
		case R1C1:
			theStack[0] *= theStack[0];
			rtnState = NOACTION;

			break;

		// x*x*x
		case R1C2:
			theStack[0] = theStack[0]*theStack[0]*theStack[0];
			rtnState = NOACTION;
			break;


		// y^x
		case R1C3:
			theStack[0] = pow(theStack[1],theStack[0]);
			rtnState = PULLSTACK;
			break;

		// sqrt
		case R2C1:
			if (theStack[0] < 0)
				MessageBox(extras->appWnd,TEXT("Sqrt(-1) is not Real"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else {
				theStack[0] = sqrt(theStack[0]);
				rtnState = NOACTION;
			}

			break;
		// cube root
		case R2C2:
			if (theStack[0] < 0)
				MessageBox(extras->appWnd,TEXT("Root(-1) not allowed"),TEXT("Math Error"),MB_OK|MB_ICONERROR);

			else {
				theStack[0] = pow(theStack[0],1.0/3.0);
				rtnState = NOACTION;
			}
			break;

		// x root y
		case R2C3:
			if (theStack[0] == 0)
				MessageBox(extras->appWnd,TEXT("1/0 power not allowed"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else if (theStack[1] < 0)
				MessageBox(extras->appWnd,TEXT("Root(-1) not allowed"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else {
			theStack[0] = pow(theStack[1],1.0/theStack[0]);
			rtnState = PULLSTACK;
			}
			break;


		// 10x
		case R3C1:
			theStack[0] = pow(10,theStack[0]);
			rtnState = NOACTION;
			break;
		// exp
		case R3C2:
			theStack[0] = exp(theStack[0]);
			rtnState = NOACTION;
			break;

			// 1/x
		case R3C3:
			if (theStack[0] == 0)
				MessageBox(extras->appWnd,TEXT("1/0 is not Defined"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else
				theStack[0] = 1.0/(theStack[0]);
			rtnState = NOACTION;


			break;

		case R4C1:
			if (theStack[0] < 0)
				MessageBox(extras->appWnd,TEXT("Log10(-1) is not Real"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else {
				theStack[0] = log10(theStack[0]);
				rtnState = NOACTION;
			}
			break;

		case R4C2:  // log10
			if (theStack[0] < 0)
				MessageBox(extras->appWnd,TEXT("Log(-1) is not Real"),TEXT("Math Error"),MB_OK|MB_ICONERROR);
			else {
				theStack[0] = log(theStack[0]);
				rtnState = NOACTION;
			}
			break;

		// PI
		case R4C3:
			// this should push the stack values and not overwrite the current value
			for ( i=9;i>0;i--)
				theStack[i] = theStack[i-1];
			theStack[0] = PI;
			rtnState = NOACTION;

			break;
		// sin
		case R5C1:
			if (alt)
				theStack[0] = asin(theStack[0])/displaytorad;
			else
				theStack[0] = sin(theStack[0]*displaytorad);
			rtnState = NOACTION;
			break;

		// cos
		case R5C2:
			if (alt)
			theStack[0] = acos(theStack[0])/displaytorad;
			else
			theStack[0] = cos(theStack[0]*displaytorad);
			rtnState = NOACTION;
			break;

		// tan
		case R5C3:
			if (alt)
				theStack[0] = atan(theStack[0])/displaytorad;
			else
				theStack[0] = tan(theStack[0]*displaytorad);
			rtnState = NOACTION;
			break;


		case R6C1:
			if (alt) {
				// to rectangular
				temp = theStack[0];
				theStack[0] = temp*cos(theStack[1]*displaytorad);
				theStack[1] = temp*sin(theStack[1]*displaytorad);

			}else {
				// to polar
				temp = sqrt(theStack[0]*theStack[0] + theStack[1]*theStack[1]);
				theStack[1] = atan2(theStack[1],theStack[0])/displaytorad;
				theStack[0] = temp;
			}
			rtnState = NOACTION; // don't change the stack, the function already did that
			break;

		case R6C2:
			if (alt)
				theStack[0] = theStack[0]*180.0/PI; // to degrees
			else
				theStack[0] = theStack[0]*PI/180.0;  // to radians
			rtnState = NOACTION;
			break;

		case R6C3:
			//alt
			break;
	}
	return rtnState;
};