#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <egb.h>
#include <guidbg.h>

extern void SaveResumeFile(void);

int ValueMsgId[3] = -1;
int OperatorMsgId = -1;
int DentaBtnId[64] = -1;

#define NUM_BUTTON 19

static void DentaBtnMode0(int kobj);
static void DentaBtnMode1(int kobj);
static void DentaBtnMode2(int kobj);
static int DentaBtnNum(int kobj);
static void DentaSetOperator(int o);
static void DentaSqrt(char *str);
static void DentaLetterFunc(int btnNum);
static void DentaAddLetter(int n,char let);
static void DentaSetMsg(int kobj,char *msg);
static void DentaClearMsg(int kobj);
static void DentaCalcAnswer(void);
static void DentaFeedBackAnswer(int ope);
static void DentaAllClear(void);

int	DentaWinFunc(int kobj,int messId)
{
	if(messId==MM_ERASE)
	{
		/* EIN(TM) >> */
		SaveResumeFile();
		/* << EIN(TM) */
		MMI_SetHaltFlag(TRUE);
	}
	messId=kobj; /* Anti Warning */
	return NOERR ;
}


/*****************************************************************************
mode 0 : 電卓に被演算数を入力中
mode 1 : 電卓に演算数を入力中
mode 2 : 結果の表示中
*****************************************************************************/

enum {
	OPE_MUL,
	OPE_DIV,
	OPE_PLUS,
	OPE_MINUS
};

static int mode=0;
static int ope;
static char valStr[3][80];

void DentaInitialize(void)
{
	mode=0;
	valStr[0][0]=0;
	valStr[1][0]=0;
	valStr[2][0]=0;
}

int	DentaBtnFunc(int kobj)
{
	switch(mode)
	{
	case 0:
		DentaBtnMode0(kobj);
		break;
	case 1:
		DentaBtnMode1(kobj);
		break;
	case 2:
		DentaBtnMode2(kobj);
		break;
	}
	return NOERR ;
}

static void DentaBtnMode0(int kobj)
{
	int btn;
	switch((btn=DentaBtnNum(kobj)))
	{
	case 17: /* 0 */
	case 18: /* 000 */
	case 13: /* 1 */
	case 14: /* 2 */
	case 15: /* 3 */
	case  9: /* 4 */
	case 10: /* 5 */
	case 11: /* 6 */
	case  5: /* 7 */
	case  6: /* 8 */
	case  7: /* 9 */
	case 12: /* . */
		DentaLetterFunc(btn);
		break;
	case  1: /* * */
		DentaSetOperator(OPE_MUL);
		mode=1;
		break;
	case  2: /* / */
		DentaSetOperator(OPE_DIV);
		mode=1;
		break;
	case  3: /* + */
		DentaSetOperator(OPE_PLUS);
		mode=1;
		break;
	case  4: /* - */
		DentaSetOperator(OPE_MINUS);
		mode=1;
		break;
	case  8: /* = */
		break;
	case 16: /* RET */
		break;
	case 19: /* sqrt */
		DentaSqrt(valStr[0]);
		break;
	}
}

static void DentaBtnMode1(int kobj)
{
	int btn;
	switch((btn=DentaBtnNum(kobj)))
	{
	case 17: /* 0 */
	case 18: /* 000 */
	case 13: /* 1 */
	case 14: /* 2 */
	case 15: /* 3 */
	case  9: /* 4 */
	case 10: /* 5 */
	case 11: /* 6 */
	case  5: /* 7 */
	case  6: /* 8 */
	case  7: /* 9 */
	case 12: /* . */
		DentaLetterFunc(btn);
		break;
	case  1: /* * */
		DentaCalcAnswer();
		DentaFeedBackAnswer(OPE_MUL);
		break;
	case  2: /* / */
		DentaCalcAnswer();
		DentaFeedBackAnswer(OPE_DIV);
		break;
	case  3: /* + */
		DentaCalcAnswer();
		DentaFeedBackAnswer(OPE_PLUS);
		break;
	case  4: /* - */
		DentaCalcAnswer();
		DentaFeedBackAnswer(OPE_MINUS);
		break;
	case  8: /* = */
	case 16: /* RET */
		DentaCalcAnswer();
		break;
	case 19: /* sqrt */
		DentaCalcAnswer();
		DentaSqrt(valStr[2]);
		break;
	}
}

static void DentaBtnMode2(int kobj)
{
	int btn;
	switch((btn=DentaBtnNum(kobj)))
	{
	case 17: /* 0 */
	case 18: /* 000 */
	case 13: /* 1 */
	case 14: /* 2 */
	case 15: /* 3 */
	case  9: /* 4 */
	case 10: /* 5 */
	case 11: /* 6 */
	case  5: /* 7 */
	case  6: /* 8 */
	case  7: /* 9 */
	case 12: /* . */
		DentaAllClear();
		DentaLetterFunc(btn);
		break;
	case  1: /* * */
		DentaFeedBackAnswer(OPE_MUL);
		break;
	case  2: /* / */
		DentaFeedBackAnswer(OPE_DIV);
		break;
	case  3: /* + */
		DentaFeedBackAnswer(OPE_PLUS);
		break;
	case  4: /* - */
		DentaFeedBackAnswer(OPE_MINUS);
		break;
	case  8: /* = */
	case 16: /* RET */
		break;
	case 19: /* sqrt */
		DentaSqrt(valStr[2]);
		break;
	}
}

