/*
 * Richedit clipboard handling
 *
 * Copyright (C) 2006 Kevin Koltzau
 *
 * 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
 */

#define NONAMELESSUNION

#include "editor.h"

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

static UINT cfRTF = 0;

typedef struct DataObjectImpl {
    IDataObject IDataObject_iface;
    LONG ref;

    FORMATETC *fmtetc;
    UINT fmtetc_cnt;

    HANDLE unicode;
    HANDLE rtf;
} DataObjectImpl;

typedef struct EnumFormatImpl {
    IEnumFORMATETC IEnumFORMATETC_iface;
    LONG ref;

    FORMATETC *fmtetc;
    UINT fmtetc_cnt;

    UINT cur;
} EnumFormatImpl;

static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc);

static inline DataObjectImpl *impl_from_IDataObject(IDataObject *iface)
{
    return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface);
}

static inline EnumFormatImpl *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
{
    return CONTAINING_RECORD(iface, EnumFormatImpl, IEnumFORMATETC_iface);
}

static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    TRACE("%p %s\n", This, debugstr_guid(riid));

    if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumFORMATETC)) {
        IEnumFORMATETC_AddRef(iface);
        *ppvObj = This;
        return S_OK;
    }
    *ppvObj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    LONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        GlobalFree(This->fmtetc);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt,
                                          FORMATETC *rgelt, ULONG *pceltFetched)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    ULONG count = 0;
    TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched);

    if(!rgelt)
        return E_INVALIDARG;

    count = min(celt, This->fmtetc_cnt-This->cur);
    if(count > 0) {
        memcpy(rgelt, This->fmtetc+This->cur, count*sizeof(FORMATETC));
        This->cur += count;
    }
    if(pceltFetched)
        *pceltFetched = count;
    return count == celt ? S_OK : S_FALSE;
}

static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    ULONG count = 0;
    TRACE("(%p)->(%d)\n", This, celt);

    count = min(celt, This->fmtetc_cnt-This->cur);
    This->cur += count;
    return count == celt ? S_OK : S_FALSE;
}

static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    TRACE("(%p)\n", This);

    This->cur = 0;
    return S_OK;
}

static HRESULT WINAPI EnumFormatImpl_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **ppenum)
{
    EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface);
    HRESULT hr;
    TRACE("(%p)->(%p)\n", This, ppenum);

    if(!ppenum)
        return E_INVALIDARG;
    hr = EnumFormatImpl_Create(This->fmtetc, This->fmtetc_cnt, ppenum);
    if(SUCCEEDED(hr))
        hr = IEnumFORMATETC_Skip(*ppenum, This->cur);
    return hr;
}

static const IEnumFORMATETCVtbl VT_EnumFormatImpl = {
    EnumFormatImpl_QueryInterface,
    EnumFormatImpl_AddRef,
    EnumFormatImpl_Release,
    EnumFormatImpl_Next,
    EnumFormatImpl_Skip,
    EnumFormatImpl_Reset,
    EnumFormatImpl_Clone
};

static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFORMATETC **lplpformatetc)
{
    EnumFormatImpl *ret;
    TRACE("\n");

    ret = heap_alloc(sizeof(EnumFormatImpl));
    ret->IEnumFORMATETC_iface.lpVtbl = &VT_EnumFormatImpl;
    ret->ref = 1;
    ret->cur = 0;
    ret->fmtetc_cnt = fmtetc_cnt;
    ret->fmtetc = GlobalAlloc(GMEM_ZEROINIT, fmtetc_cnt*sizeof(FORMATETC));
    memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
    *lplpformatetc = (LPENUMFORMATETC)ret;
    return S_OK;
}

static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));

    if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) {
        IDataObject_AddRef(iface);
        *ppvObj = This;
        return S_OK;
    }
    *ppvObj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI DataObjectImpl_AddRef(IDataObject* iface)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p) ref=%d\n",This, ref);

    if(!ref) {
        if(This->unicode) GlobalFree(This->unicode);
        if(This->rtf) GlobalFree(This->rtf);
        if(This->fmtetc) GlobalFree(This->fmtetc);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", This, pformatetc->cfFormat, pformatetc->tymed);

    if(pformatetc->lindex != -1)
        return DV_E_LINDEX;

    if(!(pformatetc->tymed & TYMED_HGLOBAL))
        return DV_E_TYMED;

    if(This->unicode && pformatetc->cfFormat == CF_UNICODETEXT)
        pmedium->u.hGlobal = This->unicode;
    else if(This->rtf && pformatetc->cfFormat == cfRTF)
        pmedium->u.hGlobal = This->rtf;
    else
        return DV_E_FORMATETC;

    pmedium->tymed = TYMED_HGLOBAL;
    pmedium->pUnkForRelease = (LPUNKNOWN)iface;
    IUnknown_AddRef(pmedium->pUnkForRelease);
    return S_OK;
}

static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    UINT i;
    BOOL foundFormat = FALSE;
    TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", This, pformatetc->cfFormat, pformatetc->tymed);

    if(pformatetc->lindex != -1)
        return DV_E_LINDEX;

    for(i=0; i<This->fmtetc_cnt; i++) {
        if(This->fmtetc[i].cfFormat == pformatetc->cfFormat) {
            foundFormat = TRUE;
            if(This->fmtetc[i].tymed == pformatetc->tymed)
                return S_OK;
        }
    }
    return foundFormat?DV_E_FORMATETC:DV_E_TYMED;
}

