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



//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#include <svpm.h>
#include <string.h>
#include "Os2Clipboard.hxx"

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using namespace com::sun::star::datatransfer;
using namespace com::sun::star::datatransfer::clipboard;
using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities;
using namespace com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace cppu;
using namespace osl;
using namespace rtl;
using namespace os2;

const Type CPPUTYPE_SEQINT8	 = getCppuType( ( Sequence< sal_Int8 >* )0 );
const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );

#define DTRANS_OBJ_CLASSNAME "DTRANSOBJWND"

// -----------------------------------------------------------------------

inline void SetWindowPtr( HWND hWnd, Os2Clipboard* pThis )
{
	WinSetWindowULong( hWnd, QWL_USER, (ULONG)pThis );
}

inline Os2Clipboard* GetWindowPtr( HWND hWnd )
{
	return (Os2Clipboard*)WinQueryWindowULong( hWnd, QWL_USER );
}

// -----------------------------------------------------------------------

MRESULT EXPENTRY DtransObjWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 )
{

	switch ( nMsg )
	{
	case WM_DRAWCLIPBOARD:	// clipboard content has changed
		{
			Os2Clipboard* os2Clipboard = GetWindowPtr( hWnd);
			if (os2Clipboard)
			{
				//MutexGuard aGuard(os2Clipboard->m_aMutex);
				debug_printf("WM_DRAWCLIPBOARD os2Clipboard %08x\n", os2Clipboard);
				if (os2Clipboard->m_bInSetClipboardData)
				{
					debug_printf("WM_DRAWCLIPBOARD our change\n");
				}
				else
				{
					// notify listener for clipboard change
					debug_printf("WM_DRAWCLIPBOARD notify change\n");
					os2Clipboard->notifyAllClipboardListener();
				}
			}
		}
		break;
	}

	return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 );
}

// -----------------------------------------------------------------------

Os2Clipboard::Os2Clipboard() :
	m_aMutex(),
	WeakComponentImplHelper4< XClipboardEx, XClipboardNotifier, XServiceInfo, XInitialization > (m_aMutex),
	m_bInitialized(sal_False),
	m_bInSetClipboardData(sal_False)
{
	MutexGuard aGuard(m_aMutex);

	debug_printf("Os2Clipboard::Os2Clipboard\n");
	hAB = WinQueryAnchorBlock( HWND_DESKTOP );
	hText = 0;
	hBitmap = 0;

#if 0
	// register object class
	if ( WinRegisterClass( hAB, (PSZ)DTRANS_OBJ_CLASSNAME,
							(PFNWP)DtransObjWndProc, 0, sizeof(ULONG) ))
	{
		APIRET	rc;
		// create object window to get clip viewer messages
		hObjWnd = WinCreateWindow( HWND_OBJECT, (PCSZ)DTRANS_OBJ_CLASSNAME,
										(PCSZ)"", 0, 0, 0, 0, 0,
										HWND_OBJECT, HWND_TOP,
										222, NULL, NULL);
		// store pointer
		SetWindowPtr( hObjWnd, this);
		// register the viewer window
		rc = WinOpenClipbrd(hAB);
		rc = WinSetClipbrdViewer(hAB, hObjWnd);
		rc = WinCloseClipbrd(hAB);
	}
#endif

}

Os2Clipboard::~Os2Clipboard()
{
	debug_printf("Os2Clipboard::~Os2Clipboard\n");
}

void SAL_CALL Os2Clipboard::initialize( const Sequence< Any >& aArguments )
	throw(Exception, RuntimeException)
{
	if (!m_bInitialized)
	{
		for (sal_Int32 n = 0, nmax = aArguments.getLength(); n < nmax; n++)
			if (aArguments[n].getValueType() == getCppuType((OUString *) 0))
			{
				aArguments[0] >>= m_aName;
				break;
			}
	}
}

OUString SAL_CALL Os2Clipboard::getImplementationName() throw( RuntimeException )
{
	debug_printf("Os2Clipboard::getImplementationName\n");
	return OUString::createFromAscii( OS2_CLIPBOARD_IMPL_NAME );
}

sal_Bool SAL_CALL Os2Clipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException )
{
	debug_printf("Os2Clipboard::supportsService\n");
	Sequence < OUString > SupportedServicesNames = Os2Clipboard_getSupportedServiceNames();

	for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
		if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
			return sal_True;

	return sal_False;
}

Sequence< OUString > SAL_CALL Os2Clipboard::getSupportedServiceNames() throw( RuntimeException )
{
	debug_printf("Os2Clipboard::getSupportedServiceNames\n");
	return Os2Clipboard_getSupportedServiceNames();
}

