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

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
#include <tools/debug.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/app.hxx>
#include <basic/basmgr.hxx>
#include <basic/sbmod.hxx>
#include <svx/svxerr.hxx>
#include <filter/msfilter/svxmsbas.hxx>
#include <msvbasic.hxx>
#include <filter/msfilter/msocximex.hxx>
#include <sot/storinfo.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
using namespace com::sun::star::beans;
using namespace com::sun::star::io;
using namespace com::sun::star::awt;
#include <comphelper/storagehelper.hxx>

#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/script/ModuleInfo.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>

using namespace com::sun::star::container;
using namespace com::sun::star::script;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star;

using rtl::OUString;

static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) ); 

int SvxImportMSVBasic::Import( const String& rStorageName,
                                const String &rSubStorageName,
                                sal_Bool bAsComment, sal_Bool bStripped )
{
    std::vector< String > codeNames;
    return Import(  rStorageName, rSubStorageName, codeNames, bAsComment, bStripped );
}

int SvxImportMSVBasic::Import( const String& rStorageName,
								const String &rSubStorageName,
								const std::vector< String >& codeNames,
								sal_Bool bAsComment, sal_Bool bStripped )
{
	int nRet = 0;
	if( bImport && ImportCode_Impl( rStorageName, rSubStorageName, codeNames,
									bAsComment, bStripped ))
		nRet |= 1;

    if (bImport)
        ImportForms_Impl(rStorageName, rSubStorageName);

	if( bCopy && CopyStorage_Impl( rStorageName, rSubStorageName ))
		nRet |= 2;

	return nRet;
}

bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
    const String& rSubStorageName)
{
    SvStorageRef xVBAStg(xRoot->OpenSotStorage(rStorageName,
        STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
    if (!xVBAStg.Is() || xVBAStg->GetError())
        return false;

    std::vector<String> aUserForms;
    SvStorageInfoList aContents;
    xVBAStg->FillInfoList(&aContents);
    for (sal_uInt16 nI = 0; nI < aContents.Count(); ++nI)
    {
          SvStorageInfo& rInfo = aContents.GetObject(nI);
          if (!rInfo.IsStream() && rInfo.GetName() != rSubStorageName)
              aUserForms.push_back(rInfo.GetName());
    }

    if (aUserForms.empty())
        return false;

    bool bRet = true;
    try
    {
        Reference<XMultiServiceFactory> xSF(comphelper::getProcessServiceFactory());

        Reference<XComponentContext> xContext;
        Reference<XPropertySet> xProps(xSF, UNO_QUERY);
        xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext;


        Reference<XLibraryContainer> xLibContainer = rDocSh.GetDialogContainer();
        DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );

        String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
        Reference<XNameContainer> xLib;
        if (xLibContainer.is())
        {
            if( !xLibContainer->hasByName(aLibName))
                xLibContainer->createLibrary(aLibName);

            Any aLibAny = xLibContainer->getByName( aLibName );
            aLibAny >>= xLib;
        }

        if(xLib.is())
        {
            typedef std::vector<String>::iterator myIter;
            myIter aEnd = aUserForms.end();
            for (myIter aIter = aUserForms.begin(); aIter != aEnd; ++aIter)
            {
                SvStorageRef xForm (xVBAStg->OpenSotStorage(*aIter,
                    STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));

                if (!xForm.Is() || xForm->GetError())
                    continue;

                SvStorageStreamRef xFrame = xForm->OpenSotStream(
                    String( RTL_CONSTASCII_USTRINGPARAM( "\3VBFrame" ) ),
                    STREAM_STD_READ | STREAM_NOCREATE);

                if (!xFrame.Is() || xFrame->GetError())
                    continue;

                SvStorageStreamRef xTypes = xForm->OpenSotStream(
                    String( 'f' ), STREAM_STD_READ | STREAM_NOCREATE);

                if (!xTypes.Is() || xTypes->GetError())
                    continue;

                //<UserForm Name=""><VBFrame></VBFrame>"
                String sData;
                String sLine;
                while(xFrame->ReadByteStringLine(sLine, RTL_TEXTENCODING_MS_1252))
                {
                    sData += sLine;
                    sData += '\n';
                }
                sData.ConvertLineEnd();

                Reference<container::XNameContainer> xDialog(
                    xSF->createInstance(
                       OUString(RTL_CONSTASCII_USTRINGPARAM(
                           "com.sun.star.awt.UnoControlDialogModel"))), uno::UNO_QUERY);

                OCX_UserForm aForm(xVBAStg, *aIter, *aIter, xDialog, xSF );
                aForm.pDocSh = &rDocSh;
                sal_Bool bOk = aForm.Read(xTypes);
                DBG_ASSERT(bOk, "Had unexpected content, not risking this module");
                if (bOk)
                    aForm.Import(xLib);
            }
        }
    }
    catch(...)
    {
        DBG_ERRORFILE( "SvxImportMSVBasic::ImportForms_Impl - any exception caught" );
        //bRet = false;
    }
    return bRet;
}


sal_Bool SvxImportMSVBasic::CopyStorage_Impl( const String& rStorageName,
									 	const String& rSubStorageName)
{
	sal_Bool bValidStg = sal_False;
	{
		SvStorageRef xVBAStg( xRoot->OpenSotStorage( rStorageName,
									STREAM_READWRITE | STREAM_NOCREATE |
									STREAM_SHARE_DENYALL ));
		if( xVBAStg.Is() && !xVBAStg->GetError() )
		{
			SvStorageRef xVBASubStg( xVBAStg->OpenSotStorage( rSubStorageName,
								 	STREAM_READWRITE | STREAM_NOCREATE |
									STREAM_SHARE_DENYALL ));
			if( xVBASubStg.Is() && !xVBASubStg->GetError() )
			{
                // then we will copy these storages into the (temporary) storage of the document
				bValidStg = sal_True;
			}
		}
	}

	if( bValidStg )
	{
		String aDstStgName( GetMSBasicStorageName() );
        SotStorageRef xDst = SotStorage::OpenOLEStorage( rDocSh.GetStorage(), aDstStgName, STREAM_READWRITE | STREAM_TRUNC );
        SotStorageRef xSrc = xRoot->OpenSotStorage( rStorageName, STREAM_STD_READ );

        // TODO/LATER: should we commit the storage?
        xSrc->CopyTo( xDst );
        xDst->Commit();
        ErrCode nError = xDst->GetError();
        if ( nError == ERRCODE_NONE )
            nError = xSrc->GetError();
        if ( nError != ERRCODE_NONE )
            xRoot->SetError( nError );
        else
            bValidStg = sal_True;
	}

	return bValidStg;
}

sal_Bool SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
										const String &rSubStorageName,
										const std::vector< String >& codeNames,
										sal_Bool bAsComment, sal_Bool bStripped )
{
	sal_Bool bRet = sal_False;
	VBA_Impl aVBA( *xRoot, bAsComment );
	if( aVBA.Open(rStorageName,rSubStorageName) )
	{
        Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
		DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
		
        /*  Set library container to VBA compatibility mode. This will create
            the VBA Globals object and store it in the Basic manager of the
            document. */
        if( !bAsComment ) try
        {
            Reference< vba::XVBACompatibility >( xLibContainer, UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True );
        }
        catch( Exception& )
        {
        }

        sal_uInt16 nStreamCount = aVBA.GetNoStreams();
		Reference<XNameContainer> xLib;
        String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
        if( xLibContainer.is() && nStreamCount )
        {
		    if( !xLibContainer->hasByName( aLibName ) )
			    xLibContainer->createLibrary( aLibName );

            Any aLibAny = xLibContainer->getByName( aLibName );
		    aLibAny >>= xLib;
        }
		if( xLib.is() )
		{
            Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
            Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
			if ( !bAsComment )
            {
                Reference< XMultiServiceFactory> xSF(rDocSh.GetModel(), UNO_QUERY);
                if ( xSF.is() )
                {
                    try
                    {
                        xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), UNO_QUERY );
                    }
                    catch( Exception& ) { }
                }
            }
            typedef  std::hash_map< rtl::OUString, uno::Any, ::rtl::OUStringHash,
::std::equal_to< ::rtl::OUString > > NameModuleDataHash;
            typedef  std::hash_map< rtl::OUString, script::ModuleInfo, ::rtl::OUStringHash,
::std::equal_to< ::rtl::OUString > > NameModuleInfoHash;

            NameModuleDataHash moduleData;
            NameModuleInfoHash moduleInfos;

			for( sal_uInt16 i=0; i<nStreamCount;i++)
			{
				StringArray aDecompressed = aVBA.Decompress(i);
#if 0
/*  DR 2005-08-11 #124850# Do not filter special characters from module name.
    Just put the original module name and let the Basic interpreter deal with
    it. Needed for roundtrip...
 */
				ByteString sByteBasic(aVBA.GetStreamName(i),
					RTL_TEXTENCODING_ASCII_US,
						(RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE|
						RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
						RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |
						RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE)
				);

				const String sBasicModule(sByteBasic,
					RTL_TEXTENCODING_ASCII_US);
#else
                const String &sBasicModule = aVBA.GetStreamName( i);
#endif
                /* #117718# expose information regarding type of Module
                * Class, Form or plain 'ould VBA module with a REM statment
                * at the top of the module. Mapping of Module Name
                * to type is performed in  VBA_Impl::Open() method,
                * ( msvbasic.cxx ) by examining the PROJECT stream.
                */

                // using name from aVBA.GetStreamName
                // because the encoding of the same returned
                // is the same as the encoding for the names
                // that are keys in the map used by GetModuleType method
                const String &sOrigVBAModName = aVBA.GetStreamName( i );
                ModType mType = aVBA.GetModuleType( sOrigVBAModName );

                rtl::OUString sClassRem( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=" ) );

                rtl::OUString modeTypeComment;

                switch( mType )
                {
                    case ModuleType::CLASS:
                        modeTypeComment = sClassRem +
                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAClassModule\n" ) );
                        break;
                    case ModuleType::FORM:
                        modeTypeComment = sClassRem +
                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAFormModule\n" ) );
                        break;
                    case ModuleType::DOCUMENT:
                        modeTypeComment = sClassRem +
                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBADocumentModule\n" ) );
                        break;
                    case ModuleType::NORMAL:
                        modeTypeComment = sClassRem +
                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAModule\n" ) );
                        break;
                    case ModuleType::UNKNOWN:
                        modeTypeComment = sClassRem +
                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAUnknown\n" ) );
                        break;
                    default:
                        DBG_ERRORFILE( "SvxImportMSVBasic::ImportCode_Impl - unknown module type" );
                        break;
                }
				static ::rtl::OUString sClassOption( RTL_CONSTASCII_USTRINGPARAM( "Option ClassModule\n" ) ); 
				if ( !bAsComment )
				{
					modeTypeComment += sVBAOption;
					if ( mType == ModuleType::CLASS )
						modeTypeComment += sClassOption;
				}

				String sModule(sBasicModule); //#i52606# no need to split Macros in 64KB blocks any more!
				String sTemp;
				if (bAsComment)
				{
					sTemp+=String(RTL_CONSTASCII_USTRINGPARAM( "Sub " ));
					String sMunge(sModule);
					//Streams can have spaces in them, but modulenames
					//cannot !
					sMunge.SearchAndReplaceAll(' ','_');

					sTemp += sMunge;
					sTemp.AppendAscii("\n");
				};
	            ::rtl::OUString aSource(sTemp);

				for(sal_uLong j=0;j<aDecompressed.GetSize();j++)
				{
					if (bStripped)
					{
                        String *pStr = aDecompressed.Get(j);
                        bool bMac = true;
                        xub_StrLen nBegin = pStr->Search('\x0D');
                        if ((STRING_NOTFOUND != nBegin) && (pStr->Len() > 1) && (pStr->GetChar(nBegin+1) == '\x0A'))
                            bMac = false;

                        const char cLineEnd = bMac ? '\x0D' : '\x0A';
                        const String sAttribute(String::CreateFromAscii(
                            bAsComment ? "Rem Attribute" : "Attribute"));
						nBegin = 0;
						while (STRING_NOTFOUND != (nBegin =	pStr->Search(sAttribute, nBegin)))
						{
                            if ((nBegin) && pStr->GetChar(nBegin-1) != cLineEnd)
							{
                                // npower #i63766# Need to skip instances of Attribute
								// that are NOT Attribute statements
								nBegin = nBegin + sAttribute.Len();
                                continue;
							}
							xub_StrLen nEnd = pStr->Search(cLineEnd ,nBegin);
                            // DR #i26521# catch STRING_NOTFOUND, will loop endless otherwise
                            if( nEnd == STRING_NOTFOUND )
                                pStr->Erase();
                            else
                                pStr->Erase(nBegin, (nEnd-nBegin)+1);
						}
					}
					if( aDecompressed.Get(j)->Len() )
					{
			            aSource+=::rtl::OUString( *aDecompressed.Get(j) );
					}

				}
				if (bAsComment)
				{
						aSource += rtl::OUString::createFromAscii("\nEnd Sub");
				}
				::rtl::OUString aModName( sModule );
				aSource = modeTypeComment + aSource;

				Any aSourceAny;
                OSL_TRACE("erm %d", mType );
                    aSourceAny <<= aSource;
                if (  !bAsComment )
                {
                    OSL_TRACE("vba processing  %d", mType );
                    script::ModuleInfo sModuleInfo;
                    sModuleInfo.ModuleType = mType;
                    moduleInfos[ aModName ] = sModuleInfo;
                }
 				moduleData[ aModName ] = aSourceAny;
            }
            // Hack for missing codenames ( only know to happen in excel but... )
            // only makes sense to do this if we are importing non-commented basic
            if ( !bAsComment )
            {
                for ( std::vector< String >::const_iterator it =  codeNames.begin(); it != codeNames.end(); ++it )
                {
                    script::ModuleInfo sModuleInfo;
                    sModuleInfo.ModuleType = ModuleType::DOCUMENT;
                    moduleInfos[ *it ] = sModuleInfo;
                    moduleData[ *it ] = uno::makeAny( sVBAOption );
                }
            }
            NameModuleDataHash::iterator it_end = moduleData.end();
            for ( NameModuleDataHash::iterator it = moduleData.begin(); it != it_end; ++it )
            {
                NameModuleInfoHash::iterator it_info = moduleInfos.find( it->first );
                if ( it_info != moduleInfos.end() )
                {
                    ModuleInfo& sModuleInfo = it_info->second;
                    if ( sModuleInfo.ModuleType == ModuleType::FORM )
                        // hack, the module ( imo document basic should...
                        // know the XModel... ) but it doesn't
                        sModuleInfo.ModuleObject.set( rDocSh.GetModel(), UNO_QUERY );
                    //  document modules, we should be able to access
			        //  the api objects at this time
                    else if ( sModuleInfo.ModuleType == ModuleType::DOCUMENT )
			        {
                        if ( xVBACodeNamedObjectAccess.is() )
                        {
                            try
                            {
                                sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( it->first ), uno::UNO_QUERY );    
                                OSL_TRACE("** Straight up creation of Module");
                            }
                            catch(uno::Exception& e)
                            {
    						    OSL_TRACE("Failed to get documument object for %s", rtl::OUStringToOString( it->first, RTL_TEXTENCODING_UTF8 ).getStr() );
    					    }
    				    }
    			    }
                    xVBAModuleInfo->insertModuleInfo( it->first, sModuleInfo );
                }
                     
                if( xLib->hasByName( it->first ) )
                    xLib->replaceByName( it->first, it->second );
                else
                    xLib->insertByName( it->first, it->second );
			}
			bRet = true;
		}
	}
	return bRet;
}

/* vi:set tabstop=4 shiftwidth=4 expandtab: */
