/*
 * Dynamic structure array (DSA) implementation
 *
 * Copyright 1998 Eric Kohl
 *           1998 Juergen Schmied <j.schmied@metronet.de>
 *           2000 Eric Kohl for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 *     These functions were involuntarily documented by Microsoft in 2002 as
 *     the outcome of an anti-trust suit brought by various U.S. governments.
 *     As a result the specifications on MSDN are inaccurate, incomplete 
 *     and misleading. A much more complete (unofficial) documentation is
 *     available at:
 *
 *     http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32  
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "commctrl.h"

#include "comctl32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dsa);

struct _DSA
{
    INT  nItemCount;
    LPVOID pData;
    INT  nMaxCount;
    INT  nItemSize;
    INT  nGrow;
};

/**************************************************************************
 * DSA_Create [COMCTL32.320]
 *
 * Creates a dynamic storage array
 *
 * PARAMS
 *     nSize [I] size of the array elements
 *     nGrow [I] number of elements by which the array grows when it is filled
 *
 * RETURNS
 *     Success: pointer to an array control structure. Use this like a handle.
 *     Failure: NULL
 *
 * NOTES
 *     The DSA_ functions can be used to create and manipulate arrays of
 *     fixed-size memory blocks. These arrays can store any kind of data
 *     (e.g. strings and icons).
 */
HDSA WINAPI DSA_Create (INT nSize, INT nGrow)
{
    HDSA hdsa;

    TRACE("(size=%d grow=%d)\n", nSize, nGrow);

    hdsa = Alloc (sizeof(*hdsa));
    if (hdsa)
    {
        hdsa->nItemCount = 0;
        hdsa->pData = NULL;
        hdsa->nMaxCount = 0;
        hdsa->nItemSize = nSize;
        hdsa->nGrow = max(1, nGrow);
    }

    return hdsa;
}


/**************************************************************************
 * DSA_Destroy [COMCTL32.321]
 * 
 * Destroys a dynamic storage array
 *
 * PARAMS
 *     hdsa [I] pointer to the array control structure
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DSA_Destroy (HDSA hdsa)
{
    TRACE("(%p)\n", hdsa);

    if (!hdsa)
        return FALSE;

    if (hdsa->pData && (!Free (hdsa->pData)))
        return FALSE;

    return Free (hdsa);
}


/**************************************************************************
 * DSA_GetItem [COMCTL32.322]
 *
 * Copies the specified item into a caller-supplied buffer.
 *
 * PARAMS
 *     hdsa   [I] pointer to the array control structure
 *     nIndex [I] number of the Item to get
 *     pDest  [O] destination buffer. Has to be >= dwElementSize.
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DSA_GetItem (HDSA hdsa, INT nIndex, LPVOID pDest)
{
    LPVOID pSrc;

    TRACE("(%p %d %p)\n", hdsa, nIndex, pDest);

    if (!hdsa)
        return FALSE;
    if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
        return FALSE;

    pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
    memmove (pDest, pSrc, hdsa->nItemSize);

    return TRUE;
}


/**************************************************************************
 * DSA_GetItemPtr [COMCTL32.323]
 *
 * Retrieves a pointer to the specified item.
 *
 * PARAMS
 *     hdsa   [I] pointer to the array control structure
 *     nIndex [I] index of the desired item
 *
 * RETURNS
 *     Success: pointer to an item
 *     Failure: NULL
 */
LPVOID WINAPI DSA_GetItemPtr (HDSA hdsa, INT nIndex)
{
    LPVOID pSrc;

    TRACE("(%p %d)\n", hdsa, nIndex);

    if (!hdsa)
        return NULL;
    if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
        return NULL;

    pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);

    TRACE("-- ret=%p\n", pSrc);

    return pSrc;
}


