/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/


// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dtrans.hxx"
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/MouseEvent.hpp>

#include <vcl/window.hxx>

#include "DragSource.hxx"
#include "globals.hxx"

using namespace com::sun::star::datatransfer::dnd::DNDConstants;

// for AOO internal D&D we provide the Transferable
Reference<XTransferable> DragSource::g_XTransferable;
// the handle of the window starting the drag
HWND DragSource::g_DragSourceHwnd = NULLHANDLE;


DragSource::DragSource( const Reference<XMultiServiceFactory>& sf):
    WeakComponentImplHelper4< XDragSource,
            XInitialization,
            XDragSourceContext,
            XServiceInfo >(m_aMutex),
    m_serviceFactory(sf),
    pSourceDraginfo(NULL),
    pSharedMem(NULL),
    pDTShareMem(NULL)
{
    g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt);
    debug_printf("DragSource::DragSource");
}

DragSource::~DragSource()
{
    g_moduleCount.modCnt.release( &g_moduleCount.modCnt);
    debug_printf("DragSource::~DragSource");
}

// XInitialization

//
// aArguments contains a machine id
//
void SAL_CALL DragSource::initialize( const Sequence< Any >& aArguments )
throw(Exception, RuntimeException)
{
    if (aArguments.getLength() < 2) {
        throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Not enough parameter.")),
                        static_cast<OWeakObject*>(this));
    }

    m_hWnd = *(HWND*)aArguments[1].getValue();
    debug_printf("DragSource::initialize hwnd %x", m_hWnd);
    // init done in DropTarget, window is already subclassed
    SetWindowDragSourcePtr( m_hWnd, this);
}

void SAL_CALL DragSource::disposing()
{
    debug_printf("DragSource::disposing hwnd %x", m_hWnd);
    SetWindowDragSourcePtr( m_hWnd, 0);
}

// XDragSource
sal_Bool SAL_CALL DragSource::isDragImageSupported(  )
throw(RuntimeException)
{
    return 0;
}

sal_Int32 SAL_CALL DragSource::getDefaultCursor( sal_Int8 /*dragAction*/ )
throw( IllegalArgumentException, RuntimeException)
{
    return 0;
}

//
// Notifies the XDragSourceListener by calling dragDropEnd
//
void SAL_CALL DragSource::startDrag(
    const DragGestureEvent& /* trigger */,
    sal_Int8 sourceActions,
    sal_Int32 /* cursor */,
    sal_Int32 /* image */,
    const Reference<XTransferable >& trans,
    const Reference<XDragSourceListener >& listener ) throw( RuntimeException)
{
    debug_printf("DragSource::startDrag hwnd %x, sourceActions %d",
                 m_hWnd, sourceActions);

    DRAGITEM    dragItem;
    DRAGIMAGE   dimg;
    HSTR        hstrType, hstrRMF;
    HWND        hwndTarget;

    // store transferable for internal AOO d&d operations
    g_XTransferable = trans;
    // store drag source window handle in a global field since we can
    // start only one drag operation at time
    g_DragSourceHwnd = m_hWnd;

#if 1
    // dump data flavours
    Sequence<DataFlavor> seq = g_XTransferable->getTransferDataFlavors();
    for( int i=0; i<seq.getLength(); i++) {
        DataFlavor df = seq[i];
        debug_printf("DragSource::startDrag mimetype %s",
                     ::rtl::OUStringToOString( df.MimeType, RTL_TEXTENCODING_UTF8 ).getStr());
    }
#endif

    dragSourceListener = listener;
    debug_printf("DragSource::startDrag dragSourceListener 0x%x", dragSourceListener.get());

    // allocate OS/2 specific resources
    pSourceDraginfo = DrgAllocDraginfo(1);
    pSourceDraginfo->hwndSource = m_hWnd;

    hstrType = DrgAddStrHandle( DRT_TEXT);
    hstrRMF = DrgAddStrHandle( "<DRM_DTSHARE,DRF_TEXT>,<DRM_SHAREDMEM,DRF_TEXT>,<DRM_OS2FILE,DRF_TEXT>");

    dragItem.hwndItem          = m_hWnd;
    dragItem.ulItemID          = 1;
    dragItem.hstrType          = hstrType;
    dragItem.hstrRMF           = hstrRMF;
    dragItem.hstrContainerName = NULL; // force rendering
    dragItem.hstrSourceName    = NULL;
    dragItem.hstrTargetName    = NULL;
    dragItem.fsControl         = 0;
    dragItem.fsSupportedOps    = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;

    dimg.cb       = sizeof(dimg);
    dimg.hImage   = WinQuerySysPointer( HWND_DESKTOP, SPTR_FILE, FALSE);
    dimg.fl       = DRG_ICON | DRG_TRANSPARENT;
    dimg.cxOffset = 0;
    dimg.cyOffset = 0;

    DrgSetDragitem( pSourceDraginfo, &dragItem, sizeof(dragItem), 0);

    // start PM dragging
    hwndTarget = DrgDrag( m_hWnd, pSourceDraginfo, &dimg, 1L, VK_BUTTON2, NULL);
    if (hwndTarget == NULLHANDLE) {
        // post a dummy message to ourselves to allow freeing resources
        // (yes, we could call endConversation() directly)
        WinPostMsg( m_hWnd, DM_AOO_ENDCONVERSATION,
                    0, MPFROMSHORT(DMFL_TARGETFAIL));
    }

    debug_printf("DragSource::startDrag hwndTarget %x", hwndTarget);

}

