/*
 * Copyright (c) 2025
 *      libchewing Core Team.
 *
 * See the file "COPYING" for information on usage and redistribution
 * of this file.
 */

#ifndef chewing_public_bindings_h
#define chewing_public_bindings_h

#pragma once

/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/** @brief indicate the internal encoding of data processing.
 *  @since 0.3.0
 */
#define LIBCHEWING_ENCODING "UTF-8"



/**
 * Indicates chewing will translate keystrokes to Chinese characters.
 */
#define CHINESE_MODE 1

/**
 * Indicates the input mode is translating keystrokes to symbols.
 */
#define SYMBOL_MODE 0

/**
 * Indicates chewing will translate latin and puctuation characters to
 * double-with characters.
 */
#define FULLSHAPE_MODE 1

/**
 * Indicates chewing will not translate latin and puctuation characters.
 */
#define HALFSHAPE_MODE 0

/**
 * Use conversion engine that doesn't perform intelligent phrasing.
 */
#define SIMPLE_CONVERSION_ENGINE 0

/**
 * Use the original Chewing intelligent phrasing.
 */
#define CHEWING_CONVERSION_ENGINE 1

/**
 * Use original Chewing intelligent phrasing with fuzzy prefix search.
 */
#define FUZZY_CHEWING_CONVERSION_ENGINE 2

/**
 * Indicates automatic user phrase learning is disabled.
 */
#define AUTOLEARN_DISABLED 1

/**
 * Indicates automatic user phrase learning is enabled.
 */
#define AUTOLEARN_ENABLED 0

/**
 * The minimal size of pre-edit buffer.
 */
#define MIN_CHI_SYMBOL_LEN 0

/**
 * The maximum size of pre-edit buffer.
 */
#define MAX_CHI_SYMBOL_LEN (MAX_PHONE_SEQ_LEN - MAX_PHRASE_LEN)

/**
 * The size of internal buffer for pre-edit buffer.
 */
#define MAX_PHONE_SEQ_LEN 50

/**
 * The maximum phrase size.
 */
#define MAX_PHRASE_LEN 11

/**
 * The number of minimum candidates that are selectable via shortcut keys.
 */
#define MIN_SELKEY 1

/**
 * The number of maximum candidates that are selectable via shortcut keys.
 */
#define MAX_SELKEY 10

/**
 * Log level.
 */
#define CHEWING_LOG_VERBOSE 1

/**
 * Log level.
 */
#define CHEWING_LOG_DEBUG 2

/**
 * Log level.
 */
#define CHEWING_LOG_INFO 3

/**
 * Log level.
 */
#define CHEWING_LOG_WARN 4

/**
 * Log level.
 */
#define CHEWING_LOG_ERROR 5

/**
 * Use "asdfjkl789" as selection key.
 */
#define HSU_SELKEY_TYPE1 1

/**
 * Use "asdfzxcv89" as selection key.
 */
#define HSU_SELKEY_TYPE2 2

#define KEYSTROKE_IGNORE 1

#define KEYSTROKE_COMMIT 2

#define KEYSTROKE_BELL 4

#define KEYSTROKE_ABSORB 8

#define CHEWING_VERSION_MAJOR 0

#define CHEWING_VERSION_MINOR 13

#define CHEWING_VERSION_PATCH 0

/**
 * Keyboard layout index.
 *
 */
typedef enum KB {
  KB_DEFAULT,
  KB_HSU,
  KB_IBM,
  KB_GIN_YIEH,
  KB_ET,
  KB_ET26,
  KB_DVORAK,
  KB_DVORAK_HSU,
  KB_DACHEN_CP26,
  KB_HANYU_PINYIN,
  KB_THL_PINYIN,
  KB_MPS2_PINYIN,
  KB_CARPALX,
  KB_COLEMAK_DH_ANSI,
  KB_COLEMAK_DH_ORTH,
  KB_WORKMAN,
  KB_COLEMAK,
  KB_TYPE_NUM,
} KB;

/**
 * Opaque context handle used for chewing APIs.
 *
 */
typedef struct ChewingContext ChewingContext;

/**
 * Specifies the interval of a phrase segment in the pre-editng area
 */
typedef struct IntervalType {
  /**
   * Starting position of certain interval
   */
  int from;
  /**
   * Ending position of certain interval (exclusive)
   */
  int to;
} IntervalType;

