/*{{{  #includes*/
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>

#include <local/bool.h>

#define KEYTAB_C

#include "origami.h"
/*}}}  */

/*{{{  variables*/
private KEY *toplevel[KBD_COUNT];
private KEY *find_current;
public int curr_kbd=0;
/*}}}  */
/*{{{  key_convert_lists key_convert_list*/
/*{{{  keytab codes*/
#define KT_SFB   7
#define KT_SF    6
#define KT_SB    5
#define KT_FB    3
#define KT_S     4
#define KT_F     2
#define KT_B     1
#define KT_NONE  0
/*}}}  */
private char key_convert_list[] = {
  /* O_NOP              */         KT_SFB,
  /*{{{  for macros*/
  /* M_ADD_COUNTER      */         KT_B,
  /* M_BEGIN_FOLD_COMMENT */       KT_B,
  /* M_BEGIN_OF_LINE    */         KT_FB,
  /* M_BEHIND_COUNTER_X */         KT_FB,
  /* M_BOT_OF_FOLD      */         KT_FB,
  /* M_CALL             */         KT_B,
  /* M_CHANGED          */         KT_B,
  /* M_CLOSED_FOLD      */         KT_B,
  /* M_END_FOLD_COMMENT */         KT_B,
  /* M_END_MACRO        */         KT_SB,
  /* M_END_OF_LINE      */         KT_FB,
  /* M_EXIT             */         KT_B,
  /* M_FILED_FOLD       */         KT_B,
  /* M_GO_COUNTER_X_POS */         KT_FB,
  /* M_GO_LINE          */         KT_B,
  /* M_GO_X_POS         */         KT_FB,
  /* M_INT_STRING       */         KT_B,
  /* M_INV_COUNTER      */         KT_B,
  /* M_JMP              */         KT_B,
  /* M_JMP_FALSE        */         KT_B,
  /* M_JMP_TRUE         */         KT_B,
  /* M_LANGUAGE         */         KT_B,
  /* M_NOT              */         KT_B,
  /* M_NULL_COUNTER     */         KT_B,
  /* M_POSITIV_COUNTER  */         KT_B,
  /* M_POS_TO_COUNTER   */         KT_FB,
  /* M_POP_INT          */         KT_SFB,
  /* M_PROMPT           */         KT_NONE,
  /* M_PUSH_INT         */         KT_SFB,
  /* M_READ_REPEAT      */         KT_NONE,
  /* M_SET_COUNTER      */         KT_B,
  /* M_STORE_LINE_NO    */         KT_B,
  /* M_SUM_COUNTER      */         KT_B,
  /* M_TEST_CHAR        */         KT_FB,
  /* M_TEXTLINE         */         KT_B,
  /* M_TOP_OF_FOLD      */         KT_FB,
  /*}}}  */
  /* O_ATTACH_FILE      */         KT_NONE,
  /* O_AUTO_FOLD        */         KT_NONE,
  /* O_AUTO_SAVE        */         KT_B,
  /* O_A_AUTO_SAVE      */         KT_SB,
  /* O_A_ECHO           */         KT_B,
  /* O_A_OVER           */         KT_FB,
  /* O_A_VIEW           */         KT_FB,
  /* O_BOT_OF_FOLD      */         KT_SB,
  /* O_BREAK            */         KT_SB,
  /* O_CAPITALIZE_WORD  */         KT_F,
  /* O_CLOSE_FOLD       */         KT_B,
  /* O_COPY             */         KT_NONE,
  /* O_COPY_PICK        */         KT_SB,
  /* O_CREATE_FOLD      */         KT_S,
  /* O_DEF_FIX          */         KT_B,
  /* O_DEF_MACRO        */         KT_B,
  /* O_DELETE           */         KT_F,
  /* O_DELTO_EOL        */         KT_F,
  /* O_DEL_CHAR_R       */         KT_F,
  /* O_DEL_LINE         */         KT_NONE,
  /* O_DESCRIBE_BINDINGS*/         KT_B,
  /* O_DOWN             */         KT_SB,
  /* O_D_AUTO_SAVE      */         KT_SB,
  /* O_D_ECHO           */         KT_B,
  /* O_D_OVER           */         KT_FB,
  /* O_D_VIEW           */         KT_FB,
  /* O_END_OF_LINE      */         KT_FB,
  /* O_ENTER_FOLD       */         KT_B,
  /* O_EXIT_FOLD        */         KT_B,
  /* O_FILE_FOLD        */         KT_NONE,
  /* O_FILTER_BUFFER    */         KT_NONE,
  /* O_FIND             */         KT_B,
  /* O_FIND_REVERSE     */         KT_B,
  /* O_FINISH           */         KT_B,
  /* O_FIRST_LINE_TO_FOLD_HEADER*/ KT_NONE,
  /* O_FOLD_INFO        */         KT_B,
  /* O_GOTO_LINE        */         KT_B,
  /* O_HELP             */         KT_B,
  /* O_INSERT_FILE      */         KT_NONE,
  /* O_ITS_REVERSE      */         KT_B,
  /* O_ITS_SEARCH       */         KT_B,
  /* O_LANGUAGE         */         KT_NONE,
  /* O_LEFT             */         KT_FB,
  /* O_LOWERCASE_WORD   */         KT_F,
  /* O_MOVE             */         KT_NONE,
  /* O_NEXT_FILE        */         KT_SB,
  /* O_OPEN_FOLD        */         KT_B,
  /* O_OPEN_NEW_FILE    */         KT_SB,
  /* O_PAGE_DOWN        */         KT_SB,
  /* O_PAGE_UP          */         KT_SB,
  /* O_PICK             */         KT_NONE,
  /* O_PIPE_FROM_COMMAND*/         KT_NONE,
  /* O_PIPE_KBD         */         KT_B,
  /* O_PIPE_TO_COMMAND  */         KT_B,
  /* O_PREV_FILE        */         KT_SB,
  /* O_PROMPT           */         KT_SB,
  /* O_PUT_PICK         */         KT_NONE,
  /* O_QUERY_REPLACE    */         KT_NONE,
  /* O_QUIT             */         KT_B,
  /* O_QUOTE            */         KT_NONE,
  /* O_REFRESH          */         KT_SB,
  /* O_REMOVE_FOLD      */         KT_NONE,
  /* O_REPLACE          */         KT_NONE,
  /*{{{  argument-repeat*/
  /* O_REP_0            */         KT_B,
  /* O_REP_1            */         KT_B,
  /* O_REP_2            */         KT_B,
  /* O_REP_3            */         KT_B,
  /* O_REP_4            */         KT_B,
  /* O_REP_5            */         KT_B,
  /* O_REP_6            */         KT_B,
  /* O_REP_7            */         KT_B,
  /* O_REP_8            */         KT_B,
  /* O_REP_9            */         KT_B,
  /*}}}  */
  /* O_RESET_USER_MODE  */         KT_B,
  /* O_RETURN           */         KT_F,
  /* O_RIGHT            */         KT_FB,
  /* O_SAVE_FILE        */         KT_SB,
  /* O_SET_USER_MODE    */         KT_B,
  /* O_SHELL            */         KT_B,
  /* O_SHELL_COMMAND    */         KT_B,
  /* O_START_OF_LINE    */         KT_FB,
  /* O_SUSPEND          */         KT_B,
  /* O_SW_KBD           */         KT_B,
  /* O_TOGGLE_CASE      */         KT_F,
  /* O_TOP_OF_FOLD      */         KT_SB,
  /* O_TRANSPOSE_CHARACTERS*/      KT_F,
  /* O_UNDEL_CHAR       */         KT_F,
  /* O_UNDEL_LINE       */         KT_NONE,
  /* O_UP               */         KT_SB,
  /* O_UPPER_CASE       */         KT_F,
  /* O_WORD_LEFT        */         KT_FB,
  /* O_WORD_RIGHT       */         KT_FB,
  /* O_WRITE_FILE       */         KT_B,
};
/*}}}  */

