/*
 * XDND handler code
 *
 * Copyright 2003 Ulrich Czekalla
 *
 * 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
 */

#include "config.h"
#include "wine/port.h"

#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wownt32.h"

#include "x11drv.h"
#include "shlobj.h"  /* DROPFILES */

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(xdnd);

/* Maximum wait time for selection notify */
#define SELECTION_RETRIES 500  /* wait for .1 seconds */
#define SELECTION_WAIT    1000 /* us */

typedef struct tagXDNDDATA
{
    int cf_win;
    Atom cf_xdnd;
    void *data;
    unsigned int size;
    struct tagXDNDDATA *next;
} XDNDDATA, *LPXDNDDATA;

static LPXDNDDATA XDNDData = NULL;
static POINT XDNDxy = { 0, 0 };

static void X11DRV_XDND_InsertXDNDData(int property, int format, void* data, unsigned int len);
static int X11DRV_XDND_DeconstructTextPlain(int property, void* data, int len);
static int X11DRV_XDND_DeconstructTextHTML(int property, void* data, int len);
static int X11DRV_XDND_MapFormat(unsigned int property, unsigned char *data, int len);
static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm,
    Atom *types, unsigned long *count);
static void X11DRV_XDND_SendDropFiles(HWND hwnd);
static void X11DRV_XDND_FreeDragDropOp(void);
static unsigned int X11DRV_XDND_UnixToDos(char** lpdest, char* lpsrc, int len);
static DROPFILES* X11DRV_XDND_BuildDropFiles(char* filename, unsigned int len, POINT pt);

static CRITICAL_SECTION xdnd_cs;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &xdnd_cs,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { 0, (DWORD)(__FILE__ ": xdnd_cs") }
};
static CRITICAL_SECTION xdnd_cs = { &critsect_debug, -1, 0, 0, 0, 0 };


/**************************************************************************
 * X11DRV_XDND_EnterEvent
 *
 * Handle an XdndEnter event.
 */
void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event )
{
    Atom *xdndtypes;
    unsigned long count = 0;

    TRACE("ver(%ld) check-XdndTypeList(%ld) data=%ld,%ld,%ld,%ld,%ld\n",
          (event->data.l[1] & 0xFF000000) >> 24, (event->data.l[1] & 1),
          event->data.l[0], event->data.l[1], event->data.l[2],
          event->data.l[3], event->data.l[4]);

    /* If the source supports more than 3 data types we retrieve
     * the entire list. */
    if (event->data.l[1] & 1)
    {
        Atom acttype;
        int actfmt;
        unsigned long bytesret;

        /* Request supported formats from source window */
        wine_tsx11_lock();
        XGetWindowProperty(event->display, event->data.l[0], x11drv_atom(XdndTypeList),
                           0, 65535, FALSE, AnyPropertyType, &acttype, &actfmt, &count,
                           &bytesret, (unsigned char**)&xdndtypes);
        wine_tsx11_unlock();
    }
    else
    {
        count = 3;
        xdndtypes = &event->data.l[2];
    }

    if (TRACE_ON(xdnd))
    {
        unsigned int i = 0;

        wine_tsx11_lock();
        for (; i < count; i++)
        {
            if (xdndtypes[i] != 0)
            {
                char * pn = XGetAtomName(event->display, xdndtypes[i]);
                TRACE("XDNDEnterAtom %ld: %s\n", xdndtypes[i], pn);
                XFree(pn);
            }
        }
        wine_tsx11_unlock();
    }

    /* Do a one-time data read and cache results */
    X11DRV_XDND_ResolveProperty(event->display, event->window,
                                event->data.l[1], xdndtypes, &count);

    if (event->data.l[1] & 1)
        XFree(xdndtypes);
}

/**************************************************************************
 * X11DRV_XDND_PositionEvent
 *
 * Handle an XdndPosition event.
 */
