#ifndef IMBasicObject_HH_
#define IMBasicObject_HH_
#include <list>
#include <map>
#include <functional>
#include <IMProtocolStruct.h>
#include <IMLock.hh>
#include "basictype.hh"
#include "SunIM.h"

class IMLang
{
    string identifier;
    u16string hrn;
  public:
    const char* get_id() const
    { return identifier.c_str(); }
    const u16string& get_hrn() const
    { return hrn; }

    bool operator <(const IMLang &b)
    {
	return (identifier.compare(b.identifier) < 0);
    }
    bool operator ==(const IMLang &b)
    {
	return (identifier.compare(b.identifier) == 0);
    }

    IMLang(
	const char *id,
	const u16string& x_hrn
    )
	: identifier(id), hrn(x_hrn)
    {}
};

inline bool
operator==(const IMLang& lang, const std::string& l)
{
    return (l.compare(lang.get_id()) == 0);
}
// some older g++ needs
inline bool
operator!=(const IMLang&lang, const std::string& l)
{
    return (l.compare(lang.get_id()) != 0);
}

typedef list<IMLang> IMLangList;

/*
  SYMBOL-ID
  4   : CARD32 :  MSB  --------------------------> LSB
  +----------+---------+-+-----------+
  | reserved | TYPEBIT |1|  IDBITS   |
  +----------+---------+-+-----------+
  |<--8bits->|<--8bit->| |<-15bits-->|
  TYPEBITS : 0:RESERVED for ATTRIBID
  1: operation,

  2: variable(number),
  3: valriable(bool),
  4: variable(char),
  5: variable(mtext),
  6: variable(event),

  0x12:property(number),
  0x13:property(bool),
  0x14:property(char),
  0x15:property(mtext),
  0x16:property(event),

  0x81:EIMIL,
  0x82:IMDESCRIPTOR,
  0x83:BINARY_GUI,
  0x84:BINARY_LWE,
  0x85:JAVA_GUI,
  0x86:JAVA_LWE
*/
class IMObject
{
  public:
    enum OBJTYPE {
	    UNKNOWN,

	    OPERATION = 1,

	    NUMBER_VARIABLE = 2,
	    BOOL_VARIABLE = 3,
	    CHAR_VARIABLE = 4,
	    MTEXT_VARIABLE = 5,
	    EVENT_VARIABLE = 6,

	    NUMBER_PROPERTY = 0x12,
	    BOOL_PROPERTY = 0x13,
	    CHAR_PROPERTY = 0x14,
	    MTEXT_PROPERTY = 0x15,
	    EVENT_PROPERTY = 0x16,

	    DOWNLOADABLE_OBJ_MASK = 0x80,
	    EIMIL_CONFIG = 0x81,
	    IMDESCRIPTOR = 0x82,
	    BINARY_GUI = 0x83,
	    BINARY_LWE = 0x84,
	    JAVA_GUI = 0x85,
	    JAVA_LWE = 0x86,
	    SCRIPT_GUI = 0x87,
	    SCRIPT_LWE = 0x88
    };
    enum OBJCATEGORY {
	    UNKNOWN_OBJECT = -1,
	    GUI_OBJECT = 0,
	    LWE_OBJECT = 1,
	    SYNTAX_RULE_OBJECT = 2,
	    IM_MANAGER_RULE_OBJECT = 3,
	    PRELOADING_LWE_OBJECT = 4
    };
  private:
    CARD32BIT id;
    enum OBJTYPE type;
    bool downloadable;
    
  protected:
    IMObject(enum OBJTYPE type, bool downloadble);
    virtual ~IMObject() {};
  public:
    CARD16BIT get_attribid() const
    {
	if (!downloadablep()) return 0;
	return ((id & ((1 << 15) - 1)) | (1 << 15));
    }
    CARD32BIT get_fullid() const
    { return id; }
    bool downloadablep() const
    { return downloadable; }
    enum OBJTYPE get_type() const
    { return type; }
    enum OBJCATEGORY get_category() const;
};

class IMDescriptorMatchPredicate;
class IMDescriptor : public IMObject
{
    u16string imname;
    u16string hrn;
    string domainname;
    IMLangList langs;
    const IMHotkeyProfileStruct *hotkey_profile;

  public:
    const u16string& get_imname() const
    { return imname; }
    const u16string& get_hrn() const
    { return hrn; }
    const IMLangList* get_languages() const
    { return &langs; }
    const IMHotkeyProfileStruct* get_hotkey_profile() const
    { return hotkey_profile; }

    IMDescriptor(
	const u16string& imname,
	const u16string& hrn,
	const string& domainname,
	const IMLangList& langs,
	IMHotkeyProfileStruct *hkps
    );
  friend class IMDescriptorMatchPredicate;
};
typedef list<IMDescriptor> IMDescriptorList;

// IMDescriptor predicate.
class IMDescriptorMatchPredicate : public unary_function<IMDescriptor, bool>
{
    const u16string* ppattern;
  public:
    IMDescriptorMatchPredicate(const u16string* pattern)
    { ppattern = pattern; }
    bool operator()(
	const IMDescriptor &d
    ) const;
};


class IMObjectWithDesc : public IMObject
{
    CARD8BIT *pbinrep;
    string leid;
    int size;
    list<u16string> jarfile_classes;
    u16string hrn;
    u16string domain;
    u16string path;
    u16string scope;
    u16string signature;
    u16string basepath;
    u16string encoding;

    void set_size();

  public:
    int get_object_size() const
    { return size; }
    const u16string& get_domain() const
    { return domain; }
    const u16string& get_hrn() const
    { return hrn; }
    const u16string& get_signature() const
    { return signature; }
    const u16string& get_scope() const
    { return scope; }
    const u16string& get_path() const
    { return path; }
    const list<u16string>& get_classes() const
    { return jarfile_classes; }
    virtual const CARD8BIT* get_binary_representation();

  public:
    void log_obj();
    IMObjectWithDesc(const IMObjectDescriptorStruct &desc);
    virtual ~IMObjectWithDesc();
};
typedef list<IMObjectWithDesc*> IMObjectWithDescList;

// singleton class
class IMObjectMgr
{
    int attribid_counter;
    static IMObjectMgr *pimobjmgr;
    IMSyncObject sync_object;
    typedef map<CARD16BIT, IMObject*> IMObjectMap;
    IMObjectMap objmap;

    CARD16BIT get_attribid(CARD32BIT fullid);

    IMObjectMgr();
  public:
    static IMObjectMgr* get_instance()
    { return pimobjmgr; }
    bool add(
	IMObject *pobj,
	CARD32BIT &id
    );
    IMObject* get_object_from_fullid(
	CARD32BIT id
    );
    IMObject* get_object_from_attribid(
	CARD16BIT id
    );
    static IMObjectMgr* construct();

  friend class IMObject;
};

#endif /* not IMHANDLER_HH_ */

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