Reference< XTransferable > SAL_CALL Os2Clipboard::getContents() throw( RuntimeException )
{
	debug_printf("Os2Clipboard::getContents\n");
	MutexGuard aGuard(m_aMutex);

	// os2 can have only one viewer at time, and we don't get a notification
	// when the viewer changes. So we need to check handles of clipboard
	// data and compare with previous handles
	if (UWinOpenClipbrd(hAB)) {
		sal_Bool	fireChanged = sal_False;
		ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT);
		if (handle) {
			if (handle != hText) {
				hText = handle;
				fireChanged = sal_True;
			}
		}
		handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP);
		if (handle) {
			if (handle != hBitmap) {
				hBitmap = handle;
				fireChanged = sal_True;
			}
		}
		UWinCloseClipbrd( hAB);
		if (fireChanged)
		{
			// notify listener for clipboard change
			debug_printf("Os2Clipboard::getContents notify change\n");
			notifyAllClipboardListener();
		}
	}

	if( ! m_aContents.is() )
		m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );

	return m_aContents;
}

void SAL_CALL Os2Clipboard::setContents( const Reference< XTransferable >& xTrans, const Reference< XClipboardOwner >& xClipboardOwner ) throw( RuntimeException )
{
	debug_printf("Os2Clipboard::setContents\n");
	// remember old values for callbacks before setting the new ones.
	ClearableMutexGuard aGuard(m_aMutex);

	Reference< XClipboardOwner > oldOwner(m_aOwner);
	m_aOwner = xClipboardOwner;

	Reference< XTransferable > oldContents(m_aContents);
	m_aContents = xTrans;

	aGuard.clear();

	// notify old owner on loss of ownership
	if( oldOwner.is() )
		oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents);

	// notify all listeners on content changes
	OInterfaceContainerHelper *pContainer =
		rBHelper.aLC.getContainer(getCppuType( (Reference < XClipboardListener > *) 0));
	if (pContainer)
	{
		ClipboardEvent aEvent(static_cast < XClipboard * > (this), m_aContents);
		OInterfaceIteratorHelper aIterator(*pContainer);

		while (aIterator.hasMoreElements())
		{
			Reference < XClipboardListener > xListener(aIterator.next(), UNO_QUERY);
			if (xListener.is())
				xListener->changedContents(aEvent);
		}
	}

#if OSL_DEBUG_LEVEL>0
	// dump list of available mimetypes
	Sequence< DataFlavor > aFlavors( m_aContents->getTransferDataFlavors() );
	for( int i = 0; i < aFlavors.getLength(); i++ )
		debug_printf("Os2Clipboard::setContents available mimetype: %d %s\n",
			i, CHAR_POINTER(aFlavors.getConstArray()[i].MimeType));
#endif

	// we can only export text or bitmap
	DataFlavor nFlavorText( OUString::createFromAscii( "text/plain;charset=utf-16" ),
						OUString::createFromAscii( "Unicode-Text" ), CPPUTYPE_OUSTRING);
	DataFlavor nFlavorBitmap( OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ),
						OUString::createFromAscii( "Bitmap" ), CPPUTYPE_DEFAULT);

	// try text transfer data (if any)
	PSZ pSharedText = NULL;
	HBITMAP hbm = NULL;
	try
	{
		Any aAny = m_aContents->getTransferData( nFlavorText );
		if (aAny.hasValue())
		{
			APIRET rc;
			// copy unicode text to clipboard
			OUString aString;
			aAny >>= aString;
			// share text
			rc = DosAllocSharedMem( (PPVOID) &pSharedText, NULL,
				aString.getLength() * 2 + 2,
				PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_ANY);
			if (!rc)
				memcpy( pSharedText, aString.getStr(), aString.getLength() * 2 + 2 );
			else
				pSharedText = NULL;
			debug_printf("Os2Clipboard::setContents SetClipbrdData text done\n");
		}
	} catch ( UnsupportedFlavorException&) {
		debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no text)\n");
	}

	// try bitmap transfer data (if any)
	try
	{
		Any aAnyB = m_aContents->getTransferData( nFlavorBitmap );
		if (aAnyB.hasValue())
		{
			hbm = OOoBmpToOS2Handle( aAnyB);
			debug_printf("Os2Clipboard::setContents SetClipbrdData bitmap done\n");
		}
	} catch ( UnsupportedFlavorException&) {
		debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no bitmap)\n");
	}

	// copy to clipboard only if we have data available, otherwise clipboard
	// remains in use and locks all other applications.
	if ( (pSharedText || hbm) && UWinOpenClipbrd( hAB) )
	{
		// set the flag, so we will ignore the next WM_DRAWCLIPBOARD
		// since we generate it with following code.
		m_bInSetClipboardData = sal_True;
		UWinEmptyClipbrd( hAB);
		// give pointer to clipboard (it will become owner of pSharedText!)
		if (pSharedText) {
			UWinSetClipbrdData( hAB, (ULONG) pSharedText, UCLIP_CF_UNICODETEXT, CFI_POINTER);
			// update internal handle to avoid detection of this text as new data
			hText = (ULONG)pSharedText;
		}
		// give bitmap to clipboard
		if (hbm) {
			UWinSetClipbrdData( hAB, (ULONG) hbm, UCLIP_CF_BITMAP, CFI_HANDLE);
			// update internal handle to avoid detection of this bitmap as new data
			hBitmap = hbm;
		}
		// reset the flag, so we will not ignore next WM_DRAWCLIPBOARD
		m_bInSetClipboardData = sal_False;
		UWinCloseClipbrd( hAB);
	}

}

