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

#ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX
#include "MultiPropertySetHelper.hxx"
#endif
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/stl_types.hxx>

// STL includes
#include <algorithm>


using ::com::sun::star::beans::XMultiPropertySet;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::XPropertySetInfo;
using ::com::sun::star::lang::XServiceInfo;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::UNO_QUERY;
using ::comphelper::UStringLess;
using ::rtl::OUString;
using ::std::sort;


MultiPropertySetHelper::MultiPropertySetHelper(
	const sal_Char** pNames ) :
		pPropertyNames( NULL ),
		nLength( 0 ),
		aPropertySequence(),
		pSequenceIndex( NULL ),
		aValues(),
		pValues( NULL )
{
	// first count the elements
	for( const sal_Char** pPtr = pNames; *pPtr != NULL; pPtr++ )
		nLength++;

	// allocate array and create strings
	pPropertyNames = new OUString[nLength];
	for( sal_Int16 i = 0; i < nLength; i++ )
		pPropertyNames[i] = OUString::createFromAscii( pNames[i] );
}

MultiPropertySetHelper::MultiPropertySetHelper(
	const OUString* pNames ) :
		pPropertyNames( NULL ),
		nLength( 0 ),
		aPropertySequence(),
		pSequenceIndex( NULL ),
		aValues(),
		pValues( NULL )
{
	// count elements
	for( const OUString* pPtr = pNames; pPtr != NULL; pPtr++ )
		nLength++;

	// allocate array and assign strings
	pPropertyNames = new OUString[nLength];
	for( sal_Int16 i = 0; i < nLength; i++ )
		pPropertyNames[i] = pNames[i];
}


MultiPropertySetHelper::~MultiPropertySetHelper()
{
	pValues = NULL;	// memory 'owned' by aValues

	delete[] pSequenceIndex;
	delete[] pPropertyNames;
}



void MultiPropertySetHelper::hasProperties(
	const Reference<XPropertySetInfo> & rInfo )
{
	DBG_ASSERT( rInfo.is(), "I'd really like an XPropertySetInfo here." );

	// allocate sequence index
	if ( NULL == pSequenceIndex )
		pSequenceIndex = new sal_Int16[nLength] ;

	// construct pSequenceIndex
	sal_Int16 nNumberOfProperties = 0;
	sal_Int16 i;

	for( i = 0; i < nLength; i++ )
	{
		// ask for property
		sal_Bool bHasProperty =
			rInfo->hasPropertyByName( pPropertyNames[i] );

		// set index and increment (if appropriate)
		pSequenceIndex[i]= bHasProperty ? nNumberOfProperties : -1;
		if ( bHasProperty )
			nNumberOfProperties++;
	}

	// construct property sequence from index array
	if ( aPropertySequence.getLength() != nNumberOfProperties )
		aPropertySequence.realloc( nNumberOfProperties );
	OUString* pPropertySequence = aPropertySequence.getArray();
	for( i = 0; i < nLength; i ++ )
	{
		sal_Int16 nIndex = pSequenceIndex[i];
		if ( nIndex != -1 )
			pPropertySequence[nIndex] = pPropertyNames[i];
	}
}

sal_Bool MultiPropertySetHelper::checkedProperties()
{
    return (NULL != pSequenceIndex);
}



void MultiPropertySetHelper::getValues(
	const Reference<XMultiPropertySet> & rMultiPropertySet )
{
	DBG_ASSERT( rMultiPropertySet.is(), "We need an XMultiPropertySet." );

	aValues = rMultiPropertySet->getPropertyValues( aPropertySequence );
	pValues = aValues.getConstArray();
}

void MultiPropertySetHelper::getValues(
	const Reference<XPropertySet> & rPropertySet )
{
	DBG_ASSERT( rPropertySet.is(), "We need an XPropertySet." );

	// re-alloc aValues (if necessary) and fill with values from XPropertySet
	sal_Int16 nSupportedPropertiesCount =
		(sal_Int16)aPropertySequence.getLength();
	if ( aValues.getLength() != nSupportedPropertiesCount )
		aValues.realloc( nSupportedPropertiesCount );
	Any* pMutableArray = aValues.getArray();
	for( sal_Int16 i = 0; i < nSupportedPropertiesCount; i++ )
	{
		pMutableArray[i] = rPropertySet->getPropertyValue(
			pPropertyNames[ pSequenceIndex[ i ] ] );
	}

	// re-establish pValues pointer
	pValues = aValues.getConstArray();
}


const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex,
					 const Reference< XPropertySet> & rPropSet,
					 sal_Bool bTryMulti )
{
	if( !pValues )
	{
		if( bTryMulti )
		{
			Reference < XMultiPropertySet > xMultiPropSet( rPropSet,
														   UNO_QUERY );
			if( xMultiPropSet.is() )
				getValues( xMultiPropSet );
			else
				getValues( rPropSet );
		}
		else
		{
			getValues( rPropSet );
		}
	}

	return getValue( nIndex );
}

const Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex,
					 const Reference< XMultiPropertySet> & rMultiPropSet )
{
	if( !pValues )
		getValues( rMultiPropSet );

	return getValue( nIndex );
}

// inline methods defined in header:
// inline Any& MultiPropertySetHelper::getValue( sal_Int16 nIndex )
// inline sal_Bool MultiPropertySetHelper::hasProperty( sal_Int16 nValueNo )
