/**************************************************************
 *
 * 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_sfx2.hxx"

#ifdef WNT

#undef WB_LEFT
#undef WB_RIGHT

#define UINT64 USE_WIN_UINT64
#define INT64 USE_WIN_INT64
#define UINT32 USE_WIN_UINT32
#define INT32 USE_WIN_INT32

#include <tools/presys.h>
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <tools/postsys.h>

#undef UINT64
#undef INT64
#undef UINT32
#undef INT32

#endif
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/io/XStream.hpp>


#include <osl/thread.h>
#include <vcl/gdimtf.hxx>
#include <vcl/graph.hxx>
#include <vcl/cvtgrf.hxx>
#include <vcl/outdev.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/salbtype.hxx>

#include <tools/stream.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/streamwrap.hxx>
#include <comphelper/processfactory.hxx>


#include "sfx2/sfxresid.hxx"
#include "graphhelp.hxx"
#include "doc.hrc"

using namespace ::com::sun::star;

#define THUMBNAIL_RESOLUTION 256

//---------------------------------------------------------------
// static
SvMemoryStream* GraphicHelper::getFormatStrFromGDI_Impl( const GDIMetaFile* pGDIMeta, sal_uInt32 nFormat )
{
	SvMemoryStream* pResult = NULL;
	if ( pGDIMeta )
	{
		SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
		if ( pStream )
		{
			Graphic aGraph( *pGDIMeta );
			if ( GraphicConverter::Export( *pStream, aGraph, nFormat ) == 0 )
				pResult = pStream;
			else
				delete pStream;
		}
	}

	return pResult;
}

//---------------------------------------------------------------
// static
void* GraphicHelper::getEnhMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta )
{
    (void)pGDIMeta;  // unused
	void* pResult = NULL;

#ifdef WNT
	if ( pGDIMeta )
	{
		String aStr = ::rtl::OUString::createFromAscii( ".emf" );
		::utl::TempFile aTempFile( ::rtl::OUString(),
								   &aStr,
								   NULL,
								   sal_False );

		::rtl::OUString aMetaFile = aTempFile.GetFileName();
		::rtl::OUString aMetaURL = aTempFile.GetURL();
		::rtl::OString aWinFile = ::rtl::OUStringToOString( aMetaFile, osl_getThreadTextEncoding() );

		SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMetaURL, STREAM_STD_READWRITE );
		if ( pStream )
		{
			Graphic aGraph( *pGDIMeta );
			sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_EMF );
			pStream->Flush();
			delete pStream;

			if ( !bFailed )
				pResult = GetEnhMetaFileA( aWinFile.getStr() );
		}
	}
#endif

	return pResult;
}

//---------------------------------------------------------------
// static
void* GraphicHelper::getWinMetaFileFromGDI_Impl( const GDIMetaFile* pGDIMeta, const Size& aMetaSize )
{
    (void)pGDIMeta;  // unused
    (void)aMetaSize; // unused
    void* pResult = NULL;

#ifdef WNT
	if ( pGDIMeta )
	{
		SvMemoryStream* pStream = new SvMemoryStream( 65535, 65535 );
		if ( pStream )
		{
			Graphic aGraph( *pGDIMeta );
			sal_Bool bFailed = (sal_Bool)GraphicConverter::Export( *pStream, aGraph, CVT_WMF );
			pStream->Flush();
			if ( !bFailed )
			{
				sal_Int32 nLength = pStream->Seek( STREAM_SEEK_TO_END );
				if ( nLength > 22 )
				{
					HMETAFILE hMeta = SetMetaFileBitsEx( nLength - 22,
									( reinterpret_cast< const sal_uChar*>( pStream->GetData() ) ) + 22 );

					if ( hMeta )
					{
						HGLOBAL hMemory = GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, sizeof( METAFILEPICT ) );

						if ( hMemory )
						{
   							METAFILEPICT* pMF = (METAFILEPICT*)GlobalLock( hMemory );

   							pMF->hMF = hMeta;
   							pMF->mm = MM_ANISOTROPIC;

							MapMode aMetaMode = pGDIMeta->GetPrefMapMode();
							MapMode aWinMode( MAP_100TH_MM );

							if ( aWinMode == pGDIMeta->GetPrefMapMode() )
							{
								pMF->xExt = aMetaSize.Width();
								pMF->yExt = aMetaSize.Height();
							}
							else
							{
								Size aWinSize = OutputDevice::LogicToLogic( Size( aMetaSize.Width(), aMetaSize.Height() ),
																			pGDIMeta->GetPrefMapMode(),
																			aWinMode );
								pMF->xExt = aWinSize.Width();
								pMF->yExt = aWinSize.Height();
							}

							GlobalUnlock( hMemory );
							pResult = (void*)hMemory;
						}
						else
   							DeleteMetaFile( hMeta );
					}
				}
			}

			delete pStream;
		}
	}

#endif


	return pResult;
}

//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::supportsMetaFileHandle_Impl()
{
#ifdef WNT
	return sal_True;
#else
	return sal_False;
#endif
}

//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::mergeBitmaps_Impl( const BitmapEx& rBmpEx, const BitmapEx& rOverlay,
				   const Rectangle& rOverlayRect, BitmapEx& rReturn )
{
	// the implementation is provided by KA

	Point			aNullPt;
	Rectangle		aBmpRect( aNullPt, rBmpEx.GetSizePixel() );
	VirtualDevice	aVDev;

	if( !rReturn.IsEmpty() )
		rReturn.SetEmpty();

	if( !rBmpEx.IsEmpty() && aVDev.SetOutputSizePixel( aBmpRect.GetSize() ) )
	{
		Rectangle aOverlayRect( rOverlayRect );

		aOverlayRect.Intersection( aBmpRect );

		if( rOverlay.IsEmpty() || rOverlayRect.IsEmpty() )
			rReturn = rBmpEx;
		else
		{
			aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetBitmap() );
			aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay );

			Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
			aBmp.Convert( BMP_CONVERSION_24BIT );

			if( !rBmpEx.IsTransparent() )
				rReturn = aBmp;
			else
			{
				aVDev.DrawBitmap( aNullPt, aVDev.GetOutputSizePixel(), rBmpEx.GetMask() );
				Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) );

				if( rOverlay.IsTransparent() )
					aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), rOverlay.GetMask() );
				else
				{
					aVDev.SetLineColor( COL_BLACK );
					aVDev.SetFillColor( COL_BLACK );
					aVDev.DrawRect( aOverlayRect);
				}

				aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND );
				aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp );
				rReturn = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
			}
		}
	}

	return !rReturn.IsEmpty();
}


//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::createThumb_Impl( const GDIMetaFile& rMtf,
				       sal_uInt32 nMaximumExtent,
				       BitmapEx& rBmpEx,
				       const BitmapEx* pOverlay,
				       const Rectangle* pOverlayRect )
{
	// the implementation is provided by KA

	// initialization seems to be complicated but is used to avoid rounding errors
	VirtualDevice	aVDev;
	const Point     aNullPt;
	const Point     aTLPix( aVDev.LogicToPixel( aNullPt, rMtf.GetPrefMapMode() ) );
	const Point     aBRPix( aVDev.LogicToPixel( Point( rMtf.GetPrefSize().Width() - 1, rMtf.GetPrefSize().Height() - 1 ), rMtf.GetPrefMapMode() ) );
	Size            aDrawSize( aVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
	Size			aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
	Point			aPosPix;

	if ( !rBmpEx.IsEmpty() )
		rBmpEx.SetEmpty();

	// determine size that has the same aspect ratio as image size and
	// fits into the rectangle determined by nMaximumExtent
	if ( aSizePix.Width() && aSizePix.Height() &&
            ( sal::static_int_cast<sal_uInt32>(aSizePix.Width()) > nMaximumExtent ||
              sal::static_int_cast<sal_uInt32>(aSizePix.Height()) > nMaximumExtent ) )
	{
		const Size  aOldSizePix( aSizePix );
		double      fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height();

		if ( fWH <= 1.0 )
		{
			aSizePix.Width() = FRound( nMaximumExtent * fWH );
			aSizePix.Height() = nMaximumExtent;
		}
		else
		{
			aSizePix.Width() = nMaximumExtent;
			aSizePix.Height() = FRound(  nMaximumExtent / fWH );
		}

		aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() );
		aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() );
	}

	Size 		aFullSize;
	Point		aBackPosPix;
	Rectangle 	aOverlayRect;

	// calculate addigtional positions and sizes if an overlay image is used
	if (  pOverlay )
	{
		aFullSize = Size( nMaximumExtent, nMaximumExtent );
		aOverlayRect = Rectangle( aNullPt, aFullSize  );

		aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) );

		if ( !aOverlayRect.IsEmpty() )
			aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 );
		else
			pOverlay = NULL;
	}
	else
	{
		aFullSize = aSizePix;
		pOverlay = NULL;
	}

	// draw image(s) into VDev and get resulting image
	if ( aVDev.SetOutputSizePixel( aFullSize ) )
	{
		// draw metafile into VDev
		const_cast< GDIMetaFile& >( rMtf ).WindStart();
		const_cast< GDIMetaFile& >( rMtf ).Play( &aVDev, aBackPosPix, aDrawSize );

		// draw overlay if necessary
		if ( pOverlay )
			aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay );

		// get paint bitmap
		Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );

		// assure that we have a true color image
		if ( aBmp.GetBitCount() != 24 )
			aBmp.Convert( BMP_CONVERSION_24BIT );

		rBmpEx = BitmapEx( aBmp );
	}

	return !rBmpEx.IsEmpty();
}

//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::getThumbnailFormatFromGDI_Impl( GDIMetaFile* pMetaFile,
														sal_Bool bSigned,
														const uno::Reference< io::XStream >& xStream )
{
	sal_Bool bResult = sal_False;
	SvStream* pStream = NULL;

	if ( xStream.is() )
		pStream = ::utl::UcbStreamHelper::CreateStream( xStream );

	if ( pMetaFile && pStream && !pStream->GetError() )
	{
		BitmapEx aResultBitmap;
		BitmapEx* pSignatureBitmap = NULL;

		if ( bSigned )
			pSignatureBitmap = new BitmapEx( SfxResId( BMP_SIGNATURE ) );

		bResult = createThumb_Impl( *pMetaFile,
			       				    THUMBNAIL_RESOLUTION,
			       				    aResultBitmap,
								    pSignatureBitmap );
		if ( bResult )
			bResult = ( !aResultBitmap.IsEmpty()
						&& GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
						&& ( pStream->Flush(), !pStream->GetError() ) );

		if ( pSignatureBitmap )
			delete pSignatureBitmap;

		delete pStream;
	}

	return bResult;
}

//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::getSignedThumbnailFormatFromBitmap_Impl( const BitmapEx& aBitmap,
																 const uno::Reference< io::XStream >& xStream )
{
	sal_Bool bResult = sal_False;
	SvStream* pStream = NULL;

	if ( xStream.is() )
		pStream = ::utl::UcbStreamHelper::CreateStream( xStream );

	if ( pStream && !pStream->GetError() )
	{
		BitmapEx aResultBitmap;
		BitmapEx aSignatureBitmap( SfxResId( BMP_SIGNATURE ) );

		bResult = mergeBitmaps_Impl( aBitmap,
									aSignatureBitmap,
									Rectangle( Point(), aBitmap.GetSizePixel() ),
									aResultBitmap );

		if ( bResult )
		{
			bResult = ( !aResultBitmap.IsEmpty()
						&& GraphicConverter::Export( *pStream, aResultBitmap, CVT_PNG ) == 0
						&& ( pStream->Flush(), !pStream->GetError() ) );
		}

		delete pStream;
	}

	return bResult;
}

//---------------------------------------------------------------
// static
sal_Bool GraphicHelper::getThumbnailReplacement_Impl( sal_Int32 nResID, const uno::Reference< io::XStream >& xStream )
{
	sal_Bool bResult = sal_False;
	if ( nResID && xStream.is() )
	{
    	uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
		if ( xServiceManager.is() )
		{
			try
			{
				uno::Reference< graphic::XGraphicProvider > xGraphProvider(
					xServiceManager->createInstance(
						::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
					uno::UNO_QUERY );
				if ( xGraphProvider.is() )
				{
					::rtl::OUString aURL = ::rtl::OUString::createFromAscii( "private:resource/sfx/bitmapex/" );
					aURL += ::rtl::OUString::valueOf( nResID );

					uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
					aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" );
					aMediaProps[0].Value <<= aURL;

					uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
					if ( xGraphic.is() )
					{
						uno::Sequence< beans::PropertyValue > aStoreProps( 2 );
						aStoreProps[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
						aStoreProps[0].Value <<= xStream;
						aStoreProps[1].Name = ::rtl::OUString::createFromAscii( "MimeType" );
						aStoreProps[1].Value <<= ::rtl::OUString::createFromAscii( "image/png" );

						xGraphProvider->storeGraphic( xGraphic, aStoreProps );
						bResult = sal_True;
					}
				}
			}
			catch( uno::Exception& )
			{
			}
		}
	}

	return bResult;
}

//---------------------------------------------------------------
// static
sal_uInt16 GraphicHelper::getThumbnailReplacementIDByFactoryName_Impl( const ::rtl::OUString& aFactoryShortName, sal_Bool /*bIsTemplate*/ )
{
	sal_uInt16 nResult = 0;

	if ( aFactoryShortName.equalsAscii( "scalc" ) )
	{
		nResult = BMP_128X128_CALC_DOC;
	}
	else if ( aFactoryShortName.equalsAscii( "sdraw" ) )
	{
		nResult = BMP_128X128_DRAW_DOC;
	}
	else if ( aFactoryShortName.equalsAscii( "simpress" ) )
	{
		nResult = BMP_128X128_IMPRESS_DOC;
	}
	else if ( aFactoryShortName.equalsAscii( "smath" ) )
	{
		nResult = BMP_128X128_MATH_DOC;
	}
	else if ( aFactoryShortName.equalsAscii( "swriter" ) || aFactoryShortName.compareToAscii( "swriter/", 8 ) == 0 )
	{
		nResult = BMP_128X128_WRITER_DOC;
	}

	return nResult;
}
