/*
 * ConvCalc - Common header includes/defines/etc...
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#include <exec/libraries.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/nodes.h>
#include <exec/lists.h>

#include <devices/keymap.h>

#include <graphics/gfxbase.h>
#include <graphics/displayinfo.h>

#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>

#include <dos/dos.h>
#include <dos/rdargs.h>
#include <dos/dostags.h>

#include <devices/clipboard.h>

#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>

#include <libraries/asl.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/gadtools.h>
#include <libraries/mui.h>

#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>

#include <clib/alib_protos.h>

#include <proto/asl.h>
#include <proto/diskfont.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/iffparse.h>
#include <proto/muimaster.h>
#include <proto/utility.h>
#include <proto/wb.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include <math.h>


#define REG(x) register __ ## x
#define ASM    __asm
#define SAVEDS __saveds

#define SimpleHelpButton(name,helpnode)\
	TextObject,\
		ButtonFrame,\
		MUIA_Text_Contents, name,\
		MUIA_Text_PreParse, "\33c",\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
      MUIA_HelpNode     , helpnode,\
		End

#define KeyHelpButton(name,key,helpnode)\
	TextObject,\
		ButtonFrame,\
		MUIA_Text_Contents, name,\
		MUIA_Text_PreParse, "\33c",\
		MUIA_Text_HiChar  , key,\
		MUIA_ControlChar  , key,\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
      MUIA_HelpNode     , helpnode,\
		End


/*
 * MESSAGE IDs -----------------------------
 */
#define ID_MENU_NEW              101
#define ID_MENU_OPEN             102
#define ID_MENU_SAVE             103
#define ID_MENU_SAVEAS           104
#define ID_MENU_ABOUT            105
#define ID_MENU_QUIT             106
#define ID_MENU_EDITCOPY         111
#define ID_MENU_EDITPASTE        112
#define ID_MENU_PREFSCLRVERIFY   121
#define ID_MENU_PREFSSAVE        122
#define ID_MENU_RUNMACRO         131
#define ID_MENU_SETPRECISION     141
#define ID_MENU_SETUNITDEFNS     142
#define ID_MENU_PREC1            151
#define ID_MENU_PREC2            152
#define ID_MENU_PREC3            153
#define ID_MENU_PREC4            154
#define ID_MENU_PREC5            155
#define ID_MENU_PREC6            156
#define ID_MENU_PREC7            157

#define ID_BUT_FRAC1_2           1001
#define ID_BUT_FRAC1_3           1002
#define ID_BUT_FRAC1_4           1003
#define ID_BUT_FRAC1_8           1004
#define ID_BUT_FRAC1_16          1005
#define ID_BUT_C                 1006
#define ID_BUT_CE                1007
#define ID_BUT_DIVIDE            1008
#define ID_BUT_MULTIPLY          1009
#define ID_BUT_7                 1010
#define ID_BUT_8                 1011
#define ID_BUT_9                 1012
#define ID_BUT_MINUS             1013
#define ID_BUT_4                 1014
#define ID_BUT_5                 1015
#define ID_BUT_6                 1016
#define ID_BUT_Plus              1017
#define ID_BUT_1                 1018
#define ID_BUT_2                 1019
#define ID_BUT_3                 1020
#define ID_BUT_0                 1021
#define ID_BUT_DECIMAL           1022
#define ID_LIS_CALCULATE         1023
#define ID_POP_UNITS             1024
#define ID_BUT_EQUAL             1025

#define ID_UDFN_CLOSEWINDOW      2001
#define ID_BUT_UDFNPOPNEW        2002
#define ID_LIS_UDFNPOPDEL        2003
#define ID_BUT_UDFNUNITSNEW      2004
#define ID_BUT_UDFNNAMEACK       2005
#define ID_BUT_UDFNFACTORACK     2006
#define ID_BUT_UDFNBASEACK       2007
#define ID_BUT_UDFNBASENAMEACK   2008
#define ID_LIS_UDFNUPDATE        2009
#define ID_LIS_UDFNPOPUPDATE     2010
#define ID_BUT_UDFNOK            2011
#define ID_BUT_UDFNCANCEL        2012


/*
 * GENERAL DEFINES ----------------------------------
 */
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))

#define FILEID_HEADER      "CONVCALCV2_JMH2A"

#define ENDWINDOW_OK       1
#define ENDWINDOW_CANCEL   0

#define SUCCESS 0L
#define FAILURE 1L
#define STOPRUN -1

#define MAX_BASE_COUNT  64
#define MAX_UNIT_COUNT  128


/*
 * APP-TEMPLATE FUNCTION PROTOTYPES -----------------
 */
void  JMH_About( void );
LONG  JMH_Error( char *, APTR, char *, char *, LONG );
void  JMH_InitVars( void );
void  JMH_Startup( int, char ** );
char *JMH_Trim( char *, char *, BYTE );
void  JMH_Quit( char * );


/*
 * STRUCTURE DEFINITIONS ----------------------------
 */
struct MyGlobals {
   APTR  App;
   APTR  menustrip;
   APTR  WIN_Main, WIN_UDfn;

   struct DiskObject  *dobj_App;
   char                szProjectSpec[ FMSIZE+1 ];

   struct IOClipReq   *pClipIO;
   struct MsgPort     *pClipMP;

   BOOL   fStartNewNumber;
   BOOL   fDecimalTyped;
   BOOL   running;

   UBYTE  ubPrecision;

   struct Base        *pBaseBase;
   UWORD               uwNumBases;
};
struct MainWindow
{
   APTR  TXT_Input,        TXT_Output,      TXT_PopText,    POP_Units,
         LIS_PopUnits,     LIS_FromUnits,   LIS_ToUnits,
         BUT_Frac1_2, BUT_Frac1_3, BUT_Frac1_4, BUT_Frac1_8, BUT_Frac1_16,
         BUT_C,       BUT_CE,      BUT_Divide,  BUT_Multiply,
         BUT_7,       BUT_8,       BUT_9,       BUT_Minus,
         BUT_4,       BUT_5,       BUT_6,       BUT_Plus,
         BUT_1,       BUT_2,       BUT_3,
         BUT_0,                    BUT_Decimal, BUT_Enter,
         BUT_Calculate;
};
struct UnitDefnsWindow {
   APTR  STR_BaseName, POP_BasePopper,
         LIS_PopList , BUT_PopNew    , BUT_PopDel,
         LIS_UnitList, BUT_UnitsNew  , BUT_UnitsDel,
         STR_BaseUnit, STR_UnitFactor, STR_UnitName,
         BUT_OK      , BUT_Cancel;
};

struct Base {
   UBYTE  szBaseName[20+1];
   UBYTE  szBaseUnit[20+1];
   UWORD  uwNumUnits;
   struct Unit *pUnitBase;
};
struct Unit {
   UBYTE   szUnitName[20+1];
   double  dblFactor;
};


/*
 * APPLICATION FUNCTION PROTOTYPES ------------------
 */
void fnFreeData( void );
void fnFillListWithBases( Object * );
void fnFillListWithUnits( Object *, UWORD );
BOOL fnReallocList( Object *, UWORD );
void fnFillUDfnList( Object *, UWORD );
ULONG fnReadData( char * );
BOOL fnWriteData( BOOL );
void fnAddFraction( double );
void fnAddDigit( char * );
void fnNew( void );
void fnClear( void );
LONG fnClipCopy( void );
LONG fnClipPaste( void );
void fnConvert( void );
void fnTokenizeValue( double *, UWORD * );
void fnTokenizeToken( double, double *, UWORD * );
void fnRecalc( double *, UWORD * );
BOOL fnConstructMainWindow( void );
