/**************************************************************
 * 
 * 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/uno/Reference.h>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>

#include <cppuhelper/servicefactory.hxx>
#include <rtl/string.h>

#include "atlwindow.hxx"
#include "targetlistener.hxx"
#include "sourcelistener.hxx"
//#include "transferable.hxx"
#include <map>

#include <winbase.h>
using namespace com::sun::star::lang;
using namespace com::sun::star::datatransfer::dnd;
using namespace com::sun::star::datatransfer::dnd::DNDConstants;
using namespace cppu;
using namespace rtl;
using namespace std;

LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) ;


extern Reference< XMultiServiceFactory > MultiServiceFactory;
DWORD WINAPI MTAFunc(LPVOID pParams);

char* szSTAWin= "XDragSource::executeDrag is called from the same "
				"OLE STA thread that created the window.";
char* szMTAWin= "XDragSource::executeDrag is called from a MTA thread "
				"that did not create the window.";

WNDPROC wpOrigEditProc;

map<HWND, HWND> mapEditToMainWnd;

LRESULT AWindow::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	Reference<XComponent> xcompSource( m_xDragSource, UNO_QUERY);

	PostQuitMessage(0);


	m_xDropTarget=0;
	m_xDragSource=0;

	
     // Remove the subclass from the edit control. 
    ::SetWindowLong(m_hwndEdit, GWL_WNDPROC, 
                (LONG) wpOrigEditProc); 
            
	return 0;
}


LRESULT AWindow::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	// Prepare the EDIT control
    m_hwndEdit = CreateWindowA( 
        "EDIT",     // predefined class 
        NULL,       // no window title 
        WS_CHILD | WS_VISIBLE | WS_VSCROLL | 
            ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 
        0, 0, 0, 0, // set size in WM_SIZE message 
        m_hWnd,       // parent window 
        (HMENU) NULL, // edit control ID 
        (HINSTANCE) GetWindowLong( GWL_HINSTANCE), 
        NULL);  

	// the map is used in the window procedure for the edit window to associate the 
	// it to the right main window ( AWindow)
	mapEditToMainWnd[m_hwndEdit]= m_hWnd;
	// Superclass the edit window, because we want to process mouse messages
	wpOrigEditProc = (WNDPROC) ::SetWindowLongA(m_hwndEdit, 
                GWL_WNDPROC, (LONG) EditSubclassProc); 
            
	
	// Add text to the window. 
	if( m_isMTA)
		::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szMTAWin);
	else
		::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szSTAWin);


	// create the DragSource
	Reference< XInterface> xint= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDragSource"));
	m_xDragSource= Reference<XDragSource>( xint, UNO_QUERY);
	Reference<XInitialization> xInit( xint, UNO_QUERY);
	
	Any ar[2];
	ar[1]<<= (sal_uInt32)m_hWnd;
	xInit->initialize( Sequence<Any>( ar, 2) );

	//create the DropTarget
	Reference< XInterface> xintTarget= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDropTarget"));
	m_xDropTarget= Reference<XDropTarget>( xintTarget, UNO_QUERY);
	Reference<XInitialization> xInitTarget( xintTarget, UNO_QUERY);
	
	Any any;
	any <<= (sal_uInt32)m_hWnd;
	xInitTarget->initialize( Sequence<Any>( &any, 1) );


	m_xDropTarget->addDropTargetListener( static_cast<XDropTargetListener*>
		( new DropTargetListener( m_hwndEdit)) );
//	// make this window tho a drop target
	m_xDropTarget->setActive(sal_True);

	return 0;
}

// When the mouse is dragged for a second than a drag is initiated
LRESULT AWindow::OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	if( uMsg== WM_LBUTTONDOWN)
	{
		SetTimer( 1, 1000);
	}

	else if( uMsg == WM_LBUTTONUP)
	{
		KillTimer(  1);
	}

	return 0;
}

LRESULT AWindow::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	HRESULT hr;
	USES_CONVERSION;
	KillTimer( 1);
	if(m_xDragSource.is())
	{

		//Get the Text out of the Edit window
		int length= (int)::SendMessageA( m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);
		char * pBuffer= new char[length + 1];
		ZeroMemory( pBuffer, length + 1);
		::SendMessageA( m_hwndEdit, WM_GETTEXT, length, (LPARAM) pBuffer);
		
		IDataObject* pData= NULL;
		HRESULT hr= CreateDataCache( NULL, CLSID_NULL, __uuidof(IDataObject),(void**) &pData); 
		if( pData)
		{
			FORMATETC format={ CF_TEXT, NULL, DVASPECT_CONTENT, -1, };

			HGLOBAL mem= GlobalAlloc(GHND, length + 1 );
			void* pMem= GlobalLock( mem);
			memcpy( pMem, pBuffer, length+1);
			GlobalUnlock( mem);

			STGMEDIUM medium;
			medium.tymed= TYMED_HGLOBAL;
			medium.hGlobal= mem;
			medium.pUnkForRelease= NULL;

			pData->SetData( &format,  &medium, TRUE); // releases HGLOBAL eventually
			
			Reference<XTransferable> xTrans= m_aDataConverter.createTransferableFromDataObj( 
												MultiServiceFactory, pData);
	
			// call XDragSource::executeDrag from an MTA
			if( m_isMTA )
			{
				DWORD mtaThreadId;
				ThreadData data;
				data.source= m_xDragSource;
				data.transferable= xTrans;

				data.evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL);

				HANDLE hThread= CreateThread( NULL, 0, MTAFunc, &data, 0, &mtaThreadId);
				// We must wait until the thread copied the ThreadData structure
				WaitForSingleObject( data.evtThreadReady, INFINITE);
				CloseHandle( data.evtThreadReady);
					

			}
			else
			{
				m_xDragSource->startDrag( DragGestureEvent(), 
					ACTION_LINK|ACTION_MOVE|ACTION_COPY,
					0,
					0,
					xTrans,
					Reference<XDragSourceListener>( static_cast<XDragSourceListener*>(new DragSourceListener() ) ) );
			}	
		}

		delete[] pBuffer;
	}

	return 0;
}

LRESULT AWindow::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    // Make the edit control the size of the window's 
    // client area. 
    ::MoveWindow(m_hwndEdit, 
        0, 0,           // starting x- and y-coordinates 
        LOWORD(lParam), // width of client area 
        HIWORD(lParam), // height of client area 
        TRUE);          // repaint window 
    
	return 0;
}
LRESULT AWindow::OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    ::SetFocus(m_hwndEdit); 
    return 0; 
}
 


// Subclass procedure for EDIT window
LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) 
{ 

	if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
	{
		HWND hAWindow= mapEditToMainWnd[hwnd];
		::SendMessage( hAWindow, uMsg, wParam, lParam);

	}
    return CallWindowProc( wpOrigEditProc, hwnd, uMsg, 
        wParam, lParam); 
} 
 
