/*
 * Copyright (C) 1992 by Software Research Associates, Inc.
 *      Author: Y. Kawabe <kawabe@sra.co.jp>
 *
 * Permission to use, copy, modify, and distribute, and sell this software
 * and its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Software Research Associates not be
 * used in advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  Software Research Associates
 * makes no representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 */

#include <IV-X11/Xlib.h>
#include <IV-X11/xatom.h>
#include <hyperg/OS/string.h>
#include <hyperg/OS/table2.h>

inline unsigned long key_to_hash(String &s) {
    return (unsigned long) s.hash();
}

inline unsigned long key_to_hash(Atom a) {
    return (unsigned long) a;
}

inline unsigned long key_to_hash(XDisplay* d) {
    return (unsigned long) ConnectionNumber(d);
}

declareTable2(XString2AtomTable, XDisplay*, String, Atom);
implementTable2(XString2AtomTable, XDisplay*, String, Atom);


declareTable2(XAtom2StringTable, XDisplay*, Atom, String*);
implementTable2(XAtom2StringTable, XDisplay*, Atom, String*);

/*
 * class XAtomRep
 */

class XAtomRep {
  public:
    XAtomRep();
  public:
    XString2AtomTable	*atable_;
    XAtom2StringTable	*stable_;
};

XAtomRep::XAtomRep () {
    atable_ = new XString2AtomTable(8);
    stable_ = new XAtom2StringTable(8);
}

/*
 * class XAtom
 */

XAtomRep *XAtom::rep_;

Atom XAtom::intern (XDisplay *display, const String& name) {
    Atom atom;
    if (rep_ == nil) {
	rep_ = new XAtomRep;
    }
    if (rep_->atable_->find(atom, display, name)) {
	return atom;
    }
    String* p = new CopyString(name);
    atom = XInternAtom(display, p->string(), false);
    rep_->atable_->insert(display, *p, atom);
    rep_->stable_->insert(display, atom, p);
    return atom;
}

const String& XAtom::name (XDisplay *display, Atom atom) {
    String *name;
    if (rep_ == nil) {
	rep_ = new XAtomRep;
    }
    if (rep_->stable_->find(name, display, atom)) {
	return *name;
    }
    char* xname = XGetAtomName(display, atom);
    String* p = xname ? new CopyString(xname) : new CopyString();
    rep_->atable_->insert(display, *p, atom);
    rep_->stable_->insert(display, atom, p);
    if (xname) XFree(xname);
    return *p;
}