static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatetcIn,
                                                           FORMATETC *pformatetcOut)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    TRACE("(%p)->(%p,%p)\n", This, pformatetcIn, pformatetcOut);

    if(pformatetcOut) {
        *pformatetcOut = *pformatetcIn;
        pformatetcOut->ptd = NULL;
    }
    return DATA_S_SAMEFORMATETC;
}

static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pformatetc,
                                             STGMEDIUM *pmedium, BOOL fRelease)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject* iface, DWORD dwDirection,
                                                   IEnumFORMATETC **ppenumFormatEtc)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    TRACE("(%p)->(%d)\n", This, dwDirection);

    if(dwDirection != DATADIR_GET) {
        FIXME("Unsupported direction: %d\n", dwDirection);
        /* WinXP riched20 also returns E_NOTIMPL in this case */
        *ppenumFormatEtc = NULL;
        return E_NOTIMPL;
    }
    return EnumFormatImpl_Create(This->fmtetc, This->fmtetc_cnt, ppenumFormatEtc);
}

static HRESULT WINAPI DataObjectImpl_DAdvise(IDataObject* iface, FORMATETC *pformatetc, DWORD advf,
                                             IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI DataObjectImpl_DUnadvise(IDataObject* iface, DWORD dwConnection)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI DataObjectImpl_EnumDAdvise(IDataObject* iface, IEnumSTATDATA **ppenumAdvise)
{
    DataObjectImpl *This = impl_from_IDataObject(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static const IDataObjectVtbl VT_DataObjectImpl =
{
    DataObjectImpl_QueryInterface,
    DataObjectImpl_AddRef,
    DataObjectImpl_Release,
    DataObjectImpl_GetData,
    DataObjectImpl_GetDataHere,
    DataObjectImpl_QueryGetData,
    DataObjectImpl_GetCanonicalFormatEtc,
    DataObjectImpl_SetData,
    DataObjectImpl_EnumFormatEtc,
    DataObjectImpl_DAdvise,
    DataObjectImpl_DUnadvise,
    DataObjectImpl_EnumDAdvise
};

static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
    int pars = 0;
    WCHAR *data;
    HANDLE ret;
    ME_DisplayItem *para;
    int nEnd = ME_GetCursorOfs(start) + nChars;

    /* count paragraphs in range */
    para = start->pPara;
    while((para = para->member.para.next_para) &&
          para->member.para.nCharOfs <= nEnd)
        pars++;

    ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1));
    data = GlobalLock(ret);
    ME_GetTextW(editor, data, nChars + pars, start, nChars, TRUE, FALSE);
    GlobalUnlock(ret);
    return ret;
}

typedef struct tagME_GlobalDestStruct
{
  HGLOBAL hData;
  int nLength;
} ME_GlobalDestStruct;

static DWORD CALLBACK ME_AppendToHGLOBAL(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
{
    ME_GlobalDestStruct *pData = (ME_GlobalDestStruct *)dwCookie;
    int nMaxSize;
    BYTE *pDest;

    nMaxSize = GlobalSize(pData->hData);
    if (pData->nLength+cb+1 >= cb) {
        /* round up to 2^17 */
        int nNewSize = (((nMaxSize+cb+1)|0x1FFFF)+1) & 0xFFFE0000;
        pData->hData = GlobalReAlloc(pData->hData, nNewSize, 0);
    }
    pDest = GlobalLock(pData->hData);
    memcpy(pDest + pData->nLength, lpBuff, cb);
    pData->nLength += cb;
    pDest[pData->nLength] = '\0';
    GlobalUnlock(pData->hData);
    *pcb = cb;

    return 0;
}

static HGLOBAL get_rtf_text(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
    EDITSTREAM es;
    ME_GlobalDestStruct gds;

    gds.hData = GlobalAlloc(GMEM_MOVEABLE, 0);
    gds.nLength = 0;
    es.dwCookie = (DWORD_PTR)&gds;
    es.pfnCallback = ME_AppendToHGLOBAL;
    ME_StreamOutRange(editor, SF_RTF, start, nChars, &es);
    GlobalReAlloc(gds.hData, gds.nLength+1, 0);
    return gds.hData;
}

HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
                         int nChars, LPDATAOBJECT *lplpdataobj)
{
    DataObjectImpl *obj;
    TRACE("(%p,%d,%d)\n", editor, ME_GetCursorOfs(start), nChars);

    obj = heap_alloc(sizeof(DataObjectImpl));
    if(cfRTF == 0)
        cfRTF = RegisterClipboardFormatA("Rich Text Format");

    obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl;
    obj->ref = 1;
    obj->unicode = get_unicode_text(editor, start, nChars);
    obj->rtf = NULL;

    obj->fmtetc_cnt = 1;
    if(editor->mode & TM_RICHTEXT)
        obj->fmtetc_cnt++;
    obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC));
    InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL);
    if(editor->mode & TM_RICHTEXT) {
        obj->rtf = get_rtf_text(editor, start, nChars);
        InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
    }

    *lplpdataobj = (LPDATAOBJECT)obj;
    return S_OK;
}
