/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#ifndef _ANDROID_GRAPHICS_REFLIST_H
#define _ANDROID_GRAPHICS_REFLIST_H

#include <inttypes.h>

#include "android/utils/compiler.h"
#include <android/utils/system.h>

ANDROID_BEGIN_HEADER

/* Definitions for a smart list of references to generic objects.
 * supports safe deletion and addition while they are being iterated
 * with AREFLIST_FOREACH() macro.
 *
 * note that you cannot add NULL to an ARefList.
 */

/* Clients should ignore these implementation details, which
 * we're going to explain there:
 *   - 'count' is the number of items in the list
 *   - 'size' is the number of slots in the list's array. It is
 *     always >= 'count'. Some slots correspond to deleted items
 *     and will hold a NULL value.
 *   - 'max' is the size of the slots array
 *   - 'u.item0' is used when 'max' is 1
 *   - 'u.items' is the slot array if 'max > 1'
 *   - 'u.next' is only used for free-list storage.
 */
typedef struct ARefList {
    /* XXX: should we use uint32_t instead ? */
    uint16_t   count, size, max;
    uint16_t   iteration;
    union {
        void*   item0;
        void**  items;
    } u;
} ARefList;

/* Initialize an empty ARefList */
AINLINED void
areflist_init(ARefList*  l)
{
    l->count     = 0;
    l->size      = 0;
    l->max       = 1;
    l->iteration = 0;
}

/* Return the number of items in a list */
AINLINED int
areflist_getCount(const ARefList*  l)
{
    return l->count;
}

/* Clear an ARefList */
void  areflist_setEmpty(ARefList*  l);

/* Finalize, i.e. clear, an ARefList */
AINLINED void
areflist_done(ARefList*  l)
{
    areflist_setEmpty(l);
}

/* Return TRUE iff an ARefList has no item */
AINLINED ABool
areflist_isEmpty(const ARefList*  l)
{
    return (areflist_getCount(l) == 0);
}

/* Return the index of 'item' in the ARefList, or -1.
 * This returns -1 if 'item' is NULL.
 */
int    areflist_indexOf(const ARefList*  l, void*  item);

/* Return TRUE iff an ARefList contains 'item' */
AINLINED ABool
areflist_has(const ARefList*  l, void*  item)
{
    return areflist_indexOf(l, item) >= 0;
}

/* Append 'item' to a list. An item can be added several
 * times to the same list. Do nothing if 'item' is NULL. */
void    areflist_add(ARefList*  l, void*  item);

/* Remove first instance of 'item' from an ARefList.
 * Returns TRUE iff the item was found in the list. */
ABool   areflist_delFirst(ARefList*  l, void*  item);

/* Remove all instances of 'item' from an ARefList.
 * returns TRUE iff the item was found in the list */
ABool   areflist_delAll(ARefList*  l, void*  item);

/* Same as areflist_add() */
AINLINED void
areflist_push(ARefList*  l, void*  item)
{
    areflist_add(l, item);
}

/* Remove last item from an ARefList and return it.
 * NULL is returned if the list is empty */
void*  areflist_popLast(ARefList*  l);

/* Return the n-th array entry, or NULL in case of invalid index */
void*   areflist_get(const ARefList*  l, int  n);

AINLINED int
areflist_count(ARefList*  l)
{
    return l->count;
}

void  areflist_append(ARefList*  l, const ARefList*  src);

/* used internally */
void    _areflist_remove_deferred(ARefList*  l);

void**  _areflist_at(const ARefList*  l, int  n);

#define  AREFLIST_LOOP(list_,itemvar_) \
    do { \
        ARefList*  _reflist_loop   = (list_); \
        int        _reflist_loop_i = 0; \
        int        _reflist_loop_n = _reflist_loop->size; \
        _reflist_loop->iteration += 2; \
        for ( ; _reflist_loop_i < _reflist_loop_n; _reflist_loop_i++ ) { \
            void** _reflist_loop_at = _areflist_at(_reflist_loop, _reflist_loop_i); \
            (itemvar_) = *(_reflist_loop_at); \
            if ((itemvar_) != NULL) {

#define  AREFLIST_LOOP_END \
            } \
        } \
        if (_reflist_loop->iteration & 1) \
            _areflist_remove_deferred(_reflist_loop); \
    } while (0);

#define  AREFLIST_LOOP_CONST(list_,itemvar_) \
    do { \
        const ARefList*  _reflist_loop   = (list_); \
        int              _reflist_loop_i = 0; \
        int              _reflist_loop_n = _reflist_loop->size; \
        for ( ; _reflist_loop_i < _reflist_loop_n; _reflist_loop_i++ ) { \
            void** _reflist_loop_at = _areflist_at(_reflist_loop, _reflist_loop_i); \
            (itemvar_) = *(_reflist_loop_at); \
            if ((itemvar_) != NULL) {

#define  AREFLIST_LOOP_DEL() \
    (_reflist_loop->iteration |= 1, *_reflist_loop_at = NULL)

#define  AREFLIST_LOOP_SET(val) \
    (_reflist_loop->iteration |= 1, *_reflist_loop_at = (val))


#define  AREFLIST_FOREACH(list_,item_,statement_) \
    ({ ARefList*  _reflist   = (list_); \
       int        _reflist_i = 0; \
       int        _reflist_n = _reflist->size; \
       _reflist->iteration += 2; \
       for ( ; _reflist_i < _reflist_n; _reflist_i++ ) { \
           void**  __reflist_at   = _areflist_at(_reflist, _reflist_i); \
           void*  item_ = *__reflist_at; \
           if (item_ != NULL) { \
               statement_; \
           } \
       } \
       _reflist->iteration -= 2; \
       if (_reflist->iteration == 1) \
           _areflist_remove_deferred(_reflist); \
    })

#define  AREFLIST_FOREACH_CONST(list_,item_,statement_) \
    ({ const ARefList*  _reflist = (list_); \
       int        _reflist_i = 0; \
       int        _reflist_n = _reflist->size; \
       for ( ; _reflist_i < _reflist_n; _reflist_i++ ) { \
           void**  __reflist_at = _areflist_at(_reflist, _reflist_i); \
           void*  item_ = *__reflist_at; \
           if (item_ != NULL) { \
               statement_; \
           } \
       } \
    })

/* use this to delete the currently iterated element */
#define  AREFLIST_DEL_ITERATED()  \
    ({ *__reflist_at = NULL; \
       _reflist->iteration |= 1; })

/* use this to replace the currently iterated element */
#define  AREFLIST_SET_ITERATED(item) \
    ({ *__reflist_at = (item); \
       if (item == NULL) _reflist->iteration |= 1; })

void  areflist_copy(ARefList*  dst, const ARefList*  src);

ANDROID_END_HEADER

#endif /* _ANDROID_GRAPHICS_REFLIST_H */
