#include "global.h"
#include "memory.h"
#include "rem.h"
#include "df.h"
#include "RMFBuffer.h"
#include "d1Args.h"
#include "bool.h"

#define FT_INITED (1<<0)
Darray      FieldTypeNames_GR;
AlFieldType DefaultFT_GR;

#define RU_INITED (1<<1)
Darray      VerbNames_GR;
Darray      Verbs_GR;

#define RL_INIT (1<<2)
Darray      RegFTs_GR;          /* names of regular field types */
Darray 	    StateFTs_GR;        /* names of state field types */
Darray      StateFC_def_FTs_GR; /* Field type names for each state */
Biregistry  NameToFC_GR;
Darray      FieldTypePresOrder_GR; 
Darray      VerbPresOrder_GR; 

#define MT_INIT (1<<3)
Darray    MsgTypeNames_GR;

RMFBuffer reid_Add_translation PROTOTYPE((RMFBuffer,char*,char*,int));
RMFBuffer reid_Add_simple PROTOTYPE((RMFBuffer,char*,int));

/* This tale overerides translations for ascii string widgets so that we can */
 /* tell when a rule has been modified */

char * ModifyRuleTransTable[]={
"Ctrl<Key>F:		forward-character() ",
"    <Key>0xff53:		forward-character() ",
"     Ctrl<Key>B:		backward-character() ",
"     <Key>0xff51:		backward-character() ",
"     Meta<Key>F:		forward-word() ",
"     Meta<Key>B:		backward-word() ",
"     Meta<Key>]:		forward-paragraph() ",
"     Ctrl<Key>[:		backward-paragraph() ",
"     Ctrl<Key>A:		beginning-of-line() ",
"     Ctrl<Key>E:		end-of-line() ",
"     Ctrl<Key>N:		next-line() ",
"     <Key>0xff54:		next-line() ",
"     Ctrl<Key>P:		previous-line() ",
"     <Key>0xff52:		previous-line() ",
"     Ctrl<Key>V:		next-page() ",
"     Meta<Key>V:		previous-page() ",
"     Meta<Key>\\<:		beginning-of-file() ",
"     Meta<Key>\\>:		end-of-file() ",
"     Ctrl<Key>Z:		scroll-one-line-up() ",
"     Meta<Key>Z:		scroll-one-line-down() ",
"=     Ctrl<Key>D:		delete-next-character() ",
"=     Ctrl<Key>H:		delete-previous-character() ",
"=     <Key>0xff7f:		delete-previous-character() ",
"=     <Key>0xffff:		delete-previous-character() ",
"=     <Key>0xff08:		delete-previous-character() ",
"=     Meta<Key>D:		delete-next-word() ",
"=     Meta<Key>H:		delete-previous-word() ",
"=     Shift Meta<Key>D:		kill-word() ",
"=     Shift Meta<Key>H:		backward-kill-word() ",
"=     Ctrl<Key>W:		kill-selection() ",
"=     Ctrl<Key>K:		kill-to-end-of-line() ",
"=     Meta<Key>K:		kill-to-end-of-paragraph() ",
"=     Ctrl<Key>Y:		unkill() ",
"=     Meta<Key>Y:		stuff() ",
"=     Ctrl<Key>J:		insert-char() ",
"=     <Key>0xff0a:		insert-char() ",
"=     Ctrl<Key>O:		insert-char() ",
"=     Ctrl<Key>M:		insert-char() ",
"=     <Key>0xff0d:		insert-char() ",
"     Ctrl<Key>L:		redraw-display() ",
"     Meta<Key>I:		insert-file() ",
"     <FocusIn>:			focus-in() ",
"     <FocusOut>:		focus-out() ",
"     <Btn1Down>:		select-start() ",
"     Button1<PtrMoved>:		extend-adjust() ",
"     <Btn1Up>:			extend-end() ",
"=     <Btn2Down>:		stuff() ",
"     <Btn3Down>:		extend-start() ",
"     Button3<PtrMoved>:		extend-adjust() ",
"     <Btn3Up>:			extend-end() ",
"=     <Key>:			insert-char() ",
"=     Shift<Key>:		insert-char()",
(char*)NULL,
};

/*--------------------------------------------------*/
reid reid_Create(InitTK,Rule,SaveFunc,QuitFunc,argc,argv,
		 title,Graphic,UserData)
