#ifndef IMPROTOCOL_HH_
#define IMPROTOCOL_HH_
#include <config.h>
#include <map>
#include <IMProtocolStruct.h>
#include "basictype.hh"
#include "IMAccept.hh"
#include "IMState.hh"

class ICState;

class IMProtocol
{
  protected:
    IMAccept *pimaccept;

    typedef map<CARD16BIT, IMState*> IMStateMap;
    IMStateMap immap;

    void add_imstate(IMState *pims);
    void remove_imstate(IMState *pims);

  protected:
    IMState* get_imstate(CARD16BIT im_id)
    {
	IMStateMap::iterator it;
	it = immap.find(im_id);
	if (it == immap.end()) return NULL;
	return it->second;
    }
    ICState* get_icstate(CARD16BIT im_id, CARD16BIT ic_id)
    {
	IMState *pims;
	pims = get_imstate(im_id);
	if (!pims) return NULL;
	return pims->get_icstate(ic_id);
    }

  public:
    enum CONTEXT_ID_SPECIAL {
	    INVALID_CONTEXT_ID = 0xFFFF
    };
    bool dispatch(
	CARD16BIT im_id,
	CARD16BIT ic_id,
	void *message
    );

    // concurrency management interface.
    enum CONCURRENCY_FLAGS {
	    SYNC,
	    ASYNC
    };
    virtual bool receive_and_dispatch(IMState *pims, int flags = SYNC) = 0;
    virtual IMState* accept(int flags = SYNC) = 0;

    IMProtocol(IMAccept *pima);
    virtual ~IMProtocol();

  friend class IMState;
};

#endif /* not IMPROTOCOL_HH_ */

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