#ifndef IIIMP_IMSTATE_HH_
#define IIIMP_IMSTATE_HH_
#include <iiimp.h>
#include "basictype.hh"
#include "IMState.hh"
#include "IMHotkeyPrimitive.hh"
#include "IMHotkey.hh"
#include "lexmlconf.h"

class IIIMProtocol;
class IIIMPTrans;
class IIIMP_IMState : public IMState
{
  public:
  typedef pair<u16string, string> UserHostPair;
  typedef std::map<UserHostPair, IIIMP_IMState *> UserIMStateMap;

  private:
    static UserIMStateMap user_imstate_map;
    IIIMPTrans *pimt;
    bool parse_user_name(
	const u16string& uname,
	u16string& username,
	u16string& password,
	string& hostname
    );
    bool send_protocol_version(
	int client_proto_version
    );
    virtual bool message_proc(
	void *message
    );
    virtual void destroy();

  public:
    static IIIMP_IMState *get_imstate_from_desktop(
        iml_desktop_t *desktop
    );
    bool send_trigger_keys();
    bool send_hotkeys(const u16string& curr_input_lang, HotKeyList *hlist);
    bool switch_hotkey_profile();
    void create(IIIMP_IMState *pims);
    bool send(
	IIIMP_message* pmes,
	bool deletep = false
    );
    IIIMPTrans* get_iiimptrans()
    { return pimt; }
    IIIMP_IMState(
	IIIMP_IMState &x,
	int proto_version
    ) : IMState(x, proto_version)
    {
	pimt = x.pimt;
    }
    IIIMP_IMState(
	IIIMProtocol *pimp,
	IIIMPTrans *pimt,
	int proto_version
    );
    friend int update_supported_langlist_for_le(
        iml_desktop_t *desktop,
        IMLEName *lename,
        IMLocale *locales,
        int nLocales
    );
    friend int switch_le_profile(
        iml_desktop_t *desktop,
        IMLEName *lename
    );
};

class IIIMP_IMState_Session;
// In this state, the IM user is correctly identified by IM_CONNECT.
// And waiting the client's request.
class IIIMP_IMState_Identified : public IIIMP_IMState
{
    void exit_from_identified();
    IIIMP_imattribute *create_object_descriptors();
    IIIMP_language *create_language_list(
	const IMLangList *plangs
    );
    IIIMP_imattribute *create_input_method_descriptors();
    bool set_data_to_client();
    IIIMP_imattribute* get_imattribute(
	IIIMP_card16 id
    );
    virtual bool message_proc(
	void *message
    );

  public:
    IIIMP_IMState_Identified(
	IIIMP_IMState *pimt,
	IMHandler *pimh,
	int proto_version
    );
    friend int update_supported_langlist_for_le(
        IMLEName *lename,
        IMLocale *locales,
        int nLocales
    );
    friend int switch_le_profile(
        IMLEName *lename
    );
};

// In this state, the IM receives a request from the client, but
// still continue the session.  Note that transfering it to
// IIIMP_IMState_Identified involves to send the corresponding
// reply message.
class IIIMP_IMState_Session : public IIIMP_IMState
{
    virtual bool message_proc(
	void *message
    );

  public:
    IIIMP_IMState_Session(
	IIIMP_IMState_Identified *pimt
    );
};

#endif /* not IIIMP_IMSTATE_HH_ */

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
