// -*- C++ -*-
#ifndef _kkconv_h_included_
#define _kkconv_h_included_

#include <X11/keysymdef.h>
#include "jmode.h"
#include "keyatom.h"

//Keyが押されたときにICの側ですべきことをKKConvから返り値として
//渡す、各KKConvはKK_PUSHKEY_MASKより上のビットを内部で使用できる。
#define DO_NOTHING 0
#define COMMIT_RAW 1
#define UPDATE_MODE 2
#define PUSHKEY_AGAIN 4
#define COMMIT_WIDE 8
#define KK_PUSHKEY_MASK 255

//各種のkey modifier
// Xのキーイベントと同じ
#define SHIFT_KEY 1
#define CAPS_LOCK 2
#define CTRL_KEY 4
#define ALT_KEY 8
#define KANA_LOCK 8192

class keyEventX;
struct _GdkEventKey;

// もとのイベントから変換を行なって同じ関数内で解放する
class keyState {
public:
    keyState(keyEventX *);
    keyState(_GdkEventKey *);
    int char_code();//文字である場合 0以外になる
    int key_code();// Xもしくはgdkのkeysym
    bool is_modifier();
    int to_lower();
    
    bool modifier(int);// with modifier?
    bool is_push();//キーを押したのか(離したのではなく)
    bool is_alpha();
    atom_t get_atom();
    bool is_bind_to(atom_t a);
    void print();
private:
    int conv_gdk_state(int );
    int conv_keysym_to_charcode(int );
    char *modifier_to_str();
    atom_t atom;
    int m_char_code;//character code
    int m_key_code;// key top sym
    int m_state;
    bool m_bPush;
};

//KKContextはXimICのコンストラクタ中で作られる。
class XimIC;
class Convdisp;
class KKContext {
public:
    KKContext(XimIC *);
    virtual ~KKContext();
    virtual void OnUpdatePe(pe_stat *) = 0;
    virtual int pushKey(keyState *e) = 0;
    virtual int getMode() = 0;
    virtual void setMode(int mode) = 0;
    virtual jstring_t * clear() = 0;
    virtual void candidate_selected(int n);
    virtual bool extra_input(jstring_t *s);//KKContextで処理したかどうか？
    void set_convdisp(Convdisp *);
    XimIC *get_ic();

protected:
    void update_preedit();
    void commit_jstring(jstring_t *);
    XimIC *m_ic;
    pe_stat *m_pe;
    Convdisp *m_convdisp;
};

//一つの変換エンジンを表わす。e.g.SKK,Canna,Wnn etc
class XimIC;
class KKConv {
public:
    virtual char **getIcon()=0;
    virtual void onPushIcon()=0;
    virtual KKContext *createContext(XimIC *)=0;
    virtual char *getModeName(int )=0;
    virtual ~KKConv(){};
};

// candidates
#define CAND_NOP 0
#define CAND_COMMIT 1
#define CAND_EXHAUST 2
#define CAND_CANCEL 4
struct Candidates {
    Candidates();
    void clear();
    int proc_key(keyState *k,jstring_t *s);
    std::vector<jstring_t> cands;
    int nth;
    int opCount;/*候補に対する操作のカウンタ*/
};

bool init_conv();
KKContext *createKKContext(XimIC *);
char **getKKIcon();
void onPushIcon();

void register_kkconv(KKConv *);
cchar ascii_to_wide(cchar);
char *jstring_to_ctext(jstring_t *s);
void ctext_to_jstring(char *,jstring_t *);
void hirakana_conv(jstring_t *d,jstring_t *s);

#endif
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 */