void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event )
{
    XClientMessageEvent e;
    int accept = 0; /* Assume we're not accepting */

    XDNDxy.x = event->data.l[2] >> 16;
    XDNDxy.y = event->data.l[2] & 0xFFFF;

    /* FIXME: Notify OLE of DragEnter. Result determines if we accept */

    if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)
        accept = 1;

    TRACE("action req: %ld accept(%d) at x(%ld),y(%ld)\n",
          event->data.l[4], accept, XDNDxy.x, XDNDxy.y);

    /*
     * Let source know if we're accepting the drop by
     * sending a status message.
     */
    e.type = ClientMessage;
    e.display = event->display;
    e.window = event->data.l[0];
    e.message_type = x11drv_atom(XdndStatus);
    e.format = 32;
    e.data.l[0] = event->window;
    e.data.l[1] = accept;
    e.data.l[2] = 0; /* Empty Rect */
    e.data.l[3] = 0; /* Empty Rect */
    if (accept)
        e.data.l[4] = event->data.l[4];
    else
        e.data.l[4] = None;
    wine_tsx11_lock();
    XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e);
    wine_tsx11_unlock();

    /* FIXME: if drag accepted notify OLE of DragOver */
}

/**************************************************************************
 * X11DRV_XDND_DropEvent
 *
 * Handle an XdndDrop event.
 */
void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event )
{
    XClientMessageEvent e;

    TRACE("\n");

    /* If we have a HDROP type we send a WM_ACCEPTFILES.*/
    if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)
        X11DRV_XDND_SendDropFiles( hWnd );

    /* FIXME: Notify OLE of Drop */
    X11DRV_XDND_FreeDragDropOp();

    /* Tell the target we are finished. */
    memset(&e, 0, sizeof(e));
    e.type = ClientMessage;
    e.display = event->display;
    e.window = event->data.l[0];
    e.message_type = x11drv_atom(XdndFinished);
    e.format = 32;
    e.data.l[0] = event->window;
    wine_tsx11_lock();
    XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e);
    wine_tsx11_unlock();
}

/**************************************************************************
 * X11DRV_XDND_LeaveEvent
 *
 * Handle an XdndLeave event.
 */
void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event )
{
    TRACE("DND Operation canceled\n");

    X11DRV_XDND_FreeDragDropOp();

    /* FIXME: Notify OLE of DragLeave */
}


/**************************************************************************
 * X11DRV_XDND_ResolveProperty
 *
 * Resolve all MIME types to windows clipboard formats. All data is cached.
 */
static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm,
                                        Atom *types, unsigned long *count)
{
    unsigned int i, j;
    BOOL res;
    XEvent xe;
    Atom acttype;
    int actfmt;
    unsigned long bytesret, icount;
    int entries = 0;
    unsigned char* data = NULL;

    TRACE("count(%ld)\n", *count);

    X11DRV_XDND_FreeDragDropOp(); /* Clear previously cached data */

    for (i = 0; i < *count; i++)
    {
        TRACE("requesting atom %ld from xwin %ld\n", types[i], xwin);

        if (types[i] == 0)
            continue;

        wine_tsx11_lock();
        XConvertSelection(display, x11drv_atom(XdndSelection), types[i],
                          x11drv_atom(XdndTarget), xwin, /*tm*/CurrentTime);
        wine_tsx11_unlock();

        /*
         * Wait for SelectionNotify
         */
        for (j = 0; j < SELECTION_RETRIES; j++)
        {
            wine_tsx11_lock();
            res = XCheckTypedWindowEvent(display, xwin, SelectionNotify, &xe);
            wine_tsx11_unlock();
            if (res && xe.xselection.selection == x11drv_atom(XdndSelection)) break;

            usleep(SELECTION_WAIT);
        }

        if (xe.xselection.property == None)
            continue;

        wine_tsx11_lock();
        XGetWindowProperty(display, xwin, x11drv_atom(XdndTarget), 0, 65535, FALSE,
            AnyPropertyType, &acttype, &actfmt, &icount, &bytesret, &data);
        wine_tsx11_unlock();

        entries += X11DRV_XDND_MapFormat(types[i], data, icount * (actfmt / 8));
        wine_tsx11_lock();
        XFree(data);
        wine_tsx11_unlock();
    }

    *count = entries;
}


