

#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){

	// uses variable location 5-7 to store coefficients, so give them a name
	#define A2  5
	#define A1  6
	#define A0  7

	short rtnState = 0;
	short i;
	double displaytorad = 1;
	double temp1,temp2;

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

	// process id larger that MODKEYSIZE to set a custom key layout
	if (id > MODKEYSIZE) {
		id -= MODKEYSIZE;
		switch (id) {

		case R1C1:
		case R1C2:
		case R1C3:
			return -1; // not a active key
			break;

		case R3C1:
		case R3C2:
		case R3C3:
			extras->keyRect->x = KEYWT; // key x location is 2 (0 based) keys over from edge of screen
			extras->keyRect->dx = 3*KEYWT; // 3 keys wide
			return 0;
			break;

		case R4C1:
		case R4C2:
		case R4C3:
			extras->keyRect->x = KEYWT; // key x location is 2 keys over from edge of screen
			extras->keyRect->dx = 3*KEYWT; // 3 keys wide
			return 0;
			break;

		case R5C1:
		case R5C2:
		case R5C3:
		case R6C1:
		case R6C2:
		case R6C3:
			return -1; // not a active key
			break;

		}
		return 0;


	}

	switch (id) {



		// do nothing with the keys that are not handled


		// store in higher user variables
		case R2C1:
				extras->vars[A2] = theStack[0];
				rtnState = NOACTION;
			break;

		case R2C2:
				extras->vars[A1] = theStack[0];
				rtnState = NOACTION;
			break;

		case R2C3:
				extras->vars[A0] = theStack[0];
				rtnState = NOACTION;
			break;


		// evaluate the function
		case R3C1:
		case R3C2:
		case R3C3:
			theStack[0] = theStack[0]*theStack[0]*extras->vars[A2]+theStack[0]*extras->vars[A1]+extras->vars[A0];
			rtnState = NOACTION;
			break;

		// find the roots
		// a2*x^2 + a1*x + a0
		case R4C1:
		case R4C2:  
		case R4C3:
			// degenerate cases
			if (extras->vars[A2] == 0) {
				if (extras->vars[A1] == 0)
					MessageBox(extras->appWnd,TEXT("Degenerate eqn. No solution."),TEXT("Quadratic"),MB_OK);
				else
					theStack[0] = -extras->vars[A0]/extras->vars[A1];

			} else {
				// push the stack up two values to make room for the answers
				for (i=(STACKSIZE-1);i>1;i--)
					theStack[i] = theStack[i-2];

				// radical
				temp1 = extras->vars[A1]*extras->vars[A1] - 4.0*extras->vars[A2]*extras->vars[A0];
				
				temp2 = -extras->vars[A1]/2.0/extras->vars[A2];
				if (temp1<0) {
					// complex roots
					MessageBox(extras->appWnd,TEXT("Roots are complex (x+yi)"),TEXT("Quadratic"),MB_OK);
					theStack[0]= temp2;
					theStack[1] = sqrt(-temp1)/2.0/extras->vars[A2];
				} else {
					temp1 = sqrt(temp1)/2.0/extras->vars[A2];
					theStack[0] = temp2+temp1;
					theStack[1] = temp2-temp1;
				}
			}
			rtnState = NOACTION;

			break;


	}
	return rtnState;
};