/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "precompiled_xmloff.hxx"

#include "property_description.hxx"
#include "forms/form_handler_factory.hxx"
#include "strings.hxx"
#include "xmloff/xmltoken.hxx"
#include "xmloff/xmlnmspe.hxx"

#include <tools/diagnose_ex.h>
#include <tools/debug.hxx>

#include <hash_map>

//......................................................................................................................
namespace xmloff { namespace metadata
{
//......................................................................................................................

    using namespace ::xmloff::token;

#define FORM_SINGLE_PROPERTY( id, att ) \
    PropertyDescription( PROPERTY_##id, XML_NAMESPACE_FORM, att, &FormHandlerFactory::getFormPropertyHandler, PID_##id, NO_GROUP )

    //==================================================================================================================
	//= property meta data
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    namespace
    {
        const PropertyDescription* lcl_getPropertyMetaData()
        {
            static const PropertyDescription s_propertyMetaData[] =
            {
                FORM_SINGLE_PROPERTY( DATE_MIN,        XML_MIN_VALUE        ),
                FORM_SINGLE_PROPERTY( DATE_MAX,        XML_MAX_VALUE        ),
                FORM_SINGLE_PROPERTY( DEFAULT_DATE,    XML_VALUE            ),
                FORM_SINGLE_PROPERTY( DATE,            XML_CURRENT_VALUE    ),
                FORM_SINGLE_PROPERTY( TIME_MIN,        XML_MIN_VALUE        ),
                FORM_SINGLE_PROPERTY( TIME_MAX,        XML_MAX_VALUE        ),
                FORM_SINGLE_PROPERTY( DEFAULT_TIME,    XML_VALUE            ),
                FORM_SINGLE_PROPERTY( TIME,            XML_CURRENT_VALUE    ),

                PropertyDescription()
            };
            return s_propertyMetaData;
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    namespace
    {
        // TODO: instead of having all of the below static, it should be some per-instance data. This way, the
        // approach used here would scale much better.
        // That is, if you have multiple "meta data instances", which manage a small, but closed set of properties,
        // then looking looking through those multiple instances would probably be faster than searching within
        // one big instance, since in this case, every instance can quickly decide whether it is responsible
        // for some attribute or property, and otherwise delegate to the next instance.

	    //..............................................................................................................
        typedef ::std::hash_map< ::rtl::OUString, const PropertyDescription*, ::rtl::OUStringHash > DescriptionsByName;

	    //..............................................................................................................
        const DescriptionsByName& lcl_getPropertyDescriptions()
        {
            DBG_TESTSOLARMUTEX();
            static DescriptionsByName s_propertyDescriptionsByName;
            if ( s_propertyDescriptionsByName.empty() )
            {
                const PropertyDescription* desc = lcl_getPropertyMetaData();
                while ( desc->propertyName.getLength() != 0 )
                {
                    s_propertyDescriptionsByName[ desc->propertyName ] = desc;
                    ++desc;
                }
            }
            return s_propertyDescriptionsByName;
        }

        //..............................................................................................................
        typedef ::std::map< PropertyGroup, PropertyDescriptionList > IndexedPropertyGroups;

        //..............................................................................................................
        const IndexedPropertyGroups& lcl_getIndexedPropertyGroups()
        {
            DBG_TESTSOLARMUTEX();
            static IndexedPropertyGroups s_indexedPropertyGroups;
            if ( s_indexedPropertyGroups.empty() )
            {
                const PropertyDescription* desc = lcl_getPropertyMetaData();
                while ( desc->propertyName.getLength() != 0 )
                {
                    if ( desc->propertyGroup != NO_GROUP )
                        s_indexedPropertyGroups[ desc->propertyGroup ].push_back( desc );
                    ++desc;
                }
            }
            return s_indexedPropertyGroups;
        }

        //..............................................................................................................
        typedef ::std::hash_map< ::rtl::OUString, XMLTokenEnum, ::rtl::OUStringHash > ReverseTokenLookup;

        //..............................................................................................................
        const ReverseTokenLookup& getReverseTokenLookup()
        {
            DBG_TESTSOLARMUTEX();
            static ReverseTokenLookup s_reverseTokenLookup;
            if ( s_reverseTokenLookup.empty() )
            {
                const PropertyDescription* desc = lcl_getPropertyMetaData();
                while ( desc->propertyName.getLength() != 0 )
                {
                    s_reverseTokenLookup[ token::GetXMLToken( desc->attribute.attributeToken ) ] = desc->attribute.attributeToken;
                    ++desc;
                }
            }
            return s_reverseTokenLookup;
        }

        //..............................................................................................................
        struct AttributeHash : public ::std::unary_function< AttributeDescription, size_t >
        {
            size_t operator()( const AttributeDescription& i_attribute ) const
            {
                return size_t( i_attribute.attributeToken * 100 ) + size_t( i_attribute.namespacePrefix );
            }
        };

        //..............................................................................................................
        typedef ::std::hash_multimap< AttributeDescription, PropertyGroup, AttributeHash > AttributeGroups;

        //..............................................................................................................
        const AttributeGroups& lcl_getAttributeGroups()
        {
            DBG_TESTSOLARMUTEX();
            static AttributeGroups s_attributeGroups;
            if ( s_attributeGroups.empty() )
            {
                const PropertyDescription* desc = lcl_getPropertyMetaData();
                while ( desc->propertyName.getLength() != 0 )
                {
                    if ( desc->propertyGroup != NO_GROUP )
                        s_attributeGroups.insert( AttributeGroups::value_type( desc->attribute, desc->propertyGroup ) );
                    ++desc;
                }
            }
            return s_attributeGroups;
        }

        //..............................................................................................................
        typedef ::std::hash_map< AttributeDescription, PropertyGroups, AttributeHash > AttributesWithoutGroup;

        //..............................................................................................................
        const AttributesWithoutGroup& lcl_getAttributesWithoutGroups()
        {
            DBG_TESTSOLARMUTEX();
            static AttributesWithoutGroup s_attributesWithoutGroup;
            if ( s_attributesWithoutGroup.empty() )
            {
                const PropertyDescription* desc = lcl_getPropertyMetaData();
                while ( desc->propertyName.getLength() != 0 )
                {
                    if ( desc->propertyGroup == NO_GROUP )
                    {
                        PropertyDescriptionList singleElementList;
                        singleElementList.push_back( desc );

                        s_attributesWithoutGroup[ desc->attribute ].push_back( singleElementList );
                    }
                    ++desc;
                }
            }
            return s_attributesWithoutGroup;
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    const PropertyDescription* getPropertyDescription( const ::rtl::OUString& i_propertyName )
    {
        const DescriptionsByName& rAllDescriptions( lcl_getPropertyDescriptions() );
        DescriptionsByName::const_iterator pos = rAllDescriptions.find( i_propertyName );
        if ( pos != rAllDescriptions.end() )
            return pos->second;
        return NULL;
    }

	//------------------------------------------------------------------------------------------------------------------
    void getPropertyGroup( const PropertyGroup i_propertyGroup, PropertyDescriptionList& o_propertyDescriptions )
    {
        OSL_ENSURE( i_propertyGroup != NO_GROUP, "xmloff::metadata::getPropertyGroup: illegal group!" );

        const IndexedPropertyGroups& rPropertyGroups( lcl_getIndexedPropertyGroups() );
        const IndexedPropertyGroups::const_iterator pos = rPropertyGroups.find( i_propertyGroup );
        if ( pos != rPropertyGroups.end() )
            o_propertyDescriptions = pos->second;
    }

	//------------------------------------------------------------------------------------------------------------------
    void getPropertyGroupList( const AttributeDescription& i_attribute, PropertyGroups& o_propertyGroups )
    {
        const AttributeGroups& rAttributeGroups = lcl_getAttributeGroups();

        ::std::pair< AttributeGroups::const_iterator, AttributeGroups::const_iterator >
            range = rAttributeGroups.equal_range( i_attribute );

        if ( range.first == range.second )
        {
            // the attribute is not used for any non-trivial group, which means it is mapped directly to
            // a single property
            const AttributesWithoutGroup& attributesWithoutGroups( lcl_getAttributesWithoutGroups() );
            const AttributesWithoutGroup::const_iterator pos = attributesWithoutGroups.find( i_attribute );
            if ( pos != attributesWithoutGroups.end() )
                o_propertyGroups = pos->second;
        }
        else
        {
            const IndexedPropertyGroups& rPropertyGroups = lcl_getIndexedPropertyGroups();
            for ( AttributeGroups::const_iterator group = range.first; group != range.second; ++group )
            {
                const PropertyGroup propGroup = group->second;
                const IndexedPropertyGroups::const_iterator groupPos = rPropertyGroups.find( propGroup );
                ENSURE_OR_CONTINUE( groupPos != rPropertyGroups.end(), "getPropertyGroupList: inconsistency!" );
                o_propertyGroups.push_back( groupPos->second );
            }
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    AttributeDescription getAttributeDescription( const sal_uInt16 i_namespacePrefix, const ::rtl::OUString& i_attributeName )
    {
        AttributeDescription attribute;
        const ReverseTokenLookup& rTokenLookup( getReverseTokenLookup() );
        const ReverseTokenLookup::const_iterator pos = rTokenLookup.find( i_attributeName );
        if ( pos != rTokenLookup.end() )
        {
            attribute.namespacePrefix = i_namespacePrefix;
            attribute.attributeToken = pos->second;
        }
        return attribute;
    }

//......................................................................................................................
} } // namespace xmloff::metadata
//......................................................................................................................
