/**************************************************************
 * 
 * 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_embeddedobj.hxx"
#include <com/sun/star/embed/XEmbedObjectCreator.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/embed/EntryInitModes.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/datatransfer/DataFlavor.hpp>
#include <com/sun/star/ucb/CommandAbortedException.hpp>


#include <osl/thread.h>
#include <osl/file.hxx>
#include <vos/module.hxx>
#include <comphelper/classids.hxx>

#include "platform.h"
#include <comphelper/mimeconfighelper.hxx>

#include "xdialogcreator.hxx"
#include "oleembobj.hxx"
// LLA: tip from FS
// #include <confighelper.hxx>
#include <xdialogcreator.hxx>
#include <oleembobj.hxx>


#ifdef WNT

#include <oledlg.h>

class InitializedOleGuard
{
public:
	InitializedOleGuard()
	{
		if ( !SUCCEEDED( OleInitialize( NULL ) ) )
			throw ::com::sun::star::uno::RuntimeException();
	}

	~InitializedOleGuard()
	{
		OleUninitialize();
	}
};

extern "C" {
typedef UINT STDAPICALLTYPE OleUIInsertObjectA_Type(LPOLEUIINSERTOBJECTA);
}

#endif


using namespace ::com::sun::star;
using namespace ::comphelper;
//-------------------------------------------------------------------------
uno::Sequence< sal_Int8 > GetRelatedInternalID_Impl( const uno::Sequence< sal_Int8 >& aClassID )
{
	// Writer
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SW_CLASSID_60 );

	// Calc
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SC_CLASSID_60 );

	// Impress
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_CLASSID_60 );

	// Draw
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_CLASSID_60 );

	// Chart
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_CLASSID_60 );

	// Math
	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_60 ) )
	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_8 ) ) )
		return MimeConfigurationHelper::GetSequenceClassID( SO3_SM_CLASSID_60 );

	return aClassID;
}

//-------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL MSOLEDialogObjectCreator::impl_staticGetSupportedServiceNames()
{
    uno::Sequence< ::rtl::OUString > aRet(2);
    aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.MSOLEObjectSystemCreator");
    aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.MSOLEObjectSystemCreator");
    return aRet;
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::impl_staticGetImplementationName()
{
    return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.MSOLEObjectSystemCreator");
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL MSOLEDialogObjectCreator::impl_staticCreateSelfInstance(
			const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
{
	return uno::Reference< uno::XInterface >( *new MSOLEDialogObjectCreator( xServiceManager ) );
}

//-------------------------------------------------------------------------
embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDialog(
			const uno::Reference< embed::XStorage >& xStorage,
			const ::rtl::OUString& sEntName,
			const uno::Sequence< beans::PropertyValue >& aInObjArgs )
	throw ( lang::IllegalArgumentException,
			io::IOException,
			uno::Exception,
			uno::RuntimeException )
{
	embed::InsertedObjectInfo aObjectInfo;
	uno::Sequence< beans::PropertyValue > aObjArgs( aInObjArgs );

#ifdef WNT

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	InitializedOleGuard aGuard;

	OLEUIINSERTOBJECT io;
	char szFile[MAX_PATH];
	UINT uTemp;

	memset(&io, 0, sizeof(io));

	io.cbStruct = sizeof(io);
	io.hWndOwner = GetActiveWindow();

	szFile[0] = 0;
	io.lpszFile = szFile;
	io.cchFile = MAX_PATH;

	io.dwFlags = IOF_SELECTCREATENEW | IOF_DISABLELINK;


	::vos::OModule aOleDlgLib;
	if( !aOleDlgLib.load( ::rtl::OUString::createFromAscii( "oledlg" ) ) )
		throw uno::RuntimeException();

	OleUIInsertObjectA_Type * pInsertFct = (OleUIInsertObjectA_Type *)
								aOleDlgLib.getSymbol( ::rtl::OUString::createFromAscii( "OleUIInsertObjectA" ) );
	if( !pInsertFct )
		throw uno::RuntimeException();

	uTemp=pInsertFct(&io);

	if ( OLEUI_OK == uTemp )
	{
		if (io.dwFlags & IOF_SELECTCREATENEW)
		{
			uno::Reference< embed::XEmbedObjectCreator > xEmbCreator(
						m_xFactory->createInstance(
								::rtl::OUString::createFromAscii( "com.sun.star.embed.EmbeddedObjectCreator" ) ),
						uno::UNO_QUERY );
			if ( !xEmbCreator.is() )
				throw uno::RuntimeException();

			uno::Sequence< sal_Int8 > aClassID = MimeConfigurationHelper::GetSequenceClassID( io.clsid.Data1,
																	 io.clsid.Data2,
																	 io.clsid.Data3,
																	 io.clsid.Data4[0],
																	 io.clsid.Data4[1],
																	 io.clsid.Data4[2],
																	 io.clsid.Data4[3],
																	 io.clsid.Data4[4],
																	 io.clsid.Data4[5],
																	 io.clsid.Data4[6],
																	 io.clsid.Data4[7] );

			aClassID = GetRelatedInternalID_Impl( aClassID );

			//TODO: retrieve ClassName
			::rtl::OUString aClassName;
			aObjectInfo.Object = uno::Reference< embed::XEmbeddedObject >(
							xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, aObjArgs ),
							uno::UNO_QUERY );
		}
		else
		{
			::rtl::OUString aFileName = ::rtl::OStringToOUString( ::rtl::OString( szFile ), osl_getThreadTextEncoding() );
    		rtl::OUString aFileURL;
        	if ( osl::FileBase::getFileURLFromSystemPath( aFileName, aFileURL ) != osl::FileBase::E_None )
				throw uno::RuntimeException();

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

			// TODO: use config helper for type detection
			uno::Reference< embed::XEmbedObjectCreator > xEmbCreator;
			::comphelper::MimeConfigurationHelper aHelper( m_xFactory );

			if ( aHelper.AddFilterNameCheckOwnFile( aMediaDescr ) )
				xEmbCreator = uno::Reference< embed::XEmbedObjectCreator >(
						m_xFactory->createInstance(
								::rtl::OUString::createFromAscii( "com.sun.star.embed.EmbeddedObjectCreator" ) ),
						uno::UNO_QUERY );
			else
				xEmbCreator = uno::Reference< embed::XEmbedObjectCreator >(
						m_xFactory->createInstance(
								::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
						uno::UNO_QUERY );

			if ( !xEmbCreator.is() )
				throw uno::RuntimeException();

			aObjectInfo.Object = uno::Reference< embed::XEmbeddedObject >(
							xEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aMediaDescr, aObjArgs ),
							uno::UNO_QUERY );
		}

		if ( ( io.dwFlags & IOF_CHECKDISPLAYASICON) && io.hMetaPict != NULL )
		{
			METAFILEPICT* pMF = ( METAFILEPICT* )GlobalLock( io.hMetaPict );
			if ( pMF )
			{
				sal_uInt32 nBufSize = GetMetaFileBitsEx( pMF->hMF, 0, NULL );
				uno::Sequence< sal_Int8 > aMetafile( nBufSize + 22 );
				sal_uInt8* pBuf = (sal_uInt8*)( aMetafile.getArray() );
				*( (long* )pBuf ) = 0x9ac6cdd7L;
				*( (short* )( pBuf+6 )) = ( SHORT ) 0;
				*( (short* )( pBuf+8 )) = ( SHORT ) 0;
				*( (short* )( pBuf+10 )) = ( SHORT ) pMF->xExt;
				*( (short* )( pBuf+12 )) = ( SHORT ) pMF->yExt;
				*( (short* )( pBuf+14 )) = ( USHORT ) 2540;

				if ( nBufSize && nBufSize == GetMetaFileBitsEx( pMF->hMF, nBufSize, pBuf+22 ) )
				{
					datatransfer::DataFlavor aFlavor(
                        ::rtl::OUString::createFromAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ),
						::rtl::OUString::createFromAscii( "Image WMF" ),
						getCppuType( ( const uno::Sequence< sal_Int8 >* ) 0 ) );

					aObjectInfo.Options.realloc( 2 );
					aObjectInfo.Options[0].Name = ::rtl::OUString::createFromAscii( "Icon" );
					aObjectInfo.Options[0].Value <<= aMetafile;
					aObjectInfo.Options[1].Name = ::rtl::OUString::createFromAscii( "IconFormat" );
					aObjectInfo.Options[1].Value <<= aFlavor;
				}

				GlobalUnlock( io.hMetaPict );
			}
		}
	}
	else
		throw ucb::CommandAbortedException();

#else
	throw lang::NoSupportException(); // TODO:
#endif

	OSL_ENSURE( aObjectInfo.Object.is(), "No object was created!\n" );
	if ( !aObjectInfo.Object.is() )
		throw uno::RuntimeException();

	return aObjectInfo;
}

//-------------------------------------------------------------------------
embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceInitFromClipboard(
				const uno::Reference< embed::XStorage >& xStorage,
				const ::rtl::OUString& sEntryName,
				const uno::Sequence< beans::PropertyValue >& aObjectArgs )
		throw ( lang::IllegalArgumentException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	embed::InsertedObjectInfo aObjectInfo;

#ifdef WNT

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntryName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	uno::Reference< embed::XEmbeddedObject > xResult(
					static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory ) ),
					uno::UNO_QUERY );

	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );

	if ( !xPersist.is() )
		throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects

	xPersist->setPersistentEntry( xStorage,
									sEntryName,
									embed::EntryInitModes::DEFAULT_INIT,
									uno::Sequence< beans::PropertyValue >(),
									aObjectArgs );

	aObjectInfo.Object = xResult;

	// TODO/LATER: in case of iconifie object the icon should be stored in aObjectInfo
#else
	throw lang::NoSupportException(); // TODO:
#endif

	OSL_ENSURE( aObjectInfo.Object.is(), "No object was created!\n" );
	if ( !aObjectInfo.Object.is() )
		throw uno::RuntimeException();

	return aObjectInfo;
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::getImplementationName()
	throw ( uno::RuntimeException )
{
	return impl_staticGetImplementationName();
}

//-------------------------------------------------------------------------
sal_Bool SAL_CALL MSOLEDialogObjectCreator::supportsService( const ::rtl::OUString& ServiceName )
	throw ( uno::RuntimeException )
{
	uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();

	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
    	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
        	return sal_True;

	return sal_False;
}

//-------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL MSOLEDialogObjectCreator::getSupportedServiceNames()
	throw ( uno::RuntimeException )
{
	return impl_staticGetSupportedServiceNames();
}

