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

#include "xformsapi.hxx"

#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/xforms/XFormsSupplier.hpp>
#include <com/sun/star/xforms/XDataTypeRepository.hpp>
#include <com/sun/star/xforms/XModel.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/xsd/DataTypeClass.hpp>

#include <unotools/processfactory.hxx>
#include <tools/debug.hxx>

#include <xmloff/xmltoken.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmltkmap.hxx>

using rtl::OUString;
using com::sun::star::uno::Reference;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::UNO_QUERY;
using com::sun::star::uno::UNO_QUERY_THROW;
using com::sun::star::beans::XPropertySet;
using com::sun::star::container::XNameAccess;
using com::sun::star::lang::XMultiServiceFactory;
using com::sun::star::xforms::XFormsSupplier;
using com::sun::star::xforms::XDataTypeRepository;
using com::sun::star::container::XNameContainer;
using utl::getProcessServiceFactory;
using com::sun::star::uno::makeAny;
using com::sun::star::uno::Any;
using com::sun::star::uno::Exception;

using namespace com::sun::star;
using namespace xmloff::token;

Reference<XPropertySet> lcl_createPropertySet( const OUString& rServiceName )
{
    Reference<XMultiServiceFactory> xFactory = getProcessServiceFactory();
    DBG_ASSERT( xFactory.is(), "can't get service factory" );

    Reference<XPropertySet> xModel( xFactory->createInstance( rServiceName ),
                                    UNO_QUERY_THROW );
    DBG_ASSERT( xModel.is(), "can't create model" );

    return xModel;
}

Reference<XPropertySet> lcl_createXFormsModel()
{
    return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Model" ) );
}

Reference<XPropertySet> lcl_createXFormsBinding()
{
    return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Binding" ) );
}

void lcl_addXFormsModel(
    const Reference<frame::XModel>& xDocument,
    const Reference<XPropertySet>& xModel )
{
    bool bSuccess = false;
    try
    {
        Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY );
        if( xSupplier.is() )
        {
            Reference<XNameContainer> xForms = xSupplier->getXForms();
            if( xForms.is() )
            {
                OUString sName;
                xModel->getPropertyValue( OUSTRING("ID")) >>= sName;
                xForms->insertByName( sName, makeAny( xModel ) );
                bSuccess = true;
            }
        }
    }
    catch( const Exception& )
    {
        ; // no success!
    }

    // TODO: implement proper error handling
    DBG_ASSERT( bSuccess, "can't import model" );
}

Reference<XPropertySet> lcl_findXFormsBindingOrSubmission(
    Reference<frame::XModel>& xDocument,
    const rtl::OUString& rBindingID,
    bool bBinding )
{
    // find binding by iterating over all models, and look for the
    // given binding ID

    Reference<XPropertySet> xRet;
    try
    {
        // get supplier
        Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY );
        if( xSupplier.is() )
        {
            // get XForms models
            Reference<XNameContainer> xForms = xSupplier->getXForms();
            if( xForms.is() )
            {
                // iterate over all models
                Sequence<OUString> aNames = xForms->getElementNames();
                const OUString* pNames = aNames.getConstArray();
                sal_Int32 nNames = aNames.getLength();
                for( sal_Int32 n = 0; (n < nNames) && !xRet.is(); n++ )
                {
                    Reference<xforms::XModel> xModel(
                        xForms->getByName( pNames[n] ), UNO_QUERY );
                    if( xModel.is() )
                    {
                        // ask model for bindings
                        Reference<XNameAccess> xBindings(
                            bBinding
                                ? xModel->getBindings()
                                : xModel->getSubmissions(),
                            UNO_QUERY_THROW );

                        // finally, ask binding for name
                        if( xBindings->hasByName( rBindingID ) )
                            xRet.set( xBindings->getByName( rBindingID ),
                                      UNO_QUERY );
                    }
                }
            }
        }
    }
    catch( const Exception& )
    {
        ; // no success!
    }

    // TODO: if (!xRet.is()) rImport.SetError(...);

    return xRet;
}

Reference<XPropertySet> lcl_findXFormsBinding(
    Reference<frame::XModel>& xDocument,
    const rtl::OUString& rBindingID )
{
    return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, true );
}

Reference<XPropertySet> lcl_findXFormsSubmission(
    Reference<frame::XModel>& xDocument,
    const rtl::OUString& rBindingID )
{
    return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, false );
}

void lcl_setValue( Reference<XPropertySet>& xPropertySet,
                   const OUString& rName,
                   const Any rAny )
{
    xPropertySet->setPropertyValue( rName, rAny );
}


Reference<XPropertySet> lcl_getXFormsModel( const Reference<frame::XModel>& xDoc )
{
    Reference<XPropertySet> xRet;
    try
    {
        Reference<XFormsSupplier> xSupplier( xDoc, UNO_QUERY );
        if( xSupplier.is() )
        {
            Reference<XNameContainer> xForms = xSupplier->getXForms();
            if( xForms.is() )
            {
                Sequence<OUString> aNames = xForms->getElementNames();
                if( aNames.getLength() > 0 )
                    xRet.set( xForms->getByName( aNames[0] ), UNO_QUERY );
            }
        }
    }
    catch( const Exception& )
    {
        ; // no success!
    }

    return xRet;
}

