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

#ifndef SVX_SOURCE_FORM_FMDOCUMENTCLASSIFICATION_HXX
#include "fmdocumentclassification.hxx"
#endif
#include "svx/dbtoolsclient.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/xforms/XFormsSupplier.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/frame/XModule.hpp>
/** === end UNO includes === **/

#include <tools/diagnose_ex.h>

//........................................................................
namespace svxform
{
//........................................................................

    namespace
    {
        using ::com::sun::star::uno::Reference;
        using ::com::sun::star::uno::XInterface;
        using ::com::sun::star::container::XChild;
        using ::com::sun::star::frame::XModel;
        using ::com::sun::star::uno::UNO_QUERY;
        using ::com::sun::star::frame::XModule;

        //....................................................................
        template< class TYPE >
        Reference< TYPE > getTypedModelNode( const Reference< XInterface >& _rxModelNode )
        {
	        Reference< TYPE > xTypedNode( _rxModelNode, UNO_QUERY );
	        if ( xTypedNode.is() )
		        return xTypedNode;
	        else
	        {
		        Reference< XChild > xChild( _rxModelNode, UNO_QUERY );
		        if ( xChild.is() )
			        return getTypedModelNode< TYPE >( xChild->getParent() );
		        else
			        return Reference< TYPE >();
	        }
        }

    	//....................................................................
        Reference< XModel > getDocument( const Reference< XInterface >& _rxModelNode )
        {
            return getTypedModelNode< XModel >( _rxModelNode );
        }
    }

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::xforms;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::sdbc;

    //====================================================================
    //====================================================================
    namespace
    {
        //----------------------------------------------------------------
        struct ModuleInfo
        {
            const sal_Char* pAsciiModuleOrServiceName;
            DocumentType    eType;
        };

        //----------------------------------------------------------------
        const ModuleInfo* lcl_getModuleInfo()
        {
            static const ModuleInfo aModuleInfo[] =
            {
                { "com.sun.star.text.TextDocument", eTextDocument },
                { "com.sun.star.text.WebDocument", eWebDocument },
                { "com.sun.star.sheet.SpreadsheetDocument", eSpreadsheetDocument },
                { "com.sun.star.drawing.DrawingDocument", eDrawingDocument },
                { "com.sun.star.presentation.PresentationDocument", ePresentationDocument },
                { "com.sun.star.xforms.XMLFormDocument", eEnhancedForm },
                { "com.sun.star.sdb.FormDesign", eDatabaseForm },
                { "com.sun.star.sdb.TextReportDesign", eDatabaseReport },
                { "com.sun.star.text.GlobalDocument", eTextDocument },
                { NULL, eUnknownDocumentType }
            };
            return aModuleInfo;
        }
    }

	//====================================================================
	//= DocumentClassification
	//====================================================================
	//--------------------------------------------------------------------
    DocumentType DocumentClassification::classifyDocument( const Reference< XModel >& _rxDocumentModel ) SAL_THROW(())
    {
        DocumentType eType( eUnknownDocumentType );

        OSL_ENSURE( _rxDocumentModel.is(), "DocumentClassification::classifyDocument: invalid document!" );
        if ( !_rxDocumentModel.is() )
            return eType;

        try
        {
            // first, check whether the document has a ModuleIdentifier which we know
            ::rtl::OUString sModuleIdentifier;
            Reference< XModule > xModule( _rxDocumentModel, UNO_QUERY );
            if ( xModule.is() )
                eType = getDocumentTypeForModuleIdentifier( xModule->getIdentifier() );
            if ( eType != eUnknownDocumentType )
                return eType;

            // second, check whether it supports one of the services we know
            Reference< XServiceInfo > xSI( _rxDocumentModel, UNO_QUERY_THROW );
            const ModuleInfo* pModuleInfo = lcl_getModuleInfo();
            while ( pModuleInfo->pAsciiModuleOrServiceName )
            {
                if ( xSI->supportsService( ::rtl::OUString::createFromAscii( pModuleInfo->pAsciiModuleOrServiceName ) ) )
                    return pModuleInfo->eType;
                ++pModuleInfo;
            }

            // last: uhm, there is no last resort
            OSL_ENSURE( false, "DocumentClassification::classifyDocument: unknown document!" );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        return eType;
    }

	//--------------------------------------------------------------------
    DocumentType DocumentClassification::classifyHostDocument( const Reference< XInterface >& _rxFormComponent ) SAL_THROW(())
    {
        DocumentType eType( eUnknownDocumentType );

        try
        {
            Reference< XModel > xDocument( getDocument( _rxFormComponent.get() ) );
            if ( !xDocument.is() )
                return eUnknownDocumentType;
            eType = classifyDocument( xDocument );
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "DocumentClassification::classifyHostDocument: caught an exception!" );
        }

        return eType;
    }

	//--------------------------------------------------------------------
    DocumentType DocumentClassification::getDocumentTypeForModuleIdentifier( const ::rtl::OUString& _rModuleIdentifier )
    {
        const ModuleInfo* pModuleInfo = lcl_getModuleInfo();
        while ( pModuleInfo->pAsciiModuleOrServiceName )
        {
            if ( _rModuleIdentifier.equalsAscii( pModuleInfo->pAsciiModuleOrServiceName ) )
                return pModuleInfo->eType;
            ++pModuleInfo;
        }
        return eUnknownDocumentType;
    }

	//--------------------------------------------------------------------
    ::rtl::OUString DocumentClassification::getModuleIdentifierForDocumentType( DocumentType _eType )
    {
        const ModuleInfo* pModuleInfo = lcl_getModuleInfo();
        while ( pModuleInfo->pAsciiModuleOrServiceName )
        {
            if ( pModuleInfo->eType == _eType )
                return ::rtl::OUString::createFromAscii( pModuleInfo->pAsciiModuleOrServiceName );
            ++pModuleInfo;
        }
        return ::rtl::OUString();
    }

//........................................................................
} // namespace svxform
//........................................................................