/**
 * Configuration for chewing runtime features.
 *
 * Deprecated, use chewing_set_ series of functions to set parameters instead.
 *
 */
typedef struct ChewingConfigData {
  int candPerPage;
  int maxChiSymbolLen;
  int selKey[MAX_SELKEY];
  int bAddPhraseForward;
  int bSpaceAsSelection;
  int bEscCleanAllBuf;
  int bAutoShiftCur;
  int bEasySymbolInput;
  int bPhraseChoiceRearward;
  int hsuSelKeyType;
} ChewingConfigData;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/**
 * Creates a new instance of the Chewing IM.
 *
 * The return value is a pointer to the new Chewing IM instance.
 *
 * See also the [chewing_new2], and [chewing_delete] functions.
 */
struct ChewingContext *chewing_new(void);

/**
 * Creates a new instance of the Chewing IM.
 *
 * The `syspath` is the directory path to system dictionary. The `userpath`
 * is file path to user dictionary. User shall have enough permission to
 * update this file. The logger and loggerdata is logger function and its
 * data.
 *
 * All parameters will be default if set to NULL.
 *
 * The return value is a pointer to the new Chewing IM instance. See also
 * the [chewing_new], [chewing_delete] function.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
struct ChewingContext *chewing_new2(const char *syspath,
                                    const char *userpath,
                                    void (*logger)(void *data, int level, const char *fmt, ...),
                                    void *loggerdata);

/**
 * Creates a new instance of the Chewing IM.
 *
 * The `syspath` is the directory path to system dictionary. The `userpath`
 * is file path to user dictionary. User shall have enough permission to
 * update this file. The `enabled_dicts` is a comma separated list of
 * dictionary file names.
 *
 * The logger and loggerdata is logger function and its data.
 *
 * All parameters will be default if set to NULL.
 *
 * The return value is a pointer to the new Chewing IM instance. See also
 * the [chewing_new], [chewing_delete] function.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
struct ChewingContext *chewing_new3(const char *syspath,
                                    const char *userpath,
                                    const char *enabled_dicts,
                                    void (*logger_fn)(void *data, int level, const char *fmt, ...),
                                    void *logger_data);

/**
 * Returns the default comma separated dictionary names.
 *
 * This function should be used with [`chewing_new3`].
 *
 * The return value is a const pointer to a character string. The pointer
 * don't need to be freed.
 */
const char *chewing_get_defaultDictionaryNames(void);

