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

#include "fileopendialog.hxx"
#include <sal/types.h>
#include "pppoptimizertoken.hxx"
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
#include <com/sun/star/ui/dialogs/XFilePreview.hpp>
#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
#ifndef _COM_SUN_STAR_UI_DIALOGS_XFOLDERPICKER_HDL_
#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
#endif
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XContainerQuery.hpp>
#include <com/sun/star/view/XControlAccess.hpp>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>

#include <rtl/ustrbuf.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;
using namespace ::com::sun::star::ui::dialogs;

using ::com::sun::star::awt::XWindow;
using ::rtl::OUString;

namespace
{
    inline bool lcl_isSystemDialog(
        const Reference< XInterface > &rxIfce )
    {
        Reference< XServiceInfo > xInfo( rxIfce, UNO_QUERY );
        if ( !xInfo.is() )
            return false;

        return xInfo->supportsService(
            OUString( RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.ui.dialogs.SystemFilePicker" ) ) );
    }
}

FileOpenDialog::FileOpenDialog(
    const Reference< XComponentContext >& rxContext,
    const Reference< XWindow > &rxParent )
    : mxContext( rxContext )
{
    mxFilePicker = Reference < XFilePicker >(
        mxContext->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.ui.dialogs.FilePicker" ) ),
                    rxContext ), UNO_QUERY_THROW );
    Reference< XInitialization > xInit( mxFilePicker, UNO_QUERY_THROW );
    bool bIsSystemDlg = lcl_isSystemDialog( mxFilePicker );
    Sequence< Any > aInitPropSeq( bIsSystemDlg ? 1 : 2 );
    if ( bIsSystemDlg )
    {
        aInitPropSeq[0] <<= TemplateDescription::FILESAVE_AUTOEXTENSION;
        xInit->initialize( aInitPropSeq );
    }
    else
    {
        aInitPropSeq[ 0 ] <<= NamedValue(
            OUString(RTL_CONSTASCII_USTRINGPARAM("TemplateDescription")),
            makeAny( (sal_Int16)TemplateDescription::FILESAVE_AUTOEXTENSION));
        aInitPropSeq[ 1 ] <<= NamedValue(
            OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")),
            makeAny( rxParent ));
        xInit->initialize( aInitPropSeq );
    }

	mxFilePicker->setMultiSelectionMode( sal_False );

	Reference< XFilePickerControlAccess > xAccess( mxFilePicker, UNO_QUERY );
	if ( xAccess.is() )
	{
		Any aValue( static_cast< sal_Bool >( sal_True ) );
		try
		{
			xAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
		}
		catch( com::sun::star::uno::Exception& )
		{}
	}

	// collecting a list of impress filters
	Reference< XNameAccess > xFilters( mxContext->getServiceManager()->createInstanceWithContext(
		OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" ) ), rxContext ), UNO_QUERY_THROW );
	Sequence< OUString > aFilterList( xFilters->getElementNames() );
	for ( int i = 0; i < aFilterList.getLength(); i++ )
	{
		try
		{
			Sequence< PropertyValue > aFilterProperties;
			if ( xFilters->getByName( aFilterList[ i ] ) >>= aFilterProperties )
			{
				FilterEntry aFilterEntry;
				sal_Bool bImpressFilter = sal_False;
				for ( int j = 0; j < aFilterProperties.getLength(); j++ )
				{
					PropertyValue& rProperty( aFilterProperties[ j ] );
					switch( TKGet( rProperty.Name ) )
					{
						case TK_DocumentService :
						{
							rtl::OUString sDocumentService;
							rProperty.Value >>= sDocumentService;
							if ( sDocumentService == OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) )
								bImpressFilter = sal_True;
							else
								j = aFilterProperties.getLength();
						}
						break;
						case TK_Name :		rProperty.Value >>= aFilterEntry.maName; break;
						case TK_UIName :	rProperty.Value >>= aFilterEntry.maUIName; break;
						case TK_Type :		rProperty.Value >>= aFilterEntry.maType; break;
						case TK_Flags :		rProperty.Value >>= aFilterEntry.maFlags; break;
						default : break;
					}
				}
				if ( bImpressFilter && ( ( aFilterEntry.maFlags & 3 ) == 3 ) )
				{
					aFilterEntryList.push_back( aFilterEntry );
				}
			}
		}
		catch( Exception& )
		{
		}
	}

	Reference< XNameAccess > xTypes( mxContext->getServiceManager()->createInstanceWithContext(
		OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" ) ), rxContext ), UNO_QUERY_THROW );
	Sequence< OUString > aTypeList( xFilters->getElementNames() );

//	mxFilePicker->setDefaultName( );

    const char filter[] = "*.";
    // the filter title must be formed in the same way it is currently done
    // in the internal implementation: "UIName (.<extension>)"
    rtl::OUStringBuffer aUIName;
    // the filter must be in the form "*.<extension>"
    rtl::OUStringBuffer aFilter;
    rtl::OUString aExtension;
	Reference< XFilterManager > xFilterManager( mxFilePicker, UNO_QUERY_THROW );
	std::vector< FilterEntry >::iterator aIter( aFilterEntryList.begin() );
	while( aIter != aFilterEntryList.end() )
	{
		Sequence< PropertyValue > aTypeProperties;
		try
		{
			if ( xTypes->getByName( aIter->maType ) >>= aTypeProperties )
			{
				Sequence< OUString > aExtensions;
				for ( int i = 0; i < aTypeProperties.getLength(); i++ )
				{
					switch( TKGet( aTypeProperties[ i ].Name ) )
					{
						case TK_Extensions : aTypeProperties[ i ].Value >>= aExtensions; break;
						default: break;
					}
				}
				if ( aExtensions.getLength() )
				{
                    aExtension = aExtensions[0];
                    // form the title: "<UIName> (.<extension)"
                    aUIName.append( aIter->maUIName );
                    aUIName.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (." ));
                    aUIName.append( aExtension );
                    aUIName.append( sal_Unicode( ')' ) );
                    // form the filter: "(*.<extension>)"
                    aFilter.appendAscii( RTL_CONSTASCII_STRINGPARAM( filter ) );
                    aFilter.append( aExtensions[0] );

                    xFilterManager->appendFilter( aUIName.makeStringAndClear(),
                                                  aFilter.makeStringAndClear() );
					if ( aIter->maFlags & 0x100 )
						xFilterManager->setCurrentFilter( aIter->maUIName );
				}
			}
		}
		catch ( Exception& )
		{
		}
		aIter++;
	}
}
FileOpenDialog::~FileOpenDialog()
{
}
sal_Int16 FileOpenDialog::execute()
{
	return mxFilePicker->execute();
}
void FileOpenDialog::setDefaultName( const rtl::OUString& rDefaultName )
{
	mxFilePicker->setDefaultName( rDefaultName );
}
::rtl::OUString	FileOpenDialog::getURL() const
{
	Sequence< OUString > aFileSeq( mxFilePicker->getFiles() );
	return aFileSeq.getLength() ? aFileSeq[ 0 ] : OUString();
};
::rtl::OUString	FileOpenDialog::getFilterName() const
{
	rtl::OUString aFilterName;
	Reference< XFilterManager > xFilterManager( mxFilePicker, UNO_QUERY_THROW );
	rtl::OUString aUIName( xFilterManager->getCurrentFilter() );
	std::vector< FilterEntry >::const_iterator aIter( aFilterEntryList.begin() );
	while( aIter != aFilterEntryList.end() )
	{
		if ( aIter->maUIName == aUIName )
		{
			aFilterName = aIter->maName;
			break;
		}
		aIter++;
	}
	return aFilterName;
};