// XDragSourceContext
sal_Int32 SAL_CALL DragSource::getCurrentCursor(  )
throw( RuntimeException)
{
    return 0;
}

void SAL_CALL DragSource::setCursor( sal_Int32 /*cursorId*/ )
throw( RuntimeException)
{
}

void SAL_CALL DragSource::setImage( sal_Int32 /*imageId*/ )
throw( RuntimeException)
{
}

void SAL_CALL DragSource::transferablesFlavorsChanged(  )
throw( RuntimeException)
{
}


//
// XServiceInfo
//
OUString SAL_CALL DragSource::getImplementationName(  ) throw (RuntimeException)
{
    return OUString(RTL_CONSTASCII_USTRINGPARAM(OS2_DNDSOURCE_IMPL_NAME));
}

sal_Bool SAL_CALL DragSource::supportsService( const OUString& ServiceName ) throw (RuntimeException)
{
    if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(OS2_DNDSOURCE_SERVICE_NAME ))))
        return sal_True;
    return sal_False;
}

Sequence< OUString > SAL_CALL DragSource::getSupportedServiceNames(  ) throw (RuntimeException)
{
    OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(OS2_DNDSOURCE_SERVICE_NAME))};
    return Sequence<OUString>(names, 1);
}


//
// OS/2 specific platform code
//