/**
 * Releases the resources used by the given Chewing IM instance.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_delete(struct ChewingContext *ctx);

/**
 * Releases the memory allocated by the Chewing IM and returned to the
 * caller.
 *
 * There are functions returning pointers of strings or other data
 * structures that are allocated on the heap. These memory must be freed to
 * avoid memory leak. To avoid memory allocator mismatch between the
 * library and the caller, use this function to free the resources.
 *
 * Do nothing if ptr is NULL.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_free(void *ptr);

/**
 * Reset the context but keep all settings.
 *
 * All preedit buffers are reset to empty.
 *
 * The return value is 0 on success and -1 on failure.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_Reset(struct ChewingContext *ctx);

/**
 * Acknowledge the commit buffer and aux output buffer.
 *
 * Chewing automatically acknowledges and clear the output buffers after
 * processing new input events.
 *
 * After handling the ephemeral output buffer like the commit buffer and
 * the aux output buffer, IM wrappers can proactively acknowledge and clear
 * the buffers. This can be used so that IM wrappers don't have to remember
 * whether an output has been handled or not.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_ack(struct ChewingContext *ctx);

/**
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_config_has_option(const struct ChewingContext *ctx, const char *name);

/**
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_config_get_int(const struct ChewingContext *ctx, const char *name);

/**
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_config_set_int(struct ChewingContext *ctx, const char *name, int value);

/**
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_config_get_str(const struct ChewingContext *ctx, const char *name, char **value);

/**
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_config_set_str(struct ChewingContext *ctx, const char *name, const char *value);

/**
 * Sets the current keyboard layout for ctx.
 *
 * The kbtype argument must be a value defined in [KB][super::public::KB].
 *
 * The return value is 0 on success and -1 on failure. The keyboard type
 * will set to KB_DEFAULT if return value is -1.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_set_KBType(struct ChewingContext *ctx, int kbtype);

/**
 * Returns the current keyboard layout index for ctx.
 *
 * The return value is the layout index defined in [KB][super::public::KB].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_KBType(const struct ChewingContext *ctx);

/**
 * Returns the the current layout name string of ctx.
 *
 * The return value is the name of the current layout, see also function
 * [chewing_KBStr2Num].
 *
 * The returned pointer must be freed by
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_get_KBString(const struct ChewingContext *ctx);

/**
 * Converts the keyboard layout name from string to corresponding layout
 * index.
 *
 * If the string does not match any layout, this function returns
 * KB_DEFAULT.
 *
 * The string str might be one of the following layouts:
 * * KB_DEFAULT
 * * KB_HSU
 * * KB_IBM
 * * KB_GIN_YIEH
 * * KB_ET
 * * KB_ET26
 * * KB_DVORAK
 * * KB_DVORAK_HSU
 * * KB_DVORAK_CP26
 * * KB_HANYU_PINYIN
 * * KB_THL_PINYIN
 * * KB_MPS2_PINYIN
 * * KB_CARPALX
 * * KB_COLEMAK
 * * KB_COLEMAK_DH_ANSI
 * * KB_COLEMAK_DH_ORTH
 * * KB_WORKMAN
 *
 * See also [chewing_kbtype_Enumerate] for getting the list of supported
 * layouts programmatically.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_KBStr2Num(const char *str);

/**
 * Sets the input mode to Chinese or English.
 *
 * The *mode* argument is one of the [CHINESE_MODE] and [SYMBOL_MODE]
 * constants.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_ChiEngMode(struct ChewingContext *ctx, int mode);

/**
 * Returns the current Chinese/English mode setting.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_ChiEngMode(const struct ChewingContext *ctx);

/**
 * Sets the current punctuation input mode.
 *
 * The *mode* argument is one of the [FULLSHAPE_MODE] and [HALFSHAPE_MODE]
 * constants.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_ShapeMode(struct ChewingContext *ctx, int mode);

/**
 * Returns the current punctuation mode.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_ShapeMode(const struct ChewingContext *ctx);

/**
 * Sets the number of candidates returned per page.
 *
 * The setting is ignored if *n* is not between [MIN_SELKEY][super::public::MIN_SELKEY] and
 * [MAX_SELKEY][super::public::MAX_SELKEY] inclusive.
 *
 * The default value is MAX_SELKEY.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_candPerPage(struct ChewingContext *ctx, int n);

/**
 * Gets the number of candidates returned per page.
 *
 * The default value is MAX_SELKEY.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_candPerPage(const struct ChewingContext *ctx);

/**
 * Sets the maximum number of the Chinese characters allowed in the
 * pre-edit buffer.
 *
 * If the pre-edit string is longer than this number then the leading part
 * will be committed automatically. The range of n shall between
 * [MIN_CHI_SYMBOL_LEN][super::public::MIN_CHI_SYMBOL_LEN] and [MAX_CHI_SYMBOL_LEN][super::public::MAX_CHI_SYMBOL_LEN].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_maxChiSymbolLen(struct ChewingContext *ctx,
                                 int n);

/**
 * Returns the maximum number of the Chinese characters allowed in the
 * pre-edit buffer.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_maxChiSymbolLen(const struct ChewingContext *ctx);

/**
 * Sets the key codes for candidate selection.
 *
 * *selkeys* is an ASCII code integer array of length [MAX_SELKEY]. The
 * second argument is unused.
 *
 * The default selection key is `1234567890`.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_selKey(struct ChewingContext *ctx, const int *sel_keys, int len);

/**
 * Returns the current selection key setting.
 *
 * The returned value is a pointer to an integer array. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int *chewing_get_selKey(const struct ChewingContext *ctx);

/**
 * Sets the direction to add new phrases when using CtrlNum.
 *
 * The direction argument is 0 when the direction is backward and 1 when
 * the direction is forward.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_addPhraseDirection(struct ChewingContext *ctx, int direction);

/**
 * Returns the direction to add new phrases when using CtrlNum.
 *
 * The direction argument is 0 when the direction is backward and 1 when
 * the direction is forward.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_addPhraseDirection(const struct ChewingContext *ctx);

/**
 * Sets whether the Space key is treated as a selection key.
 *
 * When the mode argument is 1, the Space key will initiate the candidates
 * selection mode.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_spaceAsSelection(struct ChewingContext *ctx, int mode);

/**
 * Returns whether the Space key is treated as a selection key.
 *
 * Returns 1 when the Space key will initiate the candidates selection
 * mode.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_spaceAsSelection(const struct ChewingContext *ctx);

/**
 * Sets whether the Esc key will flush the current pre-edit buffer.
 *
 * When the mode argument is 1, the Esc key will flush the pre-edit buffer.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_escCleanAllBuf(struct ChewingContext *ctx, int mode);

/**
 * Returns whether the Esc key will flush the current pre-edit buffer.
 *
 * Returns 1 when the Esc key will flush the pre-edit buffer.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_escCleanAllBuf(const struct ChewingContext *ctx);

/**
 * Sets whether the Chewing IM will automatically shift cursor after
 * selection.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_autoShiftCur(struct ChewingContext *ctx, int mode);

/**
 * Returns whether the Chewing IM will automatically shift cursor after
 * selection.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_autoShiftCur(const struct ChewingContext *ctx);

/**
 * Sets the current normal/easy symbol mode.
 *
 * In easy symbol mode, the key be will changed to its related easy symbol
 * in swkb.dat. The format of swkb.dat is key symbol pair per line. The
 * valid value of key is [0-9A-Z]. The lower case character in key will be
 * changed to upper case when loading swkb.dat. However, in easy symbol
 * mode, only [0-9A-Z] are accepted.
 *
 * The mode argument is 0 for normal mode or other for easy symbol mode.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_easySymbolInput(struct ChewingContext *ctx, int mode);

/**
 * Gets the current normal/easy symbol mode.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_easySymbolInput(const struct ChewingContext *ctx);

/**
 * Sets whether the phrase for candidates selection is before the cursor or
 * after the cursor.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_phraseChoiceRearward(struct ChewingContext *ctx, int mode);

/**
 * Returns the phrase choice rearward setting.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_phraseChoiceRearward(const struct ChewingContext *ctx);

/**
 * Sets enable or disable the automatic learning.
 *
 * The mode argument is be one of the [AUTOLEARN_ENABLED][super::public::AUTOLEARN_ENABLED] and
 * [AUTOLEARN_DISABLED][super::public::AUTOLEARN_DISABLED] constants.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_autoLearn(struct ChewingContext *ctx, int mode);

/**
 * Returns whether the automatic learning is enabled or disabled.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_autoLearn(const struct ChewingContext *ctx);

/**
 * Returns the phonetic sequence in the Chewing IM internal state machine.
 *
 * The return value is a pointer to a unsigned short array. The values in
 * the array is encoded Bopomofo phone. The memory must be freed by the
 * caller using function [chewing_free][super::setup::chewing_free].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
unsigned short *chewing_get_phoneSeq(const struct ChewingContext *ctx);

/**
 * Returns the length of the phonetic sequence in the Chewing IM internal
 * state machine.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_phoneSeqLen(const struct ChewingContext *ctx);

/**
 * Sets the external logger callback.
 *
 * The logger function is used to provide log inside Chewing IM for debugging.
 * The user_data pointer is passed directly to the logger when logging.
 *
 * # Examples
 *
 * The following example shows how to use user_data:
 *
 * ```c
 * void logger( void *data, int level, const char *fmt, ... )
 * {
 *     FILE *fd = (FILE *) data;
 *     ...
 * }
 *
 * int main()
 * {
 *     ChewingContext *ctx;
 *     FILE *fd;
 *     ...
 *     chewing_set_logger(ctx, logger, fd);
 *     ...
 * }
 * ```
 *
 * The level is log level.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_logger(struct ChewingContext *ctx, void (*logger_fn)(void *data,
                                                                      int level,
                                                                      const char *fmt,
                                                                      ...), void *logger_data);

/**
 * Starts a userphrase enumeration.
 *
 * Caller shall call this function prior [chewing_userphrase_has_next] and
 * [chewing_userphrase_get] in order to enumerate userphrase correctly.
 *
 * This function stores an iterator in the context. The iterator is only
 * destroyed after enumerate all userphrases using
 * [chewing_userphrase_has_next].
 *
 * Returns 0 on success, -1 on failure.
 *
 * # Examples
 *
 * ```c
 * chewing_userphrase_enumerate(ctx);
 * while (chewing_userphrase_has_next(ctx, &phrase_len, &bopomofo_len)) {
 *     phrase = malloc(phrase_len);
 *     if (!phrase) goto error;
 *     bopomofo = malloc(bopomofo_len);
 *     if (!bopomofo) goto error;
 *
 *     chewing_userphrase_get(ctx, phrase, phrase_len, bopomofo, bopomofo_len);
 *     // ...
 * }
 * ```
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_enumerate(struct ChewingContext *ctx);

/**
 * Checks if there is another userphrase in current enumeration.
 *
 * The *phrase_len* and *bopomofo_len* are output buffer length needed by the userphrase and its bopomofo string.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_has_next(struct ChewingContext *ctx,
                                unsigned int *phrase_len,
                                unsigned int *bopomofo_len);

/**
 * Gets the current enumerated userphrase.
 *
 * The *phrase_buf* and *bopomofo_buf* are userphrase and its bopomofo
 * buffer provided by caller. The length of the buffers can be retrived
 * from [chewing_userphrase_has_next].
 *
 * Returns 0 on success, -1 on failure.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_get(struct ChewingContext *ctx,
                           char *phrase_buf,
                           unsigned int phrase_len,
                           char *bopomofo_buf,
                           unsigned int bopomofo_len);

/**
 * Adds new userphrase to the user dictionary.
 *
 * Returns how many phrases are added, -1 on failure.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_add(struct ChewingContext *ctx,
                           const char *phrase_buf,
                           const char *bopomofo_buf);

/**
 * Removes a userphrase from the user dictionary.
 *
 * Returns how many phrases are removed, -1 on failure.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_remove(struct ChewingContext *ctx,
                              const char *phrase_buf,
                              const char *bopomofo_buf);

/**
 * Searchs if a userphrase is in the user dictionary.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_userphrase_lookup(struct ChewingContext *ctx,
                              const char *phrase_buf,
                              const char *bopomofo_buf);

/**
 * Sets the candidate list to the first (longest) candidate list.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the candidate selection window is not currently
 * open.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_first(struct ChewingContext *ctx);

/**
 * Sets the candidate list to the last (shortest) candidate list.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the candidate selection window is not currently
 * open.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_last(struct ChewingContext *ctx);

/**
 * Checks whether there is a next (shorter) candidate list.
 *
 * Returns 1 (true) when there is a next candidate list, 0 otherwise.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_has_next(struct ChewingContext *ctx);

/**
 * Checks whether there is a previous (longer) candidate list.
 *
 * Returns 1 (true) when there is a previous candidate list, 0 otherwise.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_has_prev(struct ChewingContext *ctx);

/**
 * Changes current candidate list to next candidate list.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the candidate selection window is not currently
 * open.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_next(struct ChewingContext *ctx);

/**
 * Changes current candidate list to previous candidate list.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the candidate selection window is not currently
 * open.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_list_prev(struct ChewingContext *ctx);

/**
 * Commits the current preedit buffer content to the commit buffer.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the IM editor is not in entering state.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_commit_preedit_buf(struct ChewingContext *ctx);

/**
 * Clears the current preedit buffer content.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the IM editor is not in entering state.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_clean_preedit_buf(struct ChewingContext *ctx);

/**
 * Clears the current bopomofo buffer content.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the IM editor is not in entering state.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_clean_bopomofo_buf(struct ChewingContext *ctx);

/**
 * Converts the u16 encoded syllables to a bopomofo string.
 *
 * If both of the buf and the len are 0, this function will return buf
 * length for bopomofo including the null character so that caller can
 * prepare enough buffer for it.
 *
 * Returns 0 on success, -1 on failure.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_phone_to_bopomofo(unsigned short phone, char *buf, unsigned short len);

/**
 * Handles all possible key events.
 *
 * **code**
 *
 * Code that identifies a physical key on a keyboard.
 *
 * Keycodes are the result of the low-level processing of the data that
 * keyboards send to a computer. For instance 36 may represent the return
 * key.
 *
 * Symbolic names are assigned to raw keycodes in order to facilitate
 * their mapping to symbols. By convention keycode names are based on US
 * QWERTY layout. For example the keycode for the return key is
 * RETURN.
 *
 * Chewing keycodes have same numeric encoding as X11 or xkbcommon
 * keycodes.
 *
 * **ksym**
 *
 * The symbol on the cap of a key.
 *
 * Keysyms (short for "key symbol") are translated from keycodes via a
 * keymap. On different layout (qwerty, dvorak, etc.) all keyboards emit
 * the same keycodes but produce different keysyms after translation.
 * The key press / release state and state of modifier keys.
 *
 * **state**
 *
 * Use the state mask to read whether a modifier key is active and
 * whether the key is pressed.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_KeyboardEvent(struct ChewingContext *ctx,
                                 uint8_t code,
                                 uint32_t ksym,
                                 uint32_t state);

/**
 * Handles the Space key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Space(struct ChewingContext *ctx);

/**
 * Handles the Esc key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Esc(struct ChewingContext *ctx);

/**
 * Handles the Enter or Return key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Enter(struct ChewingContext *ctx);

/**
 * Handles the Delete key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Del(struct ChewingContext *ctx);

/**
 * Handles the Backspace key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Backspace(struct ChewingContext *ctx);

/**
 * Handles the Tab key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Tab(struct ChewingContext *ctx);

/**
 * Handles the Left key with the Shift modifier.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_ShiftLeft(struct ChewingContext *ctx);

/**
 * Handles the Left key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Left(struct ChewingContext *ctx);

/**
 * Handles the Right key with the Shift modifier.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_ShiftRight(struct ChewingContext *ctx);

/**
 * Handles the Right key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Right(struct ChewingContext *ctx);

/**
 * Handles the Up key.
 *
 * See also [chewing_cand_close][super::candidates::chewing_cand_close] keyboardless API to close candidate
 * window.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Up(struct ChewingContext *ctx);

/**
 * Handles the Home key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Home(struct ChewingContext *ctx);

/**
 * Handles the End key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_End(struct ChewingContext *ctx);

/**
 * Handles the PageUp key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_PageUp(struct ChewingContext *ctx);

/**
 * Handles the PageDown key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_PageDown(struct ChewingContext *ctx);

/**
 * Handles the Down key.
 *
 * See also [super::io::chewing_cand_open] keyboardless API to open candidate window.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Down(struct ChewingContext *ctx);

/**
 * Handles the Capslock key.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Capslock(struct ChewingContext *ctx);

/**
 * Handles all keys that do not have dedicated methods.
 *
 * The value of of key can be any printable ASCII characters.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Default(struct ChewingContext *ctx, int key);

/**
 * Handles any number key with the Ctrl modifier.
 *
 * The value of key should be in the range between ASCII character code
 * from 0 to 9.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_CtrlNum(struct ChewingContext *ctx, int key);

/**
 * Handles the Space key with the Shift modifier.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_ShiftSpace(struct ChewingContext *ctx);

/**
 * Handles tapping the Tab key twice quickly.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_DblTab(struct ChewingContext *ctx);

/**
 * Handles any numeric key from the keypad.
 *
 * The value of key should be in the range between ASCII character code
 * from 0 to 9.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_handle_Numlock(struct ChewingContext *ctx, int key);

/**
 * Checks whether the commit buffer has something to read.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_commit_Check(const struct ChewingContext *ctx);

/**
 * Returns the string in the commit buffer.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_commit_String(const struct ChewingContext *ctx);

/**
 * Returns the string in the commit buffer.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_commit_Check]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_commit_String_static(const struct ChewingContext *ctx);

/**
 * Returns the current output in the pre-edit buffer.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_buffer_String(const struct ChewingContext *ctx);

/**
 * Returns the current output in the pre-edit buffer.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_buffer_Check]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_buffer_String_static(const struct ChewingContext *ctx);

/**
 * Checks whether there is output in the pre-edit buffer.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_buffer_Check(const struct ChewingContext *ctx);

/**
 * Returns the length of the string in current pre-edit buffer.
 *
 * <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
 * <strong>⚠ Warning:</strong> The length is calculated in terms of
 * unicode characters. One character might occupy multiple bytes.
 * </p>
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_buffer_Len(const struct ChewingContext *ctx);

/**
 * Returns the phonetic characters in the pre-edit buffer.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_bopomofo_Check]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_bopomofo_String_static(const struct ChewingContext *ctx);

/**
 * Returns the phonetic characters in the pre-edit buffer.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_bopomofo_String(const struct ChewingContext *ctx);

/**
 * Returns whether there are phonetic pre-edit string in the buffer.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_bopomofo_Check(const struct ChewingContext *ctx);

/**
 * Returns the current cursor position in the pre-edit buffer.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cursor_Current(const struct ChewingContext *ctx);

/**
 * Checks if the candidates selection has finished.
 *
 * <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
 * <strong>⚠ Warning:</strong> Not implemented.
 * </p>
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_CheckDone(const struct ChewingContext *ctx);

/**
 * Returns the number of pages of the candidates.
 *
 * If the return value is greater than zero, then the IM interface should
 * display a selection window of the candidates for the user to choose a
 * candidate. Otherwise hide the selection window.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_TotalPage(const struct ChewingContext *ctx);

/**
 * Returns the number of the coices per page.
 *
 * See also the [chewing_set_candPerPage] function.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_ChoicePerPage(const struct ChewingContext *ctx);

/**
 * Returns the total number of the available choices.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_TotalChoice(const struct ChewingContext *ctx);

/**
 * Returns the current candidate page number.
 *
 * # Examples
 *
 * The candidates pagination could be displayed as:
 *
 * ```c
 * sprintf(buf, "[%d / %d]",
 *     chewing_cand_CurrentPage(ctx),
 *     chewing_cand_TotalPage(ctx));
 * ```
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_CurrentPage(const struct ChewingContext *ctx);

/**
 * Starts the enumeration of the candidates starting from the first one in
 * the current page.
 *
 * This function stores an iterator in the context. The iterator is only
 * destroyed after enumerate candidates using
 * [chewing_cand_hasNext].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_cand_Enumerate(struct ChewingContext *ctx);

/**
 * Checks if there are more candidates to enumerate.
 *
 * <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
 * <strong>⚠ Warning:</strong> This function checks the end of total choices
 * instead of the end of current page.
 * </p>
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_hasNext(struct ChewingContext *ctx);

/**
 * Returns the current enumerated candidate string.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_cand_String(struct ChewingContext *ctx);

/**
 * Returns the current enumerated candidate string.
 *
 * The returned string is emtpy string when enumeration is over.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_cand_hasNext]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_cand_String_static(struct ChewingContext *ctx);

/**
 * Returns the candidate string by its index.
 *
 * The *index* must be between 0 and [chewing_cand_TotalChoice] inclusive.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_cand_string_by_index(struct ChewingContext *ctx, int index);

/**
 * Returns the candidate string by its index.
 *
 * The *index* must be between 0 and [chewing_cand_TotalChoice] inclusive.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after calling this function.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_cand_string_by_index_static(struct ChewingContext *ctx, int index);

/**
 * Selects the candidate by its index.
 *
 * The *index* must be between 0 and [chewing_cand_TotalChoice] inclusive.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Errors
 *
 * This function fails if the *index* is out of range or the candidate
 * selection window is not currently open.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_choose_by_index(struct ChewingContext *ctx, int index);

/**
 * Opens the candidate selection window.
 *
 * This operation is only allowed when the IM editor is in entering state.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_open(struct ChewingContext *ctx);

/**
 * Closes the candidate selection window.
 *
 * Returns 0 when success, -1 otherwise.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_cand_close(struct ChewingContext *ctx);

/**
 * Starts the enumeration of intervals of recognized phrases.
 *
 * This function stores an iterator in the context. The iterator is only
 * destroyed after enumerate all intervals using
 * [chewing_interval_hasNext].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_interval_Enumerate(struct ChewingContext *ctx);

/**
 * Checks whether there are more intervals or not.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_interval_hasNext(struct ChewingContext *ctx);

/**
 * Returns the current enumerated interval.
 *
 * The *it* argument is an output argument.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_interval_Get(struct ChewingContext *ctx, struct IntervalType *it);

/**
 * Returns whether there is auxiliary string in the auxiliary buffer.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_aux_Check(const struct ChewingContext *ctx);

/**
 * Returns the length of the auxiliary string in the auxiliary buffer.
 *
 * <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
 * <strong>⚠ Warning:</strong> The length is calculated in terms of
 * unicode characters. One character might occupy multiple bytes.
 * </p>
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_aux_Length(const struct ChewingContext *ctx);

/**
 * Returns the current auxiliary string.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_aux_String(const struct ChewingContext *ctx);

/**
 * Returns the current auxiliary string.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_aux_Check]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_aux_String_static(const struct ChewingContext *ctx);

/**
 * Checks whether the previous keystroke is ignored or not.
 *
 * Returns 1 when true, 0 when false.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_keystroke_CheckIgnore(const struct ChewingContext *ctx);

/**
 * Checks whether the previous keystroke is absorbed or not.
 *
 * Returns 1 when true, 0 when false.
 *
 * Absorbed key means the Chewing IM state machine has accepted the key and
 * changed its state accordingly. Caller should check various output
 * buffers to see if they need to update the display.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_keystroke_CheckAbsorb(const struct ChewingContext *ctx);

/**
 * Returns the number of keyboard layouts supported by the Chewing IM.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_kbtype_Total(const struct ChewingContext *_ctx);

/**
 * Starts the enumeration of the keyboard layouts.
 *
 * This function stores an iterator in the context. The iterator is only
 * destroyed after enumerate all keyboard layouts using
 * [chewing_kbtype_hasNext].
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_kbtype_Enumerate(struct ChewingContext *ctx);

/**
 * Checks whether there are more keyboard layouts to enumerate.
 *
 * Returns 1 when there are more and 0 when it's the end of the iterator.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_kbtype_hasNext(struct ChewingContext *ctx);

/**
 * Returns the current enumerated keyboard layout name.
 *
 * The returned string is emtpy string when enumeration is over.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_kbtype_String(struct ChewingContext *ctx);

/**
 * Returns the current enumerated keyboard layout name.
 *
 * The returned string is emtpy string when enumeration is over.
 *
 * The return value is a const pointer to a character string. The pointer
 * is only valid immediately after checking the [chewing_kbtype_hasNext]
 * condition.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
const char *chewing_kbtype_String_static(struct ChewingContext *ctx);

/**
 * Returns whether there are phonetic pre-edit string in the buffer. Here
 * “zuin” means bopomofo, a phonetic system for transcribing Chinese,
 * especially Mandarin.
 *
 * Returns **0** when true, **1** when false.
 *
 * <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
 * <strong>⚠ Warning:</strong> The return value of this function is
 * different from other newer functions that returns boolean value.
 * </p>
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_zuin_Check(const struct ChewingContext *ctx);

/**
 * Returns the phonetic characters in the pre-edit buffer.
 *
 * The bopomofo_count argument is a output argument. It will contain the
 * number of phonetic characters in the returned string.
 *
 * The returned value is a pointer to a character string. The memory must
 * be freed by the caller using function
 * [chewing_free][super::setup::chewing_free].
 *
 * # Failures
 *
 * This function returns NULL when memory allocation fails.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
char *chewing_zuin_String(const struct ChewingContext *ctx, int *zuin_count);

/**
 * This function exists only for backword compatibility.
 *
 * The `chewing_Init` function is no-op now. The return value is always 0.
 */
