/**************************************************************
 *
 * 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"

#if defined _MSC_VER
#pragma warning(push,1)
#endif
#include <windows.h>
#include <comdef.h>
#include <tchar.h>
#include <atlbase.h>
CComModule _Module;
#include<atlcom.h>
#include<atlimpl.cpp>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>

#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <rtl/process.h>
#include <cppuhelper/servicefactory.hxx>
//#include "transferable.hxx"
#include "sourcelistener.hxx"


#include "atlwindow.hxx"
BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

using namespace com::sun::star::lang;
using namespace com::sun::star::datatransfer;
using namespace com::sun::star::uno;
using namespace com::sun::star::datatransfer::dnd;
using namespace com::sun::star::datatransfer::dnd::DNDConstants;
using namespace rtl;

// defined in atlwindow.hxx
// #define WM_SOURCE_INIT WM_APP+100
// #define WM_SOURCE_STARTDRAG WM_APP+101
#define WM_CREATE_MTA_WND

HRESULT doTest();
DWORD WINAPI MTAFunc( void* threadData);

Reference< XMultiServiceFactory > MultiServiceFactory;
//int APIENTRY WinMain(HINSTANCE hInstance,
//                     HINSTANCE hPrevInstance,
//                     LPSTR     lpCmdLine,
//                     int       nCmdShow)
//int _tmain( int argc, TCHAR *argv[ ], TCHAR *envp[ ] )
int main( int argc, char *argv[ ], char *envp[ ] )
{
	HRESULT hr;
	if( FAILED( hr=CoInitialize(NULL )))
	{
		_tprintf(_T("CoInitialize failed \n"));
		return -1;
	}


	_Module.Init( ObjectMap, GetModuleHandle( NULL));

	if( FAILED(hr=doTest()))
	{
		_com_error err( hr);
		const TCHAR * errMsg= err.ErrorMessage();
//		MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR);
	}


	_Module.Term();
	CoUninitialize();
	return 0;
}

HRESULT doTest()
{

	MultiServiceFactory= createRegistryServiceFactory( OUString(L"types.rdb"), OUString( L"services.rdb") , sal_True);

	// create the MTA thread that is used to realize MTA calls to the services
	// We create the thread and wait until the thread has created its message queue
	HANDLE evt= CreateEvent(NULL, FALSE, FALSE, NULL);
	DWORD threadIdMTA=0;
	HANDLE hMTAThread= CreateThread( NULL, 0, MTAFunc, &evt, 0, &threadIdMTA);
	WaitForSingleObject( evt, INFINITE);
	CloseHandle(evt);


	HRESULT hr= S_OK;
	RECT pos1={0,0,300,200};
	AWindow win(_T("DnD starting in Ole STA"), threadIdMTA, pos1);

	RECT pos2={ 0, 205, 300, 405};
	AWindow win2( _T("DnD starting in MTA"), threadIdMTA, pos2, true);

	// win3 and win4 call initialize from an MTA but they are created in an STA
	RECT pos3={300,0,600,200};
	AWindow win3(_T("DnD starting in OLE STA"), threadIdMTA, pos3, false, true);

	RECT pos4={ 300, 205, 600, 405};
	AWindow win24( _T("DnD starting in Ole MTA"), threadIdMTA, pos4, true, true);


	MSG msg;
	while( GetMessage(&msg, (HWND)NULL, 0, 0) )
	{
		TranslateMessage(  &msg);
		DispatchMessage( &msg);
	}

	// Shut down the MTA thread
	PostThreadMessage( threadIdMTA, WM_QUIT, 0, 0);
	WaitForSingleObject(hMTAThread, INFINITE);
	CloseHandle(hMTAThread);

	return S_OK;
}

extern Reference<XMultiServiceFactory> MultiServiceFactory;
DWORD WINAPI MTAFunc( void* threadData)
{
	HRESULT hr= S_OK;
	hr= CoInitializeEx( NULL, COINIT_MULTITHREADED);
	ATLASSERT( FAILED(hr) );
	MSG msg;
	// force the creation of a message queue
	PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
	SetEvent( *(HANDLE*)threadData );

	RECT pos={0, 406, 300, 605};
	AWindow win(_T("DnD, full MTA"), GetCurrentThreadId(), pos, false, true);
//	ThreadData data= *( ThreadData*)pParams;
//	SetEvent(data.evtThreadReady);
	while( GetMessage(&msg, (HWND)NULL, 0, 0) )
	{
		switch( msg.message)
		{
		case  WM_SOURCE_INIT:
		{
			InitializationData* pData= (InitializationData*)msg.wParam;
			Any any;
			any <<= (sal_uInt32) pData->hWnd;
			pData->xInit->initialize( Sequence<Any>( &any, 1));

			CoTaskMemFree( pData);
			break;
		}
		case WM_SOURCE_STARTDRAG:
		{
			// wParam contains necessary data
			StartDragData* pData= (StartDragData*)msg.wParam;
			Sequence<DataFlavor> seq= pData->transferable->getTransferDataFlavors();
			// have a look what flavours are supported
			for( int i=0; i<seq.getLength(); i++)
			{
				DataFlavor d= seq[i];
			}
			pData->source->startDrag( DragGestureEvent(),
									  ACTION_LINK|ACTION_MOVE|ACTION_COPY,
									  0,
									  0,
									  pData->transferable,
									  Reference<XDragSourceListener>( static_cast<XDragSourceListener*>
																	  ( new DragSourceListener())));
			CoTaskMemFree( pData);
			break;
		}

		} // end switch

		TranslateMessage(  &msg);
		DispatchMessage( &msg);
	}


	CoUninitialize();
	return 0;
}