//
// AOO as source window vs external drop target.
//
// this is sent when drop target requests the render
//
MRESULT DragSource::render( PDRAGTRANSFER pdxfer)
{
    APIRET rc;
    ULONG ulLength;
    PSZ pRMF;
    bool rv = false;

    ulLength = DrgQueryStrNameLen( pdxfer->hstrSelectedRMF) + 1;
    pRMF = (PSZ) malloc( ulLength);
    DrgQueryStrName( pdxfer->hstrSelectedRMF, ulLength, pRMF);
    debug_printf("DragSource::render RMF:%s", pRMF);
    debug_printf("DragSource::render hstrRenderToName:%x", pdxfer->hstrRenderToName);

    if (strstr( pRMF, "<DRM_DTSHARE") != 0) {

        char DTShareName[CCHMAXPATH];

        DataFlavor df;
        df.MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
        df.DataType = getCppuType( static_cast<OUString*>(0));

        Any aAny = DragSource::g_XTransferable->getTransferData(df);
        OUString utext;
        aAny >>= utext;
        OString text = ::rtl::OUStringToOString( utext, RTL_TEXTENCODING_UTF8).getStr();
        debug_printf("DragSource::render text:%s", text.getStr());
        debug_printf("DragSource::render text.getLength():%d", text.getLength());

        DrgQueryStrName( pdxfer->hstrRenderToName, sizeof(DTShareName),
                         DTShareName);
        debug_printf("DragSource::render hstrRenderToName:%s", DTShareName);

        rc = DosGetNamedSharedMem( (PPVOID) &pDTShareMem, DTShareName,
                                   PAG_WRITE | PAG_READ);
        debug_printf("DragSource::render DosGetNamedSharedMem rc:%d", rc);
        debug_printf("DragSource::render DosGetNamedSharedMem pSharedMem:%x", pSharedMem);

        // the memory is still not committed
        rc = DosSetMem( pDTShareMem, text.getLength()+1, PAG_DEFAULT | PAG_COMMIT);
        debug_printf("DragSource::render DosSetMem rc:%d", rc);

        // first ULONG is text length
        *(ULONG*) pDTShareMem = text.getLength();
        // text data from 2nd ULONG
        memcpy( pDTShareMem + sizeof(ULONG), text.getStr(),
                text.getLength()+1);

        // return success
        rv = true;

    } else if (strstr( pRMF, "<DRM_SHAREDMEM") != 0) {

        PID pid;
        TID tid;
        DataFlavor df;
        df.MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
        df.DataType = getCppuType( static_cast<OUString*>(0));

        Any aAny = DragSource::g_XTransferable->getTransferData(df);
        OUString utext;
        aAny >>= utext;
        OString text = ::rtl::OUStringToOString( utext, RTL_TEXTENCODING_UTF8).getStr();
        debug_printf("DragSource::render text:%s", text.getStr());
        debug_printf("DragSource::render text.getLength():%d", text.getLength());

        rc = DosAllocSharedMem( (PPVOID) &pSharedMem, NULL,
                                       text.getLength()+sizeof(ULONG)+1,
                                       OBJ_GIVEABLE | PAG_COMMIT |
                                       PAG_WRITE | PAG_READ /*| OBJ_ANY*/);

        rc = WinQueryWindowProcess( pdxfer->hwndClient, &pid, &tid);
        rc = DosGiveSharedMem( pSharedMem, pid, PAG_READ);

        debug_printf("DragSource::render rc:%d", rc);
        *(ULONG *) pSharedMem = text.getLength();
        memcpy( pSharedMem + sizeof(ULONG), text.getStr(), text.getLength()+1);
        pdxfer->hstrRenderToName = (HSTR) pSharedMem;

        // return success
        rv = true;

    } else if (strstr( pRMF, "<DRM_OS2FILE") != 0) {

        char fileName[CCHMAXPATH];

        DataFlavor df;
        df.MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
        df.DataType = getCppuType( static_cast<OUString*>(0));

        Any aAny = DragSource::g_XTransferable->getTransferData(df);
        OUString utext;
        aAny >>= utext;
        OString text = ::rtl::OUStringToOString( utext, RTL_TEXTENCODING_UTF8).getStr();
        debug_printf("DragSource::render text:%s", text.getStr());
        debug_printf("DragSource::render text.getLength():%d", text.getLength());

        DrgQueryStrName( pdxfer->hstrRenderToName, sizeof(fileName), fileName);
        debug_printf("DragSource::render hstrRenderToName:%s", fileName);

        // write data to target file
        FILE* tmp = fopen( fileName, "wb");
        if (tmp) {
            fwrite( text.getStr(), 1, text.getLength(), tmp);
            fclose( tmp);
            rv = true;
        }

    } else {

        debug_printf("DragSource::render INTERNAL ERROR unknown type");

    }

    free( pRMF);

    // post rendered data
    int renderOK = (rv==true) ? DMFL_RENDEROK : DMFL_RENDERFAIL;
    debug_printf("DragSource::render render:%d", renderOK);
    rc = DrgPostTransferMsg( pdxfer->hwndClient, DM_RENDERCOMPLETE, pdxfer,
                        renderOK, 0, FALSE);
    debug_printf("DragSource::render DrgPostTransferMsg:%d", rc);

    // free resources
    DrgFreeDragtransfer(pdxfer);

    return (MRESULT) rv;
}

//
// AOO as source window vs external drop target.
//
// this is sent when external drop target requests the render
//
MRESULT DragSource::endConversation( ULONG itemID, ULONG flags)
{
    sal_Bool success = ((flags==DMFL_TARGETSUCCESSFUL) ? true : false);
    sal_Int8 effect = ACTION_NONE;

    debug_printf("DragSource::endConversation itemID %d, flags %d", itemID, flags);

    if (pDTShareMem)
        DosFreeMem( pDTShareMem);
    pDTShareMem = NULL;
    if (pSharedMem)
        DosFreeMem( pSharedMem);
    pSharedMem = NULL;

    if (pSourceDraginfo) {
        // query which kind of operation the target did with our data
        if (success == true)
            effect = SystemToOfficeDragActions( pSourceDraginfo->usOperation);
        debug_printf("DragSource::endConversation usOperation 0x%x", pSourceDraginfo->usOperation);
        DrgDeleteDraginfoStrHandles( pSourceDraginfo);
        DrgFreeDraginfo( pSourceDraginfo);
    }
    pSourceDraginfo = NULL;

    // terminate AOO drag
    DragSourceDropEvent de(static_cast<OWeakObject*>(this),
                           static_cast<XDragSourceContext*>(this),
                           static_cast<XDragSource*>(this),
                           effect,
                           success);
    dragSourceListener->dragDropEnd( de);

    // clear globals
    g_XTransferable = Reference<XTransferable>();
    g_DragSourceHwnd = NULLHANDLE;
    dragSourceListener = Reference<XDragSourceListener>();

    // Reserved value, should be 0
    return 0;
}