Bool InitTK;
AlRule Rule;
ReSaveFunc* SaveFunc;
ReQuitFunc* QuitFunc;
int* argc;
char** argv;
char *title;
XImage* Graphic;
VOIDP UserData;
{
  reid rei;
  char reidadd[50];
  rei=(reid)Memory_allocate(sizeof(struct reid_str));

  /*------------------------------ Client Application stuff */
  rei->Rule=Rule;
  rei->InitTK=InitTK;
  rei->SaveFunc=SaveFunc;
  rei->QuitFunc=QuitFunc;
  rei->argc=argc;
  rei->argv=argv;
  rei->title=title;
  rei->Graphic=Graphic;
  rei->UserData=UserData;

  /*----------------------------- Display 1 (d1) Globals */
  rei->IfW=NULL;
  rei->ThenW=NULL;
  rei->Then_Contents=NULL;
  rei->Actions=Darray_create();
  rei->ShellW=NULL;
  rei->DoingW=NULL;
  rei->OuterW=NULL;

  /*---------------------------- Rule (ru) globals */
  rei->TopLevelMember=NULL;
  /*---------------------------- Editing (ed) globals */
  rei->WidgetKillList=NULL;
  rei->Modified=Bool_FALSE;
  sprintf(reidadd,"%d",(long int)rei);
  {
    int i;
    char* modifyFunction, *line;
    RMFBuffer mod=RMFBuffer_create("rl_Modified_rule(",20);
    RMFBuffer ret=RMFBuffer_create(NULL,250);
    RMFBuffer_append(mod,reidadd);
    RMFBuffer_append_char(mod,')');
    modifyFunction=RMFBuffer_copy_of_buff(mod);
    i=0;
    while ((line=ModifyRuleTransTable[i++])!=NULL) {
      if (line[0]=='=')
	reid_Add_translation(ret,&(line[1]),modifyFunction,i-1);
      else
	reid_Add_simple(ret,line,i-1);
    }
    
    rei->ModifyRuleTTable=RMFBuffer_copy_of_buff(ret);
    RMFBuffer_destroy(mod);
    RMFBuffer_destroy_chunk(mod,modifyFunction);
    RMFBuffer_destroy(ret);
  }
  return(rei);
}  

static Bool RE_Inited=Bool_FALSE;


/*--------------------------------------------------*/
NORET reid_GlobalInit()
{
  char *ftn;
  if (RE_Inited==Bool_FALSE) {
    /*-------------------- Field Type stuff */
    FieldTypeNames_GR=Darray_create();
    AlFTreg_get_all_field_types(FieldTypeNames_GR);
    if (Darray_len(FieldTypeNames_GR)<1)
      Al_fatal_error("ruleeditor: No Field Types available.\n");
    ftn=df_Get(DEFAULT_FT_NAME);
    if (AlFTreg_exists_string(ftn)==Bool_FALSE)
      ftn=(char*)Darray_get(FieldTypeNames_GR,(unsigned)0);
    DefaultFT_GR=AlFTreg_string_to_obj(ftn);

    /*-------------------- Msg type Stuff */
    MsgTypeNames_GR=Darray_create();
    AlMTreg_get_all_msg_type_names(MsgTypeNames_GR);

    /*-------------------- Verb Stuff */
    Verbs_GR=Darray_create();
    VerbNames_GR=Darray_create();
    AlVerbReg_get_verbs(VerbNames_GR,Verbs_GR);

    RE_Inited=Bool_TRUE;
  }
}

/*--------------------------------------------------*/
RMFBuffer reid_Add_translation(old,trans1,function,suppress)
RMFBuffer old;
char *trans1, *function;
int suppress;
{
  if (suppress!=0) {
    RMFBuffer_append_char(old,'\n');
  }
  RMFBuffer_append(old,trans1);
  RMFBuffer_append_char(old,' ');
  RMFBuffer_append(old,function);
  return(old);
}

/*--------------------------------------------------*/
RMFBuffer reid_Add_simple(old,trans1,suppress)
RMFBuffer old;
char *trans1;
int suppress;
{
  if (suppress!=0) {
    RMFBuffer_append_char(old,'\n');
  }
  RMFBuffer_append(old,trans1);
  return(old);
}