int chewing_Init(const char *data_path, const char *hash_path);

/**
 * This function exists only for backword compatibility.
 */
void chewing_Terminate(void);

/**
 * Sets the selectAreaLen, maxChiSymbolLen and selKey parameter from pcd.
 *
 * The pcd argument is a pointer to a Chewing configuration data structure.
 * See also the ChewingConfigData data type.
 *
 * The return value is 0 on success and -1 on failure.
 *
 * **Deprecated**, use the chewing_set_* function series to set parameters
 * instead.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_Configure(struct ChewingContext *ctx, struct ChewingConfigData *pcd);

/**
 * This function is no-op now. Use [chewing_set_selKey] instead.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
void chewing_set_hsuSelKeyType(struct ChewingContext *_ctx, int mode);

/**
 * This function is no-op now. Use [chewing_get_selKey] instead.
 *
 * # Safety
 *
 * This function should be called with valid pointers.
 */
int chewing_get_hsuSelKeyType(struct ChewingContext *_ctx);

const char *chewing_version(void);

int chewing_version_major(void);

int chewing_version_minor(void);

int chewing_version_patch(void);

const char *chewing_version_extra(void);

#ifdef __cplusplus
}  // extern "C"
#endif  // __cplusplus

#endif  /* chewing_public_bindings_h */