/**************************************************************************
 * X11DRV_XDND_InsertXDNDData
 *
 * Cache available XDND property
 */
static void X11DRV_XDND_InsertXDNDData(int property, int format, void* data, unsigned int len)
{
    LPXDNDDATA current = (LPXDNDDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(XDNDDATA));

    if (current)
    {
        EnterCriticalSection(&xdnd_cs);
        current->next = XDNDData;
        current->cf_xdnd = property;
        current->cf_win = format;
        current->data = data;
        current->size = len;
        XDNDData = current;
        LeaveCriticalSection(&xdnd_cs);
    }
}


/**************************************************************************
 * X11DRV_XDND_MapFormat
 *
 * Map XDND MIME format to windows clipboard format.
 */
static int X11DRV_XDND_MapFormat(unsigned int property, unsigned char *data, int len)
{
    void* xdata;
    int count = 0;

    TRACE("%d: %s\n", property, data);

    /* Always include the raw type */
    xdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
    memcpy(xdata, data, len);
    X11DRV_XDND_InsertXDNDData(property, property, xdata, len);
    count++;

    if (property == x11drv_atom(text_plain))
        count += X11DRV_XDND_DeconstructTextPlain(property, data, len);
    else if (property == x11drv_atom(text_html))
        count += X11DRV_XDND_DeconstructTextHTML(property, data, len);

    return count;
}


/**************************************************************************
 * X11DRV_XDND_DeconstructTextPlain
 *
 * Interpret text/plain Data and add records to <dndfmt> linked list
 */
static int X11DRV_XDND_DeconstructTextPlain(int property, void* data, int len)
{
    char *p = (char*) data;
    char* dostext;
    int count = 0;

    /* Always suppply plain text */
    X11DRV_XDND_UnixToDos(&dostext, (char*)data, len);
    X11DRV_XDND_InsertXDNDData(property, CF_TEXT, dostext, strlen(dostext));
    count++;

    TRACE("CF_TEXT (%d): %s\n", CF_TEXT, dostext);

    /* Check for additional mappings */
    while (*p != '\0' && *p != ':') /* Advance to end of protocol */
        p++;

    if (*p == ':')
    {
        if (!strncasecmp(data, "http", 4))
        {
            X11DRV_XDND_InsertXDNDData(property, RegisterClipboardFormatA("UniformResourceLocator"),
                strdup(dostext), strlen(dostext));
                count++;

            TRACE("UniformResourceLocator: %s\n", dostext);
        }
        else if (!strncasecmp(data, "file", 4))
        {
            DROPFILES* pdf;

            pdf = X11DRV_XDND_BuildDropFiles(p+1, len - 5, XDNDxy);
            if (pdf)
            {
                unsigned int size = HeapSize(GetProcessHeap(), 0, pdf);

                X11DRV_XDND_InsertXDNDData(property, CF_HDROP, pdf, size);
                count++;
            }

            TRACE("CF_HDROP: %p\n", pdf);
        }
    }

    return count;
}


/**************************************************************************
 * X11DRV_XDND_DeconstructTextHTML
 *
 * Interpret text/html data and add records to <dndfmt> linked list
 */
static int X11DRV_XDND_DeconstructTextHTML(int property, void* data, int len)
{
    char* dostext;

    X11DRV_XDND_UnixToDos(&dostext, data, len);

    X11DRV_XDND_InsertXDNDData(property,
        RegisterClipboardFormatA("UniformResourceLocator"), dostext, strlen(dostext));

    TRACE("UniformResourceLocator: %s\n", dostext);

    return 1;
}