OUString SAL_CALL Os2Clipboard::getName() throw( RuntimeException )
{
	debug_printf("Os2Clipboard::getName\n");
	return m_aName;
}

sal_Int8 SAL_CALL Os2Clipboard::getRenderingCapabilities() throw( RuntimeException )
{
	debug_printf("Os2Clipboard::getRenderingCapabilities\n");
	return Delayed;
}

//========================================================================
// XClipboardNotifier
//========================================================================

void SAL_CALL Os2Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
{
	debug_printf("Os2Clipboard::addClipboardListener\n");
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	if (!rBHelper.bInDispose && !rBHelper.bDisposed)
		rBHelper.aLC.addInterface( getCppuType( (const ::com::sun::star::uno::Reference< XClipboardListener > *) 0), listener );
}

void SAL_CALL Os2Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException )
{
	debug_printf("Os2Clipboard::removeClipboardListener\n");
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	if (!rBHelper.bInDispose && !rBHelper.bDisposed)
		rBHelper.aLC.removeInterface( getCppuType( (const Reference< XClipboardListener > *) 0 ), listener ); \
}

// ------------------------------------------------------------------------

void SAL_CALL Os2Clipboard::notifyAllClipboardListener( )
{
	if ( !rBHelper.bDisposed )
	{
		ClearableMutexGuard aGuard( rBHelper.rMutex );
		if ( !rBHelper.bDisposed )
		{
			aGuard.clear( );

			ClearableMutexGuard aGuard(m_aMutex);
			// copy member references on stack so they can be called
			// without having the mutex
			Reference< XClipboardOwner > xOwner( m_aOwner );
			Reference< XTransferable > xTrans( m_aContents );
			// clear members
			m_aOwner.clear();
			m_aContents.clear();
			// release the mutex
			aGuard.clear();

			// inform previous owner of lost ownership
			if ( xOwner.is() )
				xOwner->lostOwnership(static_cast < XClipboard * > (this), m_aContents);

			OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer(
				getCppuType( ( Reference< XClipboardListener > * ) 0 ) );

			if ( pICHelper )
			{
				try
				{
					OInterfaceIteratorHelper iter(*pICHelper);
					m_aContents = 0;
					m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) );
					ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), m_aContents);

					while(iter.hasMoreElements())
					{
						try
						{
							Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY);
							if (xCBListener.is())
								xCBListener->changedContents(aClipbEvent);
						}
						catch(RuntimeException&)
						{
							OSL_ENSURE( false, "RuntimeException caught" );
							debug_printf( "RuntimeException caught" );
						}
					}
				}
				catch(const ::com::sun::star::lang::DisposedException&)
				{
					OSL_ENSURE(false, "Service Manager disposed");
					debug_printf( "Service Manager disposed");

					// no further clipboard changed notifications
					//m_pImpl->unregisterClipboardViewer();
				}

			} // end if
		} // end if
	} // end if
}

// ------------------------------------------------------------------------

Sequence< OUString > SAL_CALL Os2Clipboard_getSupportedServiceNames()
{
	Sequence< OUString > aRet(1);
	aRet[0] = OUString::createFromAscii( OS2_CLIPBOARD_SERVICE_NAME );
	return aRet;
}

// ------------------------------------------------------------------------

Reference< XInterface > SAL_CALL Os2Clipboard_createInstance(
	const Reference< XMultiServiceFactory > & xMultiServiceFactory)
{
	return Reference < XInterface >( ( OWeakObject * ) new Os2Clipboard());
}
