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

#include <stdio.h>
#include <rtl/memory.h>
#include "osl/file.h"

#include <rtl/ustrbuf.hxx>

#include <xmlscript/xmldlg_imexp.hxx>
#include <xmlscript/xml_helper.hxx>

#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/implbase2.hxx>

#include <comphelper/processfactory.hxx>
#include <comphelper/regpathhelper.hxx>

#include <tools/debug.hxx>
#include <vcl/svapp.hxx>

#include <com/sun/star/io/XActiveDataSource.hpp>

#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>

#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/registry/XImplementationRegistration.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>

#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/awt/XDialog.hpp>

#include <com/sun/star/container/XNameContainer.hpp>


using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;




Reference< XComponentContext > createInitialComponentContext(
    OUString const & inst_dir )
{
    Reference< XComponentContext > xContext;

	try
	{
        OUString file_url;
        oslFileError rc = osl_getFileURLFromSystemPath(
            inst_dir.pData, &file_url.pData );
        OSL_ASSERT( osl_File_E_None == rc );

        ::rtl::OUString unorc = file_url + OUString(
            RTL_CONSTASCII_USTRINGPARAM("/program/" SAL_CONFIGFILE("uno")) );

        return defaultBootstrap_InitialComponentContext( unorc );
    }

	catch( Exception& rExc )
	{
		OString aStr( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
		OSL_ENSURE( 0, aStr.getStr() );
	}

	return xContext;
}


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

Reference< container::XNameContainer > importFile(
	char const * fname,
    Reference< XComponentContext > const & xContext )
{
	// create the input stream
	FILE *f = ::fopen( fname, "rb" );
	if (f)
	{
		::fseek( f, 0 ,SEEK_END );
		int nLength = ::ftell( f );
		::fseek( f, 0, SEEK_SET );

		ByteSequence bytes( nLength );
		::fread( bytes.getArray(), nLength, 1, f );
		::fclose( f );

		Reference< container::XNameContainer > xModel( xContext->getServiceManager()->createInstanceWithContext(
			OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ), xContext ), UNO_QUERY );
		::xmlscript::importDialogModel( ::xmlscript::createInputStream( bytes ), xModel, xContext );

		return xModel;
	}
	else
	{
		throw Exception( OUString( RTL_CONSTASCII_USTRINGPARAM("### Cannot read file!") ),
						 Reference< XInterface >() );
	}
}

void exportToFile(
	char const * fname,
	Reference< container::XNameContainer > const & xModel,
    Reference< XComponentContext > const & xContext )
{
	Reference< io::XInputStreamProvider > xProvider( ::xmlscript::exportDialogModel( xModel, xContext ) );
	Reference< io::XInputStream > xStream( xProvider->createInputStream() );

	Sequence< sal_Int8 > bytes;
	sal_Int32 nRead = xStream->readBytes( bytes, xStream->available() );
	for (;;)
	{
		Sequence< sal_Int8 > readBytes;
		nRead = xStream->readBytes( readBytes, 1024 );
		if (! nRead)
			break;
		OSL_ASSERT( readBytes.getLength() >= nRead );

		sal_Int32 nPos = bytes.getLength();
		bytes.realloc( nPos + nRead );
		::rtl_copyMemory( bytes.getArray() + nPos, readBytes.getConstArray(), (sal_uInt32)nRead );
	}

	FILE * f = ::fopen( fname, "w" );
	::fwrite( bytes.getConstArray(), 1, bytes.getLength(), f );
	::fflush( f );
	::fclose( f );
}



class MyApp : public Application
{
public:
    void Main();
};

MyApp aMyApp;

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

void MyApp::Main()
{
	if (GetCommandLineParamCount() < 2)
	{
		OSL_ENSURE( 0, "usage: imexp inst_dir inputfile [outputfile]\n" );
		return;
	}

    Reference< XComponentContext > xContext(
        createInitialComponentContext( OUString( GetCommandLineParam( 0 ) ) ) );
	Reference< lang::XMultiServiceFactory > xMSF(
        xContext->getServiceManager(), UNO_QUERY );

	try
	{
		::comphelper::setProcessServiceFactory( xMSF );

		Reference< awt::XToolkit> xToolkit( xMSF->createInstance(
			OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.ExtToolkit" ) ) ), UNO_QUERY );

		// import dialogs
		OString aParam1( OUStringToOString(
                             OUString( GetCommandLineParam( 1 ) ),
                             RTL_TEXTENCODING_ASCII_US ) );
		Reference< container::XNameContainer > xModel(
            importFile( aParam1.getStr(), xContext ) );
		OSL_ASSERT( xModel.is() );

		Reference< awt::XControl > xDlg( xMSF->createInstance(
			OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialog" ) ) ), UNO_QUERY );
		xDlg->setModel( Reference< awt::XControlModel >::query( xModel ) );
		xDlg->createPeer( xToolkit, 0 );
		Reference< awt::XDialog > xD( xDlg, UNO_QUERY );
		xD->execute();

		if (GetCommandLineParamCount() == 3)
		{
			// write modified dialogs
			OString aParam2( OUStringToOString(
                                 OUString( GetCommandLineParam( 2 ) ), RTL_TEXTENCODING_ASCII_US ) );
			exportToFile( aParam2.getStr(), xModel, xContext );
		}
	}
	catch (xml::sax::SAXException & rExc)
	{
		OString aStr( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
		uno::Exception exc;
		if (rExc.WrappedException >>= exc)
		{
			aStr += OString( " >>> " );
			aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US );
		}
		OSL_ENSURE( 0, aStr.getStr() );
	}
	catch (uno::Exception & rExc)
	{
		OString aStr( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
		OSL_ENSURE( 0, aStr.getStr() );
	}

    Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
    if (xComp.is())
    {
        xComp->dispose();
    }
}
