/***************************************
 *                                     *
 * SCalc v1.0                          *
 * Extended Workbench Calculator       *
 *                                     *
 * by Volker Stürzl 06.05.90           *
 *                                     *
 ***************************************/

#include <exec/types.h>
#include <intuition/intuition.h>
#include "SCalcGadgets.h"

#define RETURN_OK 0L
#define RETURN_FAIL 20L

struct Window *SCWindow,*OpenWindow();
struct RastPort *SCRP;
double zahl1,zahl2,zahl3,max=1.0e+14,min=9.999999e-14;
long lzahl1,lzahl2,lzahl3;
char num,numnach,mode=10,operator,punkt,minus;
UBYTE zahlstring[30],contstring[7];
UWORD Keyfunc();
void OpenAll(),CloseAll(),Print(),Calcfunc(),Gadfunc(),Ausgabe();
void RectFill(),RefreshGadgets();
void _cli_parse() {}
void _wb_parse() {}

struct NewWindow SCNewWindow =
{
   300,0,
   174,131,
   0,1,
   CLOSEWINDOW | GADGETUP | VANILLAKEY,
   WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
   &Eins,
   NULL,
   NULL,
   NULL,
   NULL,
   0,0,
   0,0,
   WBENCHSCREEN
};

main()
{
   ULONG Class;
   UWORD GadgetNr;
   UBYTE Code;
   struct Gadget *GadgetPtr;
   struct IntuiMessage *message,*GetMsg();

   OpenAll();
   FOREVER
   {
      Wait(1<<SCWindow->UserPort->mp_SigBit);
      while(message=(struct IntuiMessage *)GetMsg(SCWindow->UserPort))
      {
         Class=message->Class;
         ReplyMsg(message);
         switch(Class)
         {
            case CLOSEWINDOW: CloseAll(RETURN_OK);
                              break;
            case GADGETUP:    GadgetPtr=(struct Gadget *)message->IAddress;
                              GadgetNr=GadgetPtr->GadgetID;
                              Gadfunc(GadgetNr);
                              break;
            case VANILLAKEY:  Code=message->Code;
                              Gadfunc(Keyfunc(Code));
                              break;
         }
      }
   }
}

/**************************************
 * Modul Print()                      *
 *                                    *
 * Schreibt text an Position x/y in   *
 * das Fenster.                       *
 *                                    *
 **************************************/
void Print(text,x,y)
UBYTE *text;
long x,y;
{
   Move(SCRP,x,y);
   Text(SCRP,text,strlen(text));
}

/**************************************
 * Modul Ausgabe()                    *
 *                                    *
 * Zeigt die Zahl in Abhängigkeit     *
 * von ihrer Länge und dem gewählten  *
 * Modus im Fenster an.               *
 *                                    *
 **************************************/
void Ausgabe()
{
   Print("                 ",31,23);
   if(mode==16) sprintf(zahlstring,"%lx",lzahl1);
   else
   {   
      if(((zahl1>-max)&&(zahl1<-min))||((zahl1<max)&&(zahl1>min))||(zahl1==0))
         sprintf(contstring,"%%1.%ldf",numnach);
      else sprintf(contstring,"%%e");
      sprintf(zahlstring,contstring,zahl1);
   }
   Print(zahlstring,(167-strlen(zahlstring)*8),23);
}

/**************************************
 * Modul Keyfunc()                    *
 *                                    *
 * Setzt Tasteneingaben in Gadget-    *
 * eingaben um und ruft damit Gad-    *
 * func() auf.                        *
 *                                    *
 **************************************/
UWORD Keyfunc(key)
UBYTE key;
{
   if((key>='1')&&(key<='9')) return(key-48);
   else if((key>='a')&&(key<='f')) return(key-87);
   else
   {
      switch(key)
      {
         case '*': return(27);
                   break;
         case '/': return(28);
                   break;
         case '+': return(25);
                   break;
         case '-': return(26);
                   break;
         case '&': return(23);
                   break;
         case '|': return(24);
                   break;
         case '!': return(21);
                   break;
         case '.': return(17);
                   break;
         case '0': return(16);
                   break;
         case 8:   return(18);
                   break;
         case 127: return(29);
                   break;
         case '\r':return(20);
                   break;
         default:  return(31);
      }
   }
}

/**************************************
 * Modul OpenAll()                    *
 *                                    *
 * Öffnet das SCalc-Fenster,          *
 * initialisiert die Variable SCRP    *
 * (RastPort), setzt Fenster und      *
 * Screen-Titel.                      *
 *                                    *
 **************************************/
void OpenAll()
{
   if(!(SCWindow=OpenWindow(&SCNewWindow))) CloseAll(RETURN_FAIL);
   SCRP=SCWindow->RPort;
   SetAPen(SCRP,2);
   RectFill(SCRP,2,10,171,129);
   SetAPen(SCRP,1);
   SetBPen(SCRP,2);
   RefreshGadgets(&Eins,SCWindow,NULL);
   DrawBorder(SCRP,&AnzeigeBorder,5,15);
   SetWindowTitles(SCWindow,(UBYTE *)"SCalc  v1.0",
    (UBYTE *)"SCalc v1.0 by Volker Stürzl 06.05.90");
   if(mode==10) Print("DEC                0",7,23);
   else Print("HEX                0",7,23);
}

/**************************************
 * Modul CloseAll()                   *
 *                                    *
 * Schließt das Fenster und gibt den  *
 * Return-Wert zurück.                *
 *                                    *
 **************************************/
void CloseAll(code)
long code;
{
   if(code) DisplayBeep(NULL);
   if(SCWindow) CloseWindow(SCWindow);
   exit(code);
}
