/*
 * Drag List control
 *
 * Copyright 1999 Eric Kohl
 * Copyright 2004 Robert Shearman
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES
 *
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Mar. 10, 2004, by Robert Shearman.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features or bugs please note them below.
 * 
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(commctrl);

/* for compiler compatibility we only accept literal ASCII strings */
#undef TEXT
#define TEXT(string) string

#define DRAGLIST_SUBCLASSID     0
#define DRAGLIST_SCROLLPERIOD 200
#define DRAGLIST_TIMERID      666

/* properties relating to IDI_DRAGICON */
#define DRAGICON_HOTSPOT_X 17
#define DRAGICON_HOTSPOT_Y  7
#define DRAGICON_HEIGHT    32

/* internal Wine specific data for the drag list control */
typedef struct _DRAGLISTDATA
{
    /* are we currently in dragging mode? */
    BOOL dragging;

    /* cursor to use as determined by DL_DRAGGING notification.
     * NOTE: as we use LoadCursor we don't have to use DeleteCursor
     * when we are finished with it */
    HCURSOR cursor;

    /* optimisation so that we don't have to load the cursor
     * all of the time whilst dragging */
    LRESULT last_dragging_response;

    /* prevents flicker with drawing drag arrow */
    RECT last_drag_icon_rect;
} DRAGLISTDATA;

static UINT uDragListMessage = 0; /* registered window message code */
static DWORD dwLastScrollTime = 0;
static HICON hDragArrow = NULL;

/***********************************************************************
 *		DragList_Notify (internal)
 *
 * Sends notification messages to the parent control. Note that it
 * does not use WM_NOTIFY like the rest of the controls, but a registered
 * window message.
 */
static LRESULT DragList_Notify(HWND hwndLB, UINT uNotification)
{
    DRAGLISTINFO dli;
    dli.hWnd = hwndLB;
    dli.uNotification = uNotification;
    GetCursorPos(&dli.ptCursor);
    return SendMessageW(GetParent(hwndLB), uDragListMessage, GetDlgCtrlID(hwndLB), (LPARAM)&dli);
}

/* cleans up after dragging */
static inline void DragList_EndDrag(HWND hwnd, DRAGLISTDATA * data)
{
    KillTimer(hwnd, DRAGLIST_TIMERID);
    ReleaseCapture();
    data->dragging = FALSE;
    /* clear any drag insert icon present */
    InvalidateRect(GetParent(hwnd), &data->last_drag_icon_rect, TRUE);
}

/***********************************************************************
 *		DragList_SubclassWindowProc (internal)
 *
 * Handles certain messages to enable dragging for the ListBox and forwards
 * the rest to the ListBox.
 */
static LRESULT CALLBACK
DragList_SubclassWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    DRAGLISTDATA * data = (DRAGLISTDATA*)dwRefData;
    switch (uMsg)
    {
    case WM_LBUTTONDOWN:
        SetFocus(hwnd);
        data->cursor = NULL;
        SetRectEmpty(&data->last_drag_icon_rect);
        data->dragging = DragList_Notify(hwnd, DL_BEGINDRAG);
        if (data->dragging)
        {
            SetCapture(hwnd);
            SetTimer(hwnd, DRAGLIST_TIMERID, DRAGLIST_SCROLLPERIOD, NULL);
        }
        /* note that we don't absorb this message to let the list box
         * do its thing (normally selecting an item) */
        break;

    case WM_KEYDOWN:
    case WM_RBUTTONDOWN:
        /* user cancelled drag by either right clicking or
         * by pressing the escape key */
        if ((data->dragging) &&
            ((uMsg == WM_RBUTTONDOWN) || (wParam == VK_ESCAPE)))
        {
            /* clean up and absorb message */
            DragList_EndDrag(hwnd, data);
            DragList_Notify(hwnd, DL_CANCELDRAG);
            return 0;
        }
        break;

    case WM_MOUSEMOVE:
    case WM_TIMER:
        if (data->dragging)
        {
            LRESULT cursor = DragList_Notify(hwnd, DL_DRAGGING);
            /* optimisation so that we don't have to load the cursor
             * all of the time whilst dragging */
            if (data->last_dragging_response != cursor)
            {
                switch (cursor)
                {
                case DL_STOPCURSOR:
                    data->cursor = LoadCursorW(NULL, (LPCWSTR)IDC_NO);
                    SetCursor(data->cursor);
                    break;
                case DL_COPYCURSOR:
                    data->cursor = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_COPY);
                    SetCursor(data->cursor);
                    break;
                case DL_MOVECURSOR:
                    data->cursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
                    SetCursor(data->cursor);
                    break;
                }
                data->last_dragging_response = cursor;
            }
            /* don't pass this message on to List Box */
            return 0;
        }
        break;

    case WM_LBUTTONUP:
        if (data->dragging)
        {
            DragList_EndDrag(hwnd, data);
            DragList_Notify(hwnd, DL_DROPPED);
        }
        break;

	case WM_SETCURSOR:
	    /* if app has told us to set a cursor then do so */
        if (data->dragging && data->cursor)
        {
            SetCursor(data->cursor);
            return TRUE;
        }
        break;

    case WM_GETDLGCODE:
        /* tell dialog boxes that we want to receive WM_KEYDOWN events
         * for keys like VK_ESCAPE */
        if (data->dragging)
            return DLGC_WANTALLKEYS;
        break;
    case WM_NCDESTROY:
        RemoveWindowSubclass(hwnd, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID);
        Free(data);
        break;
    }
    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}