static int DentaBtnNum(int kobj)
{
	int i;
	for(i=0; i<NUM_BUTTON; i++)
	{
		if(kobj==DentaBtnId[i])
		{
			return i+1;
		}
	}
	DentaSetMsg(ValueMsgId[0],"SEE <NUM_BUTTON>!");
	return 0;
}

static void DentaSetOperator(int o)
{
	ope=o;
	switch(o)
	{
	case OPE_MUL:
		DentaSetMsg(OperatorMsgId,"*");
		break;
	case OPE_DIV:
		DentaSetMsg(OperatorMsgId,"/");
		break;
	case OPE_PLUS:
		DentaSetMsg(OperatorMsgId,"+");
		break;
	case OPE_MINUS:
		DentaSetMsg(OperatorMsgId,"-");
		break;
	}
}

static void DentaSqrt(char *str)
{
	double rt;
	rt=sqrt((double)atof(str));
	sprintf(valStr[2],"%lf",rt);
	DentaClearMsg(ValueMsgId[2]);
	DentaSetMsg(ValueMsgId[2],valStr[2]);
	mode=2;
}

static void DentaLetterFunc(int btnNum)
{
	switch(btnNum)
	{
	case 17: /* 0 */
		DentaAddLetter(mode,'0');
		break;
	case 18: /* 000 */
		DentaAddLetter(mode,'0');
		DentaAddLetter(mode,'0');
		DentaAddLetter(mode,'0');
		break;
	case 13: /* 1 */
		DentaAddLetter(mode,'1');
		break;
	case 14: /* 2 */
		DentaAddLetter(mode,'2');
		break;
	case 15: /* 3 */
		DentaAddLetter(mode,'3');
		break;
	case  9: /* 4 */
		DentaAddLetter(mode,'4');
		break;
	case 10: /* 5 */
		DentaAddLetter(mode,'5');
		break;
	case 11: /* 6 */
		DentaAddLetter(mode,'6');
		break;
	case  5: /* 7 */
		DentaAddLetter(mode,'7');
		break;
	case  6: /* 8 */
		DentaAddLetter(mode,'8');
		break;
	case  7: /* 9 */
		DentaAddLetter(mode,'9');
		break;
	case 12: /* . */
		DentaAddLetter(mode,'.');
		break;
	}
}

static void DentaAddLetter(int n,char let)
{
	char str[80];
	sprintf(str,"%s%c",valStr[n],let);
	strncpy(valStr[n],str,16);
	DentaClearMsg(ValueMsgId[n]);
	DentaSetMsg(ValueMsgId[n],valStr[n]);
}

static void DentaSetMsg(int kobj,char *msg)
{
	MMI_SendMessage(kobj,MM_SETMSG,1,msg);
	MMI_SendMessage(kobj,MM_SHOW,0);
}

static void DentaClearMsg(int kobj)
{
	MMI_SendMessage(kobj,MM_SETMSG,1,"                ");
	MMI_SendMessage(kobj,MM_SHOW,0);
}

static void DentaCalcAnswer(void)
{
	double v1,v2,ans;
	v1=(double)atof(valStr[0]);
	v2=(double)atof(valStr[1]);
	switch(ope)
	{
	case OPE_DIV:
		ans=v1/v2;
		break;
	case OPE_MUL:
		ans=v1*v2;
		break;
	case OPE_PLUS:
		ans=v1+v2;
		break;
	case OPE_MINUS:
		ans=v1-v2;
		break;
	}
	sprintf(valStr[2],"%lf",ans);
	DentaClearMsg(ValueMsgId[2]);
	DentaSetMsg(ValueMsgId[2],valStr[2]);
	mode=2;
}

static void DentaFeedBackAnswer(int ope)
{
	strcpy(valStr[0],valStr[2]);
	DentaClearMsg(ValueMsgId[0]);
	DentaSetMsg(ValueMsgId[0],valStr[2]);

	valStr[1][0]=0;
	DentaClearMsg(ValueMsgId[1]);

	DentaSetOperator(ope);
	mode=1;
}

static void DentaAllClear(void)
{
	int n;
	mode=0;
	for(n=0; n<3; n++)
	{
		valStr[n][0]=0;
		DentaClearMsg(ValueMsgId[n]);
		DentaSetMsg(ValueMsgId[n],valStr[n]);
	}
}


int BackSpaceFunc(void)
{
	int l;
	if((mode==0 || mode==1) && (l=strlen(valStr[mode]))>0)
	{
		valStr[mode][l-1]=0;
		DentaClearMsg(ValueMsgId[mode]);
		DentaSetMsg(ValueMsgId[mode],valStr[mode]);
	}
	return NOERR ;
}

int	AllClearFunc(void)
{
	DentaAllClear();
	return NOERR ;
}