/**************************************************************************
 * DSA_SetItem [COMCTL32.325]
 *
 * Sets the contents of an item in the array.
 *
 * PARAMS
 *     hdsa   [I] pointer to the array control structure
 *     nIndex [I] index for the item
 *     pSrc   [I] pointer to the new item data
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DSA_SetItem (HDSA hdsa, INT nIndex, LPVOID pSrc)
{
    INT  nSize, nNewItems;
    LPVOID pDest, lpTemp;

    TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);

    if ((!hdsa) || nIndex < 0)
        return FALSE;

    if (hdsa->nItemCount <= nIndex) {
        /* within the old array */
        if (hdsa->nMaxCount > nIndex) {
            /* within the allocated space, set a new boundary */
            hdsa->nItemCount = nIndex + 1;
        }
        else {
            /* resize the block of memory */
            nNewItems =
                hdsa->nGrow * ((((nIndex + 1) - 1) / hdsa->nGrow) + 1);
            nSize = hdsa->nItemSize * nNewItems;

            lpTemp = ReAlloc (hdsa->pData, nSize);
            if (!lpTemp)
                return FALSE;

            hdsa->nMaxCount = nNewItems;
            hdsa->nItemCount = nIndex + 1;
            hdsa->pData = lpTemp;
        }
    }

    /* put the new entry in */
    pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
    TRACE("-- move dest=%p src=%p size=%d\n",
           pDest, pSrc, hdsa->nItemSize);
    memmove (pDest, pSrc, hdsa->nItemSize);

    return TRUE;
}


/**************************************************************************
 * DSA_InsertItem [COMCTL32.324]
 *
 * Inserts an item into the array at the specified index.
 *
 * PARAMS
 *     hdsa   [I] pointer to the array control structure
 *     nIndex [I] index for the new item
 *     pSrc   [I] pointer to the element
 *
 * RETURNS
 *     Success: position of the new item
 *     Failure: -1
 */
INT WINAPI DSA_InsertItem (HDSA hdsa, INT nIndex, LPVOID pSrc)
{
    INT   nNewItems, nSize;
    LPVOID  lpTemp, lpDest;

    TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);

    if ((!hdsa) || nIndex < 0)
        return -1;

    /* when nIndex >= nItemCount then append */
    if (nIndex >= hdsa->nItemCount)
         nIndex = hdsa->nItemCount;

    /* do we need to resize ? */
    if (hdsa->nItemCount >= hdsa->nMaxCount) {
        nNewItems = hdsa->nMaxCount + hdsa->nGrow;
        nSize = hdsa->nItemSize * nNewItems;

        lpTemp = ReAlloc (hdsa->pData, nSize);
        if (!lpTemp)
            return -1;

        hdsa->nMaxCount = nNewItems;
        hdsa->pData = lpTemp;
    }

    /* do we need to move elements ? */
    if (nIndex < hdsa->nItemCount) {
        lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
        lpDest = (char *) lpTemp + hdsa->nItemSize;
        nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
        TRACE("-- move dest=%p src=%p size=%d\n",
               lpDest, lpTemp, nSize);
        memmove (lpDest, lpTemp, nSize);
    }

    /* ok, we can put the new Item in */
    hdsa->nItemCount++;
    lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
    TRACE("-- move dest=%p src=%p size=%d\n",
           lpDest, pSrc, hdsa->nItemSize);
    memmove (lpDest, pSrc, hdsa->nItemSize);

    return nIndex;
}


/**************************************************************************
 * DSA_DeleteItem [COMCTL32.326]
 *
 * Deletes the specified item from the array.
 *
 * PARAMS
 *     hdsa   [I] pointer to the array control structure
 *     nIndex [I] index for the element to delete
 *
 * RETURNS
 *     Success: number of the deleted element
 *     Failure: -1
 */
