/**************************************************************
 *
 * 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 <tools/debug.hxx>
#include <xmloff/xmlprhdl.hxx>
#include "xmlbahdl.hxx"
#include <xmloff/xmlprmap.hxx>
#include <xmloff/xmltypes.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <xmloff/xmltoken.hxx>


using namespace ::std;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using ::xmloff::token::GetXMLToken;

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
	const XMLPropertyMapEntry& rMapEntry,
	const UniReference< XMLPropertyHandlerFactory >& rFactory ) :
	sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
	sAPIPropertyName( OUString(rMapEntry.msApiName, rMapEntry.nApiNameLength,
                               RTL_TEXTENCODING_ASCII_US ) ),
	nXMLNameSpace( rMapEntry.mnNameSpace ),
	nType( rMapEntry.mnType ),
	nContextId( rMapEntry.mnContextId ),
    nEarliestODFVersionForExport( rMapEntry.mnEarliestODFVersionForExport ),
	pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
{
}

XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
		const XMLPropertySetMapperEntry_Impl& rEntry ) :
	sXMLAttributeName( rEntry.sXMLAttributeName),
	sAPIPropertyName( rEntry.sAPIPropertyName),
	nXMLNameSpace( rEntry.nXMLNameSpace),
	nType( rEntry.nType),
	nContextId( rEntry.nContextId),
    nEarliestODFVersionForExport( rEntry.nEarliestODFVersionForExport ),
	pHdl( rEntry.pHdl)
{
	DBG_ASSERT( pHdl, "Unknown XML property type handler!" );
}

///////////////////////////////////////////////////////////////////////////
//
// Ctor
//
XMLPropertySetMapper::XMLPropertySetMapper(
		const XMLPropertyMapEntry* pEntries,
		const UniReference< XMLPropertyHandlerFactory >& rFactory )
{
	aHdlFactories.push_back( rFactory );
	if( pEntries )
	{
		const XMLPropertyMapEntry* pIter = pEntries;

		// count entries
		while( pIter->msApiName )
		{
			XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
			aMapEntries.push_back( aEntry );
			pIter++;
		}
	}
}

XMLPropertySetMapper::~XMLPropertySetMapper()
{
}

void XMLPropertySetMapper::AddMapperEntry(
	const UniReference < XMLPropertySetMapper >& rMapper )
{
	for( vector < UniReference < XMLPropertyHandlerFactory > >::iterator
			aFIter = rMapper->aHdlFactories.begin();
		 aFIter != rMapper->aHdlFactories.end();
		 aFIter++ )
	{
		aHdlFactories.push_back( *aFIter );
	}

	for( vector < XMLPropertySetMapperEntry_Impl >::iterator
			aEIter = rMapper->aMapEntries.begin();
		 aEIter != rMapper->aMapEntries.end();
		 aEIter++ )
	{
		aMapEntries.push_back( *aEIter );
	}
}

///////////////////////////////////////////////////////////////////////////
//
// Export a Property
//
sal_Bool XMLPropertySetMapper::exportXML(
		OUString& rStrExpValue,
		const XMLPropertyState& rProperty,
		const SvXMLUnitConverter& rUnitConverter ) const
{
	sal_Bool bRet = sal_False;

	const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

	DBG_ASSERT( pHdl, "Unknown XML Type!" );
	if( pHdl )
		bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
								rUnitConverter );

	return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Import a Property
//
sal_Bool XMLPropertySetMapper::importXML(
		const OUString& rStrImpValue,
		XMLPropertyState& rProperty,
		const SvXMLUnitConverter& rUnitConverter ) const
{
	sal_Bool bRet = sal_False;

	const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );

	if( pHdl )
		bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
								rUnitConverter );

	return bRet;
}

///////////////////////////////////////////////////////////////////////////
//
// Search for the given name and the namespace in the list and return
// the index of the entry
// If there is no matching entry the method returns -1
//
sal_Int32 XMLPropertySetMapper::GetEntryIndex(
		sal_uInt16 nNamespace,
		const OUString& rStrName,
		sal_uInt32 nPropType,
		sal_Int32 nStartAt /* = -1 */ ) const
{
	sal_Int32 nEntries = GetEntryCount();
	sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;

    if ( nEntries && nIndex < nEntries )
    {
	    do
	    {
		    const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
		    if( (!nPropType || nPropType == rEntry.GetPropType()) &&
			    rEntry.nXMLNameSpace == nNamespace &&
			    rStrName == rEntry.sXMLAttributeName )
			    return nIndex;
		    else
			    nIndex++;

	    } while( nIndex<nEntries );
    }

	return -1;
}


/** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
sal_Int32 XMLPropertySetMapper::FindEntryIndex(
		const sal_Char* sApiName,
		sal_uInt16 nNameSpace,
		const OUString& sXMLName ) const
{
	sal_Int32 nIndex = 0;
	sal_Int32 nEntries = GetEntryCount();

	do
	{
		const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
		if( rEntry.nXMLNameSpace == nNameSpace &&
			rEntry.sXMLAttributeName.equals( sXMLName ) &&
			0 == rEntry.sAPIPropertyName.compareToAscii( sApiName ) )
			return nIndex;
		else
			nIndex++;

	} while( nIndex < nEntries );

	return -1;
}

sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
{
	sal_Int32 nIndex = 0;
	const sal_Int32 nEntries = GetEntryCount();

    if ( nEntries )
    {
	    do
	    {
		    const XMLPropertySetMapperEntry_Impl& rEntry = aMapEntries[nIndex];
		    if( rEntry.nContextId == nContextId )
			    return nIndex;
		    else
			    nIndex++;

	    } while( nIndex < nEntries );
    }

	return -1;
}

void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex )
{
    const sal_Int32 nEntries = GetEntryCount();
    if( nIndex>=nEntries || nIndex<0 )
        return;
    vector < XMLPropertySetMapperEntry_Impl >::iterator aEIter = aMapEntries.begin();
    for( sal_Int32 nN=0; nN<nIndex; nN++ )
        aEIter++;
    aMapEntries.erase( aEIter );
}