/*{{{  kbd_change*/
#ifdef STD_C
public void kbd_change(int no)
#else
public kbd_change(no) int no;
#endif
{
  find_current=toplevel[curr_kbd=no];
}
/*}}}  */
/*{{{  set_key_top*/
#ifdef STD_C
public void set_key_top (KEY *top,int no)
#else
public void set_key_top (top,no)
KEY *top;
int no;
#endif
{
  toplevel[no] = top;
  find_current = toplevel[curr_kbd];
}
/*}}}  */
/*{{{  find_key*/
#ifdef STD_C
public int find_key (int key)
#else
public int find_key (key)
int key;
#endif
{
  KEY *find=NULL;

  /*{{{  quoting???*/
  if (find_current==NULL) {
    find_current = toplevel[curr_kbd];
    return(key);
  }
  /*}}}  */
  /*{{{  search in tree*/
  for (find = find_current->n_level;find;find = find->next)
    if (key == find->key) break;
  /*}}}  */
  /*{{{  sequence not found, end search*/
  if (find == NULL) {
    find_current = toplevel[curr_kbd];
    return (keytabend);
  }
  /*}}}  */
  /*{{{  an encoded sequence is found, end search*/
  if (find->code)
    if (find->code==O_QUOTE) {
      find_current=NULL;
      return(keytabcont);
    } else {
      find_current = toplevel[curr_kbd];
      return (find->code);
    }
  /*}}}  */
  /*{{{  the search continues*/
  if (find->n_level) {
    find_current = find;
    return (keytabcont);
  }
  /*}}}  */
  /*{{{  no level below this, the search ends*/
  find_current = toplevel[curr_kbd];
  return (keytabend);
  /*}}}  */
}
/*}}}  */
/*{{{  valid_key*/
#ifdef STD_C
public bool valid_key(bool *keypad, TOKEN *ch)
#else
public bool valid_key(keypad, ch) bool *keypad; TOKEN *ch;
#endif
{
  bool browse_key;

  browse_key = (*keypad && (*ch >= O_NOP) && (key_convert_list[*ch - O_NOP]&KT_B));
  if (browse_mode && !browse_key) {
    message(M_VIEW,TRUE);
    return FALSE;
  } else {
    if (!browse_key && !file_changed) {
      file_changed = TRUE;
      title_op(SET_CF);
    }
    return TRUE;
  }
}
/*}}}  */
/*{{{  valid_field_key check if token is a correct field_key*/
#ifdef STD_C
public bool valid_field_key(bool *keypad,TOKEN *ch)
#else
public bool valid_field_key(keypad, ch) bool *keypad; TOKEN *ch;
#endif
{
  if (*keypad) return (key_convert_list[*ch - O_NOP]&KT_F);
  else return TRUE;
}
/*}}}  */
/*{{{  valid_screen_key*/
#ifdef STD_C
public bool valid_screen_key(bool *keypad,TOKEN *ch)
#else
public bool valid_screen_key(keypad, ch) bool *keypad; TOKEN *ch;
#endif
{
  if (*keypad && select_on)
    return (key_convert_list[*ch - O_NOP]&KT_S);
  else
    return TRUE;
}
/*}}}  */
