//
//  There is a single InputMethod object in an application, and you can access
//  it using KimeraApp::inputmethod(). 
//

#ifndef INPUTMETHOD_H
#define INPUTMETHOD_H

#include "kimeraapp.h"
#include <qwidget.h>
#include <qstring.h>
#include <qptrlist.h>
#include <qbuffer.h>
#include <X11/Xlib.h>

class XIMethod;
class KanjiConvert;
class InputMode;

class InputMethod : public QWidget {
  Q_OBJECT

public:
  void init();

signals:
  void triggerNotify(bool);   // TRUE: on   FALSE: off
  void setInputMode(const InputMode&);

protected:
  void customEvent(QCustomEvent*);
  void recvSelectionEvent(const QEvent* e);
  void recvSelectionRequest(const XEvent&) const;
  void recvSelectionClear();
  void recvXTransportConnection(const XEvent&);
  void recvXIMConnect(const XEvent&);
  void recvXIMDisconnect(const XEvent&);
  void recvXIMOpen(const XEvent&);
  void recvXIMClose();
  void recvXIMQureyExtension();
  void recvXIMEncodingNegotiation();
  void recvXIMGetIMValues();
  void recvXIMCreateIC();
  void recvXIMDestroyIC();
  void recvXIMGetICValues();
  void recvXIMSetICValues();
  void recvXIMSetICFocus();
  void recvXIMUnsetICFocus();
  void recvXIMTriggerNotify();
  void recvXIMError();
  void recvProperty(const XEvent&);
  void recvXIMForwardEvent();
  void recvXIMResetIC();
  void recvXIMSync();
  void recvXIMSyncReply();
  //void sendXIMCommit(const XKeyEvent&) const;
  void sendXIMSetEventMask(ushort, ushort, ulong fwrd = 0, ulong sync = 0) const;
  void sendXIMRegisterTriggerkeys(ushort im) const;
  void sendXIMSync() const;
  void sendClientMessageProtocol(Window w, XClientMessageEvent&) const;
  void sendClientMessageMoredata(Window w, XClientMessageEvent&) const;
  void sendClientMessage(const QByteArray&) const;
  void sendPropertywithCM(const QByteArray&) const;
 
  QPoint calcPreeditPoint(ushort im = 0, ushort ic = 0) const;
  //QPoint calcPreeditPoint();  
  inline ushort numberElements(int n) const { return (n % 4) ? n/4+1 : n/4; }
  inline int pad(int n) const { return (4 - (n % 4)) % 4; }

  virtual void keyPressEvent(QKeyEvent*);

protected slots:
  void slotDecidePhases(const QString&);

private:
  InputMethod();
  ~InputMethod();

  Window  _curwin;    // current client communication window ID
                      //   for XTransportConnection, XIMOpen, XIMClose,
                      //   XIMConnect and XIMDisconnect messages.
  ushort  _curimid;   // current input method ID
  ushort  _curicid;   // current input context ID
  Atom    _xim_servers; 
  Atom    _server_atom;
  Atom    _xim_xconnect; 
  Atom    _xim_protocol; 
  Atom    _xim_moredata; 
  Atom    _locales;
  Atom    _transport;
  Atom    _compound_text;
  Atom    _kimera_atom;
  XIMethod*      _xim;
  KanjiConvert*  _kanjiconvt;
  QBuffer*       _buffer;       // Buffer to receive ClientMessage
  
public:
  enum { 
    // dividing size between ClientMessage and Property
    DIVIDINGSIZE = 100,

    // Major Protocol number  
    XIM_CONNECT = 1,
    XIM_CONNECT_REPLY = 2,
    XIM_DISCONNECT = 3,
    XIM_DISCONNECT_REPLY = 4,
    XIM_AUTH_REQUIRED = 10,
    XIM_AUTH_REPLY = 11,
    XIM_AUTH_NEXT = 12,
    XIM_AUTH_SETUP = 13,
    XIM_AUTH_NG = 14,
    XIM_ERROR = 20,
    XIM_OPEN = 30,
    XIM_OPEN_REPLY = 31,
    XIM_CLOSE = 32,
    XIM_CLOSE_REPLY = 33,
    XIM_REGISTER_TRIGGERKEYS = 34,
    XIM_TRIGGER_NOTIFY = 35,
    XIM_TRIGGER_NOTIFY_REPLY = 36,
    XIM_SET_EVENT_MASK = 37,
    XIM_ENCODING_NEGOTIATION = 38,
    XIM_ENCODING_NEGOTIATION_REPLY = 39,
    XIM_QUERY_EXTENSION = 40,
    XIM_QUERY_EXTENSION_REPLY = 41,
    XIM_SET_IM_VALUES = 42,
    XIM_SET_IM_VALUES_REPLY = 43,
    XIM_GET_IM_VALUES = 44,
    XIM_GET_IM_VALUES_REPLY = 45,
    XIM_CREATE_IC = 50,
    XIM_CREATE_IC_REPLY = 51,
    XIM_DESTROY_IC = 52,
    XIM_DESTROY_IC_REPLY = 53,
    XIM_SET_IC_VALUES = 54,
    XIM_SET_IC_VALUES_REPLY = 55,
    XIM_GET_IC_VALUES = 56,
    XIM_GET_IC_VALUES_REPLY = 57,
    XIM_SET_IC_FOCUS = 58,
    XIM_UNSET_IC_FOCUS = 59,
    XIM_FORWARD_EVENT = 60,
    XIM_SYNC = 61,
    XIM_SYNC_REPLY = 62,
    XIM_COMMIT = 63,
    XIM_RESET_IC = 64,
    XIM_RESET_IC_REPLY = 65
  };
  // Extension major protocol number
  //XIM_EXT_SET_EVENT_MASK = 129,
  //XIM_EXT_FORWARD_KEYEVENT = 130,
  //XIM_EXT_MOVE = 131 };

  
  friend class KimeraApp;
};


#endif // INPUTMETHOD_H





