/* strophepp.h
** strophe XMPP client library C++ API
**
** Copyright (C) 2005-2009 Collecta, Inc.
**
**  This software is provided AS-IS with no warranty, either express or
**  implied.
**
**  This program is dual licensed under the MIT and GPLv3 licenses.
*/

/** @file
 *  Strophe public C++ API definitions.
 */

#ifndef __LIBSTROPHE_STROPHEPP_H__
#define __LIBSTROPHE_STROPHEPP_H__

#include "strophe.h"

namespace XMPP {
    class Context {
    private:
        xmpp_mem_t m_mem;
        xmpp_log_t m_log;
        xmpp_ctx_t *m_ctx;

    public:
        Context();
        virtual ~Context();

        virtual void *alloc(const size_t size);
        virtual void *realloc(void *p, const size_t size);
        virtual void free(void *p);
        virtual void log(const xmpp_log_level_t level,
                         const char * const area,
                         const char * const msg);

        xmpp_ctx_t *getContext();

    private:
        static void *callAlloc(const size_t size, void * const userdata);
        static void *callRealloc(void *p, const size_t size,
                                 void * const userdata);
        static void callFree(void *p, void * const userdata);
        static void callLog(void * const userdata,
                            const xmpp_log_level_t level,
                            const char * const area,
                            const char * const msg);
    };

    class Stanza {
    private:
        Context *m_ctx;
        xmpp_stanza_t *m_stanza;

        void *operator new(size_t size, Context *ctx);
        void operator delete(void *p);
        Stanza(Context *ctx);
        virtual ~Stanza();

    public:
        static Stanza *create(Context *ctx);
        void release();
        Stanza *clone();
        Stanza *copy();

        int toText(const char ** const buf, size_t * const buflen);
        Stanza *getChildren();
        Stanza *getChildByName(const char * const name);
        Stanza *getNext();
        char *getAttribute(const char * const name);
        char *getNamespace();
        char *getText();
        char *getName();
        void addChild(Stanza *child);
        void setNamespace(const char * const ns);
        void setAttribute(const char * const key, const char * const value);
        void setName(const char * const name);
        void setText(const char * const text);
        void setText(const char * const text, const size_t size);
        char *getType();
        char *getId();
        char *getTo();
        char *getFrom();
        void setType(const char * const type);
        void setId(const char * const id);
        void setTo(const char * const to);
        void setFrom(const char * const from);
    };

    class Connection {
    private:
        Context *m_ctx;
        xmpp_conn_t *conn;

        void *operator new(size_t size, Context *ctx);
        Connection(Context *ctx);

    public:
        static Connection *create(Context *ctx);
        virtual ~Connection();
        Connection *clone();
        void operator delete(void *p);

        const char *getJID();
        void setJID(const char * const jid);
        const char *getPass();
        void setPass(const char * const pass);
        bool connectClient(const char * const domain,
                           xmpp_conn_handler callback,
                           void * const userdata);
        void disconnect();
        void send(Stanza *stanza);

        void addTimedHandler(xmpp_timed_handler handler,
                             const unsigned long perdio,
                             void * const userdata);
        void deleteTimedHandler(xmpp_timed_handler handler);
        void addHandler(xmpp_handler handler,
                        const char * const ns,
                        const char * const name,
                        const char * const type,
                        void * const userdata);
        void deleteHandler(xmpp_handler handler);
        void addIdHandler(xmpp_handler handler,
                          const char * const id,
                          void * const userdata);
        void deleteIdHandler(xmpp_handler handler);
    };
}

#endif /* __LIBSTROPHE_STROPHEPP_H__ */