INT WINAPI DSA_DeleteItem (HDSA hdsa, INT nIndex)
{
    LPVOID lpDest,lpSrc;
    INT  nSize;

    TRACE("(%p %d)\n", hdsa, nIndex);

    if (!hdsa)
        return -1;
    if (nIndex < 0 || nIndex >= hdsa->nItemCount)
        return -1;

    /* do we need to move ? */
    if (nIndex < hdsa->nItemCount - 1) {
        lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
        lpSrc = (char *) lpDest + hdsa->nItemSize;
        nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
        TRACE("-- move dest=%p src=%p size=%d\n",
               lpDest, lpSrc, nSize);
        memmove (lpDest, lpSrc, nSize);
    }

    hdsa->nItemCount--;

    /* free memory ? */
    if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
        nSize = hdsa->nItemSize * hdsa->nItemCount;

        lpDest = ReAlloc (hdsa->pData, nSize);
        if (!lpDest)
            return -1;

        hdsa->nMaxCount = hdsa->nItemCount;
        hdsa->pData = lpDest;
    }

    return nIndex;
}


/**************************************************************************
 * DSA_DeleteAllItems [COMCTL32.327]
 *
 * Removes all items and reinitializes the array.
 *
 * PARAMS
 *     hdsa [I] pointer to the array control structure
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DSA_DeleteAllItems (HDSA hdsa)
{
    TRACE("(%p)\n", hdsa);

    if (!hdsa)
        return FALSE;
    if (hdsa->pData && (!Free (hdsa->pData)))
        return FALSE;

    hdsa->nItemCount = 0;
    hdsa->pData = NULL;
    hdsa->nMaxCount = 0;

    return TRUE;
}


/**************************************************************************
 * DSA_EnumCallback [COMCTL32.387]
 *
 * Enumerates all items in a dynamic storage array.
 *
 * PARAMS
 *     hdsa     [I] handle to the dynamic storage array
 *     enumProc [I]
 *     lParam   [I]
 *
 * RETURNS
 *     none
 */
VOID WINAPI DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
                              LPVOID lParam)
{
    INT i;

    TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);

    if (!hdsa)
        return;
    if (hdsa->nItemCount <= 0)
        return;

    for (i = 0; i < hdsa->nItemCount; i++) {
        LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
        if ((enumProc)(lpItem, lParam) == 0)
            return;
    }

    return;
}


/**************************************************************************
 * DSA_DestroyCallback [COMCTL32.388]
 *
 * Enumerates all items in a dynamic storage array and destroys it.
 *
 * PARAMS
 *     hdsa     [I] handle to the dynamic storage array
 *     enumProc [I]
 *     lParam   [I]
 *
 * RETURNS
 *     none
 */
void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
                                 LPVOID lParam)
{
    TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);

    DSA_EnumCallback (hdsa, enumProc, lParam);
    DSA_Destroy (hdsa);
}

/**************************************************************************
 * DSA_Clone [COMCTL32.@]
 *
 * Creates a copy of a dsa
 *
 * PARAMS
 *     hdsa [I] handle to the dynamic storage array
 *
 * RETURNS
 *     Cloned dsa
 */
HDSA WINAPI DSA_Clone(HDSA hdsa)
{
    HDSA dest;
    INT i;

    TRACE("(%p)\n", hdsa);

    if (!hdsa)
        return NULL;

    dest = DSA_Create (hdsa->nItemSize, hdsa->nGrow);
    if (!dest)
        return NULL;

    for (i = 0; i < hdsa->nItemCount; i++) {
        void *ptr = DSA_GetItemPtr (hdsa, i);
        if (DSA_InsertItem (dest, DA_LAST, ptr) == -1) {
            DSA_Destroy (dest);
            return NULL;
        }
    }

    return dest;
}

/**************************************************************************
 * DSA_GetSize [COMCTL32.@]
 *
 * Returns allocated memory size for this array
 *
 * PARAMS
 *     hdsa [I] handle to the dynamic storage array
 *
 * RETURNS
 *     Size
 */
ULONGLONG WINAPI DSA_GetSize(HDSA hdsa)
{
    TRACE("(%p)\n", hdsa);

    if (!hdsa) return 0;

    return sizeof(*hdsa) + (ULONGLONG)hdsa->nMaxCount*hdsa->nItemSize;
}
