#ifndef INCLUDE_PBBTAGLIST_H
#define INCLUDE_PBBTAGLIST_H
/**
 * @brief prototypes and generic definitions for taglists
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation
 * (http://www.gnu.org/licenses/gpl.html)
 *
 * @file    libpbbipc/pbbtaglist.h
 * @author  Matthias Grimm <matthias.grimm@users.sourceforge.net>
 */

#define TAG_END			0
#define TAG_SKIP		1

#define FLG_STRING		0x8000
#define FLG_PRIVATE		0x4000
#define FLG_ERROR		0x2000
#define FLG_NOPEEP		0x1000  /* for pbbuttonsd internal use only */
#define FLG_DEPRECIATED	0x0800  /* for pbbuttonsd internal use only */

/**
 * This mask removes all control bits from a tag identifier so that
 * the pure identifier is the result. It should always be used before
 * comparing any tag identifiers.
 */
#define TAGMASK			~(FLG_ERROR | FLG_NOPEEP | FLG_DEPRECIATED)

/* Flags for TAG_SYSINFO */
#define SYSINFO_CONFIGWRITABLE  (1<<1)
#define SYSINFO_HAVELMU         (1<<2)
#define SYSINFO_SLEEPSUPPORTED  (1<<3)
#define SYSINFO_PMUDSUPPORT     (1<<4)
#define SYSINFO_HAVEOSS         (1<<5)
#define SYSINFO_HAVEALSA        (1<<6)
#define SYSINFO_HAVEIBAM        (1<<7)
#define SYSINFO_PB_USB_TPAD     (1<<8)
#define SYSINFO_PB_USB_KBD      (1<<9)

/* Flags for TAG_CLIENTFLAGS */
#define CLIENT_REGISTER			(1<<0) /* register client at server */
#define CLIENT_EXCLUSIVE		(1<<1) /* only one instance allowed */
#define CLIENT_REPLACEMENT		(1<<2 | CLIENT_EXCLUSIVE) /* new instance replaces old one */

typedef unsigned long tag_t;

/**
 * @brief  tag structure - type independent parameter / value pair
 *
 * This structure is able to hold a parameter and its value.  The tag is
 * the identifier of the following data. So the parameter, its data type
 * and meaning are defined through the tag, which from the other side
 * identifies the parameter.
 *
 * If multiple tag-items were queued in an array, we would get a tag-list.
 * This tag-list could hold any amount of parameters. To mark the end of a
 * tag-list the last tag is a special value TAG_END defined in taglist.h.
 */
struct tagitem {
	/**
	 * @brief parameter name also called tag
	 */
	tag_t tag;
	/**
	 * @brief data value. The data type is defined through tag
	 */
	tag_t data;
};

/* prototypes */
tag_t tagfind (struct tagitem *taglist, tag_t tag, tag_t val);
struct tagitem* find_tagitem (struct tagitem *taglist, tag_t tag);
void tagskip (struct tagitem *taglist, tag_t tag);
int tagerror (struct tagitem *tag, int error);
void taglist_init (struct tagitem *taglist);
void taglist_add (struct tagitem *taglist, tag_t tag, tag_t val);
int taglist_count (struct tagitem *taglist);

#endif    /* INCLUDE_PBBTAGLIST_H */
