//->abbrev

int abbrev_handle;
int abbrev_status;
string abbrev_string;
string abbrev_path;


// read abbreviation data from 'abbrevs' file

void abbrev_readdata()
{
 int h;
 string s;

 abbrev_string = "";
 h = fileopen(abbrev_path, "rb");
 if (h)
  while(!fileeof(h))
  {
   if(filereads(s, h)) break;
   abbrev_string += s;
  }
 else
 {
  h = fileopen(abbrev_path, "wb+");
  osclis("settype " + abbrev_path + " text");
 }
 if (h)
  fileclose(h);
}


// search for string t in string s, and set t to expanded text

int abbrev_find(string s, string &t)
{
 int p, b, e;

 if((p = -s / -t) >= 0)
 {
  b = p + slen(t);
  for(e = b; mids(s, e, 1) != "\n" && e != slen(s); ++e);
   t = mids(s, b, e - b);
 }
 return p;
}


// if character typed is a word terminator, read previous word 
// and if it is an abbreviation, replace it with the expansion

int abbrev_fix(int user, int view, int key)
{
 int b1, l, i;
 string s;

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

 // check if key is 'space', 'new para', 'tab', 'new line', 'new page', 'full stop' or 'comma'
 if (key == ' ' || key == 13 || key == 394 || key == 2061 || key == 6669 || key == '.' || key == ',')
 {
  b1 = bmcreate("abbrev_b1");
  setbmtocaret(b1);

  // find start of current word
  while(bmprevchar(b1) > 32 && bmprevchar(b1) < 256)
  {
   bmmove(b1, 0, 0);
   ++l;
  }

  // read to end of current word
  for(i = 0; i < l; ++i)
  {
   s += chars(bmchar(b1));
   bmmove(b1, 1, 0);
  }

  // substitute abbreviation with expansion
  if(s != "")
  {
   s = "/" + s + "/";
   i = abbrev_find(abbrev_string, s);
   if(i >= 0)
    type("{Deleteb}" * l + s);
  }
  bmdelete(b1);


 }
 return(key);
}


// set up EVENT_KEYPRESS events

void abbrev_setevent(int i)
{
 if (i)  
  addeventhandler(0x300, 0, "abbrev_fix");
 else
  remeventhandler(0x300, 0, "abbrev_fix");

 abbrev_status = i;
}


// deal with 'Abbreviations' menu entry

int abbrev_entry(int entry, int subcode)
{
 if(subcode == -1)
  abbrev_setevent(!abbrev_status);
 return(0);
}


// tick or un-tick 'Abbreviations' menu entry

int abbrev_flags(int entry, string &text)
{
 return(abbrev_status);
}


// deal with 'Abbreviations' menu entries

int abbrev_menu_entry(int entry, int subcode)
{
 switch(entry)
 {
  case 0:
         osclis("filer_run " + abbrev_path);
         break;
  case 1:
         abbrev_readdata();
         break;
 }
 return(0);
}


int abbrev_menu(int open)
{
 return(abbrev_handle);
}


// create 'Abbreviations' sub-menu and add it to 'Applets' menu
// read data and enable abbreviation expansion

void main(void)
{
 script_menu_initialise();

 abbrev_path = "OvationPro$AppletsDir";
 getenvs(abbrev_path);
 abbrev_path += ".!Abbrev.abbrevs";

 abbrev_handle = create_menu("{ABBREV_00}");
 addentry_menu(abbrev_handle, "abbrev_menu_entry","","","","{ABBREV_01}");
 addentry_menu(abbrev_handle, "abbrev_menu_entry","","","","{ABBREV_02}");

 addentry_menu(script_handle,"abbrev_entry","abbrev_flags","abbrev_menu","","{ABBREV_00}");
 abbrev_readdata();
 abbrev_setevent(1);
}
