// Version 1.00 03/10/96  First release as an applet.
//         1.01 21/10/96  Calculator now automatically closed
//                        when all documents have been closed.
//                        Calculator is only centred the first
//                        time it is opened.
//         1.02 13/12/98  Can now handle real decimal point
//                        characters (ASCII 183) as well as
//                        the more common plain full stops.


int calcs_handle;
int calcs_toolbox = 0;
int calcs_total = 0;
int calcs_mem = 0;
int calcs_views = 0;
int calcs_centre = 1;


// read number after caret as a string

string calcs_getnumber(int bm)
{
 int c;
 string s;

 while ((c = bmchar(bm)) >= 48 && c <= 57)
 {
  s = s + chars(c);
  bmmove(bm, 1, 0);
 }
 return s;
}

// covert total to a string

string calcs_tot(void)
{
 string s, t;

 s = itos(calcs_total);
 if (s == "0")
  s = "000";
 t = mids(s, 0, slen(s) - 2);
 s = mids(s, slen(s) - 2, 2);
 if (s != "00")
 {
  if (mids(s, 1, 1) != "0")
   t += "." + s;
  else
   t += "." + mids(s, 0, 1);
 }
 return t;
}


// add number to total

void calcs_calc(int f)
{
 int b1, c;
 string s1, s2;

 if(activetype(TEXTFRAME) <= 1)
  return;

 b1 = bmcreate("calcs_b1");
 setbmtocaret(b1);

 // find start of number
 while ((c = bmprevchar(b1)) >= 48 && c <= 57 || (c == 46 || c == 183))
  bmmove(b1, 0 , 0);

 // get number before decimal point and add '-' if necessary
 s1 = calcs_getnumber(b1);
 if(c == 45)
  s1 = "-" + s1;

 // get number after the decimal point and add to total
 if ((bmchar(b1) == 46) || (bmchar(b1) == 183))
 {
  bmmove(b1, 1, 0);
  s2 = calcs_getnumber(b1);
 }
 if(f)
  calcs_total -= stoi(s1 + mids(s2 + "00", 0, 2));
 else
  calcs_total += stoi(s1 + mids(s2 + "00", 0, 2));

 bmdelete(b1);
 type("{CDown}");

 writeicon(calcs_handle, 0, calcs_tot());
}


// display calculator, centred first time

void calcs_display(void)
{
 display_window(calcs_handle, 0, calcs_centre);
 calcs_centre = 0;
}


// deal with 'Calculator' menu entry

int calcs_entry(int entry,int subcode)
{
 calcs_toolbox = !calcs_toolbox;
 if(calcs_toolbox)
  calcs_display();
 else
  close_window(calcs_handle);

 return(0);
}


// Tick or un-tick 'Calculator' menu entry

int calcs_flags(int entry, string &text)
{
 return(calcs_toolbox);
}


// handler for calc window mouse clicks

void calcs_clicktoolbox(int handle,int icon,int bits,int mx,int my)
{
 if(icon == 1)
  calcs_calc(0);
 if(icon == 2)
  calcs_calc(1);
 if(icon == 3)
  type(calcs_tot());
 if(icon == 4)
 {
  calcs_total = 0;
  writeicon(calcs_handle, 0, calcs_tot());
 }
 if(icon == 5)
  calcs_mem = calcs_total;
 if(icon == 6)
 {
  calcs_total = calcs_mem;
  writeicon(calcs_handle, 0, calcs_tot());
 }
}


// handler for calcs window close icon

void calcs_closetoolbox(int handle)
{
 close_window(handle);
 calcs_toolbox = 0;
}


// count number of views opened and display calculator

void calcs_viewopen(int user, int view)
{
 ++calcs_views;
}


// close calculator when all views have been closed

void calcs_viewclose(int user, int view)
{
 --calcs_views;
 if(!calcs_views)
  close_window(calcs_handle);
}


// open calculator when first document gets input focus

void calcs_gaincaret(int user, int view, int gain)
{
 if(gain && calcs_toolbox && calcs_views == 1)
  calcs_display();
}


// add 'Calculator' option to 'Applets' menu
// create window and add window handlers

void main(void)
{
 script_menu_initialise();

 addentry_menu(script_handle, "calcs_entry","calcs_flags","","","{CALCS_00}");

 calcs_handle = create_window("calcs_main");
 writeicon(calcs_handle, 0, calcs_tot());

 addwindowhandler(0,calcs_handle,"calcs_clicktoolbox");
 addwindowhandler(2,calcs_handle,"calcs_closetoolbox");

 addeventhandler(0x005, 0, "calcs_viewopen");
 addeventhandler(0x006, 0, "calcs_viewclose");
 addeventhandler(0x212, 0, "calcs_gaincaret");
}