#define TOKEN_MAP_ENTRY(NAMESPACE,TOKEN) { XML_NAMESPACE_##NAMESPACE, xmloff::token::XML_##TOKEN, xmloff::token::XML_##TOKEN }
static SvXMLTokenMapEntry aTypes[] =
{
    TOKEN_MAP_ENTRY( XSD, STRING  ),
    TOKEN_MAP_ENTRY( XSD, DECIMAL ),
    TOKEN_MAP_ENTRY( XSD, DOUBLE ),
    TOKEN_MAP_ENTRY( XSD, FLOAT ),
    TOKEN_MAP_ENTRY( XSD, BOOLEAN ),
    TOKEN_MAP_ENTRY( XSD, ANYURI ),
    TOKEN_MAP_ENTRY( XSD, DATETIME_XSD ),
    TOKEN_MAP_ENTRY( XSD, DATE ),
    TOKEN_MAP_ENTRY( XSD, TIME ),
    TOKEN_MAP_ENTRY( XSD, YEAR ),
    TOKEN_MAP_ENTRY( XSD, MONTH ),
    TOKEN_MAP_ENTRY( XSD, DAY ),
    XML_TOKEN_MAP_END
};

sal_uInt16 lcl_getTypeClass(
    const Reference<XDataTypeRepository>&
    #ifdef DBG_UTIL
    xRepository
    #endif
    ,
    const SvXMLNamespaceMap& rNamespaceMap,
    const OUString& rXMLName )
{
    // translate name into token for local name
    OUString sLocalName;
    sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName);
    SvXMLTokenMap aMap( aTypes );
    sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName );

    sal_uInt16 nTypeClass = com::sun::star::xsd::DataTypeClass::STRING;
    if( mnToken != XML_TOK_UNKNOWN )
    {
        // we found an XSD name: then get the proper API name for it
        DBG_ASSERT( xRepository.is(), "can't find type without repository");
        switch( mnToken )
        {
        case XML_STRING:
            nTypeClass = com::sun::star::xsd::DataTypeClass::STRING;
            break;
        case XML_ANYURI:
            nTypeClass = com::sun::star::xsd::DataTypeClass::anyURI;
            break;
        case XML_DECIMAL:
            nTypeClass = com::sun::star::xsd::DataTypeClass::DECIMAL;
            break;
        case XML_DOUBLE:
            nTypeClass = com::sun::star::xsd::DataTypeClass::DOUBLE;
            break;
        case XML_FLOAT:
            nTypeClass = com::sun::star::xsd::DataTypeClass::FLOAT;
            break;
        case XML_BOOLEAN:
            nTypeClass = com::sun::star::xsd::DataTypeClass::BOOLEAN;
            break;
        case XML_DATETIME_XSD:
            nTypeClass = com::sun::star::xsd::DataTypeClass::DATETIME;
            break;
        case XML_DATE:
            nTypeClass = com::sun::star::xsd::DataTypeClass::DATE;
            break;
        case XML_TIME:
            nTypeClass = com::sun::star::xsd::DataTypeClass::TIME;
            break;
        case XML_YEAR:
            nTypeClass = com::sun::star::xsd::DataTypeClass::gYear;
            break;
        case XML_DAY:
            nTypeClass = com::sun::star::xsd::DataTypeClass::gDay;
            break;
        case XML_MONTH:
            nTypeClass = com::sun::star::xsd::DataTypeClass::gMonth;
            break;

            /* data types not yet supported:
            nTypeClass = com::sun::star::xsd::DataTypeClass::DURATION;
            nTypeClass = com::sun::star::xsd::DataTypeClass::gYearMonth;
            nTypeClass = com::sun::star::xsd::DataTypeClass::gMonthDay;
            nTypeClass = com::sun::star::xsd::DataTypeClass::hexBinary;
            nTypeClass = com::sun::star::xsd::DataTypeClass::base64Binary;
            nTypeClass = com::sun::star::xsd::DataTypeClass::QName;
            nTypeClass = com::sun::star::xsd::DataTypeClass::NOTATION;
            */
        }
    }

    return nTypeClass;
}


rtl::OUString lcl_getTypeName(
    const Reference<XDataTypeRepository>& xRepository,
    const SvXMLNamespaceMap& rNamespaceMap,
    const OUString& rXMLName )
{
    OUString sLocalName;
    sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName);
    SvXMLTokenMap aMap( aTypes );
    sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName );
    return ( mnToken == XML_TOK_UNKNOWN )
        ? rXMLName
        : lcl_getBasicTypeName( xRepository, rNamespaceMap, rXMLName );
}

rtl::OUString lcl_getBasicTypeName(
    const Reference<XDataTypeRepository>& xRepository,
    const SvXMLNamespaceMap& rNamespaceMap,
    const OUString& rXMLName )
{
    OUString sTypeName = rXMLName;
    try
    {
        sTypeName =
            xRepository->getBasicDataType(
                lcl_getTypeClass( xRepository, rNamespaceMap, rXMLName ) )
            ->getName();
    }
    catch( const Exception& )
    {
        DBG_ERROR( "exception during type creation" );
    }
    return sTypeName;
}