/**************************************************************************
 * X11DRV_XDND_SendDropFiles
 */
static void X11DRV_XDND_SendDropFiles(HWND hwnd)
{
    LPXDNDDATA current;

    EnterCriticalSection(&xdnd_cs);

    current = XDNDData;

    /* Find CF_HDROP type if any */
    while (current != NULL)
    {
        if (current->cf_win == CF_HDROP)
            break;
        current = current->next;
    }

    if (current != NULL)
    {
        DROPFILES *lpDrop = (DROPFILES*) current->data;

        if (lpDrop)
        {
            lpDrop->pt.x = XDNDxy.x;
            lpDrop->pt.y = XDNDxy.y;

            TRACE("Sending WM_DROPFILES: hWnd(0x%p) %p(%s)\n", hwnd,
                ((char*)lpDrop) + lpDrop->pFiles, ((char*)lpDrop) + lpDrop->pFiles);

            PostMessageA(hwnd, WM_DROPFILES, (WPARAM)lpDrop, 0L);
        }
    }

    LeaveCriticalSection(&xdnd_cs);
}


/**************************************************************************
 * X11DRV_XDND_FreeDragDropOp
 */
static void X11DRV_XDND_FreeDragDropOp(void)
{
    LPXDNDDATA next;
    LPXDNDDATA current;

    TRACE("\n");

    EnterCriticalSection(&xdnd_cs);

    current = XDNDData;

    /** Free data cache */
    while (current != NULL)
    {
        next = current->next;
        HeapFree(GetProcessHeap(), 0, current);
        current = next;
    }

    XDNDData = NULL;
    XDNDxy.x = XDNDxy.y = 0;

    LeaveCriticalSection(&xdnd_cs);
}



/**************************************************************************
 * X11DRV_XDND_BuildDropFiles
 */
static DROPFILES* X11DRV_XDND_BuildDropFiles(char* filename, unsigned int len, POINT pt)
{
    char* pfn;
    int pathlen;
    char path[MAX_PATH];
    DROPFILES *lpDrop = NULL;

    /* Advance to last starting slash */
    pfn = filename + 1;
    while (*pfn && (*pfn == '\\' || *pfn =='/'))
    {
        pfn++;
        filename++;
    }

    /* Remove any trailing \r or \n */
    while (*pfn)
    {
        if (*pfn == '\r' || *pfn == '\n')
        {
            *pfn = 0;
            break;
        }
        pfn++;
    }

    TRACE("%s\n", filename);

    pathlen = GetLongPathNameA(filename, path, MAX_PATH);
    if (pathlen)
    {
        lpDrop = (DROPFILES*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            sizeof(DROPFILES) + pathlen + 1);

        lpDrop->pFiles = sizeof(DROPFILES);
        lpDrop->pt.x = pt.x;
        lpDrop->pt.y = pt.y;
        lpDrop->fNC = 0;
        lpDrop->fWide = FALSE;

        strcpy(((char*)lpDrop)+lpDrop->pFiles, path);
    }

    TRACE("resolved %s\n", lpDrop ? filename : NULL);

    return lpDrop;
}


/**************************************************************************
 * X11DRV_XDND_UnixToDos
 */
static unsigned int X11DRV_XDND_UnixToDos(char** lpdest, char* lpsrc, int len)
{
    int i;
    unsigned int destlen, lines;

    for (i = 0, lines = 0; i <= len; i++)
    {
        if (lpsrc[i] == '\n')
            lines++;
    }

    destlen = len + lines + 1;

    if (lpdest)
    {
        char* lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, destlen);
        for (i = 0, lines = 0; i <= len; i++)
        {
            if (lpsrc[i] == '\n')
                lpstr[++lines + i] = '\r';
            lpstr[lines + i] = lpsrc[i];
        }

        *lpdest = lpstr;
    }

    return lines;
}
