// Version 1.00 21/07/98 Expert applet - to better use expert characters
// Shareware by Nick Kaijaks <nick@kaijaks.freeserve.co.uk>

//         1.01   18/01/99 Now uses bmsearch for speed, tidied spaghetti code
//         1.02   21/01/99 Minor bugfix to un-named substyle handling
//         1.03   27/01/99 Missed same fix needed later in the applet <sigh>


int expert_handle;
int expert_status;


string expert_getcurrentsubfont(int font)
{
 int currentsubfonthandle;
 string currentsubfont;

 currentsubfonthandle=getsubfont();
 getfontsubname(font,currentsubfonthandle,0,currentsubfont);
 if (currentsubfont=="(Regular)") currentsubfont=""; else currentsubfont=-currentsubfont;
 return (currentsubfont);
}


int expert_setexpertfont(int font, string csfname)
{
 int donensf,nsfhandle=0;
 string nsfname;

 if (slen(csfname)) csfname="."+csfname;  // prepends a point if there's already a subfont
 donensf=getfontsubname(font,nsfhandle,0,nsfname);
 while (donensf)
 {
  nsfname=-nsfname;
  if (nsfname=="OldStyle"+csfname || nsfname=="OsF"+csfname || nsfname=="Expert"+csfname || nsfname=="SmallCaps"+csfname)
  {
   setsubfont(font,nsfhandle);
   return(1);
  }
  nsfhandle++;
  donensf=getfontsubname(font,nsfhandle,0,nsfname);
 }
 return(0);
}


// if digit is typed and there's an appropriate expert set,
// set the font appropriately

int expert_osf_fix(int user, int view, int key)
{
 int font,csfhandle,foundexpert;
 string csfname,nsfname;

 // OSF as-you-type
 if ((key >= '0' && key <= '9'))
 {
  caretcontext();
  font=getfont();
  csfname=expert_getcurrentsubfont(font);
  csfhandle=getsubfont();          // need csfhandle to return previous font
  foundexpert=expert_setexpertfont(font,csfname);
  if (foundexpert)
  {
   type(chars(key));               // if appropriate font, type digit,
   setsubfont(font,csfhandle);     // return to previous font
   return(0);                      // and exit
  }
 }
 return (key);                     // if not found, just type digit
}


// set up EVENT_KEYPRESS events

void expert_osf_setevent(int i)
{
 if (i)
  addeventhandler(0x300, 0, "expert_osf_fix");
 else
  remeventhandler(0x300, 0, "expert_osf_fix");

 expert_status = i;
}


// deal with 'osf' menu entry

int expert_entry(int entry, int subcode)
{
 if (subcode == -1)
  expert_osf_setevent(!expert_status);
 return(0);
}


// tick or un-tick 'osf as-you-type' menu entry

int expert_flags(int entry, string &text)
{
 return(expert_status);
}


// replace all numerals with osfs

void expert_osf_add(void)
{
 int bm1, bm2, bm3, donedoc, donestory;

 if (!activetype(TEXTFRAME)) return;

 bm1 = bmcreate("expert_caret");
 bm2 = bmcreate("expert_searchstart");
 bm3 = bmcreate("expert_searchend");
 setbmtocaret(bm1);

 bmstartscan();
 donedoc=bmnextstory(bm2);
 while(!donedoc)
 {
  int font, foundexpert;
  string csfname,nsfname;

  donestory=bmsearch(bm2,bm3,"\\d",16);
  while (!donestory)
  {
   setcarettobm(bm2);
   caretcontext();
   setzonetobm(bm3);
   setbmtobm(bm2,bm3);
   font=getfont();
   csfname=expert_getcurrentsubfont(font);
   foundexpert=expert_setexpertfont(font,csfname);
   donestory=bmsearch(bm2,bm3,"\\d",16);
  }
  donedoc=bmnextstory(bm2);
 }
 setcarettobm(bm1);
 if (nselected()) clearselection();
 bmdelete(bm1);
 bmdelete(bm2);
 bmdelete(bm3);
}


// deal with 'experts' menu entries

int expert_menu_entry(int entry, int subcode)
{
 switch(entry)
 {
  case 0:
         expert_osf_add();
         break;
 }
 return(0);
}


int expert_menu(int open)
{
 return(expert_handle);
}


// create 'experts' menu and add it to 'Applets' menu
// enable experts

void main(void)
{
 script_menu_initialise();

 expert_handle = create_menu("{EXPERT_00}");
 addentry_menu(expert_handle,"expert_menu_entry","","","","{EXPERT_01}");
 addentry_menu(expert_handle,"expert_menu_entry","expert_flags","","","{EXPERT_02}");

 addentry_menu(script_handle,"expert_entry","","expert_menu","","{EXPERT_00}");
 expert_osf_setevent(1);
}