/***********************************************************************
 *		MakeDragList (COMCTL32.13)
 *
 * Makes a normal ListBox into a DragList by subclassing it.
 *
 * RETURNS
 *      Success: Non-zero
 *      Failure: Zero
 */
BOOL WINAPI MakeDragList (HWND hwndLB)
{
    DRAGLISTDATA * data = Alloc(sizeof(DRAGLISTDATA));

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

    if (!uDragListMessage)
        uDragListMessage = RegisterWindowMessageA(DRAGLISTMSGSTRING);

    return SetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR)data);
}

/***********************************************************************
 *		DrawInsert (COMCTL32.15)
 *
 * Draws insert arrow by the side of the ListBox item in the parent window.
 *
 * RETURNS
 *      Nothing.
 */
VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem)
{
    RECT rcItem, rcListBox, rcDragIcon;
    HDC hdc;
    DRAGLISTDATA * data;

    TRACE("(%p %p %d)\n", hwndParent, hwndLB, nItem);

    if (!hDragArrow)
        hDragArrow = LoadIconW(COMCTL32_hModule, (LPCWSTR)IDI_DRAGARROW);

    if (LB_ERR == SendMessageW(hwndLB, LB_GETITEMRECT, nItem, (LPARAM)&rcItem))
        return;

    if (!GetWindowRect(hwndLB, &rcListBox))
        return;

    /* convert item rect to parent co-ordinates */
    if (!MapWindowPoints(hwndLB, hwndParent, (LPPOINT)&rcItem, 2))
        return;

    /* convert list box rect to parent co-ordinates */
    if (!MapWindowPoints(HWND_DESKTOP, hwndParent, (LPPOINT)&rcListBox, 2))
        return;

    rcDragIcon.left = rcListBox.left - DRAGICON_HOTSPOT_X;
    rcDragIcon.top = rcItem.top - DRAGICON_HOTSPOT_Y;
    rcDragIcon.right = rcListBox.left;
    rcDragIcon.bottom = rcDragIcon.top + DRAGICON_HEIGHT;

    if (!GetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR*)&data))
        return;

    if (nItem < 0)
        SetRectEmpty(&rcDragIcon);

    /* prevent flicker by only redrawing when necessary */
    if (!EqualRect(&rcDragIcon, &data->last_drag_icon_rect))
    {
        /* get rid of any previous inserts drawn */
        RedrawWindow(hwndParent, &data->last_drag_icon_rect, NULL,
            RDW_INTERNALPAINT | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);

        CopyRect(&data->last_drag_icon_rect, &rcDragIcon);

        if (nItem >= 0)
        {
            hdc = GetDC(hwndParent);

            DrawIcon(hdc, rcDragIcon.left, rcDragIcon.top, hDragArrow);

            ReleaseDC(hwndParent, hdc);
        }
    }
}

/***********************************************************************
 *		LBItemFromPt (COMCTL32.14)
 *
 * Gets the index of the ListBox item under the specified point,
 * scrolling if bAutoScroll is TRUE and pt is outside of the ListBox.
 *
 * RETURNS
 *      The ListBox item ID if pt is over a list item or -1 otherwise.
 */
INT WINAPI LBItemFromPt (HWND hwndLB, POINT pt, BOOL bAutoScroll)
{
    RECT rcClient;
    INT nIndex;
    DWORD dwScrollTime;

    TRACE("(%p %ld x %ld %s)\n",
           hwndLB, pt.x, pt.y, bAutoScroll ? "TRUE" : "FALSE");

    ScreenToClient (hwndLB, &pt);
    GetClientRect (hwndLB, &rcClient);
    nIndex = (INT)SendMessageA (hwndLB, LB_GETTOPINDEX, 0, 0);

    if (PtInRect (&rcClient, pt))
    {
        /* point is inside -- get the item index */
        while (TRUE)
        {
            if (SendMessageA (hwndLB, LB_GETITEMRECT, nIndex, (LPARAM)&rcClient) == LB_ERR)
                return -1;

            if (PtInRect (&rcClient, pt))
                return nIndex;

            nIndex++;
        }
    }
    else
    {
        /* point is outside */
        if (!bAutoScroll)
            return -1;

        if ((pt.x > rcClient.right) || (pt.x < rcClient.left))
            return -1;

        if (pt.y < 0)
            nIndex--;
        else
            nIndex++;

        dwScrollTime = GetTickCount ();

        if ((dwScrollTime - dwLastScrollTime) < DRAGLIST_SCROLLPERIOD)
            return -1;

        dwLastScrollTime = dwScrollTime;

        SendMessageA (hwndLB, LB_SETTOPINDEX, (WPARAM)nIndex, 0);
    }

    return -1;
}
