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

#include "propacc.hxx"

#include <tools/urlobj.hxx>
#include <tools/errcode.hxx>
#include <svl/svarray.hxx>
#include <basic/sbstar.hxx>
#include <sbunoobj.hxx>

using com::sun::star::uno::Reference;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace cppu;


//========================================================================

// Declaration conversion from Sbx to UNO with known target type
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );

//========================================================================

#ifdef WNT
#define CDECL _cdecl
#endif
#if defined(UNX) || defined(OS2)
#define CDECL
#endif

int CDECL SbCompare_PropertyValues_Impl( const void *arg1, const void *arg2 )
{
   return ((PropertyValue*)arg1)->Name.compareTo( ((PropertyValue*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_PropertyValue_Impl( const void *arg1, const void *arg2 )
{
	const ::rtl::OUString *pArg1 = (::rtl::OUString*) arg1;
	const PropertyValue **pArg2 = (const PropertyValue**) arg2;
	return pArg1->compareTo( (*pArg2)->Name );
}

int CDECL SbCompare_Properties_Impl( const void *arg1, const void *arg2 )
{
   return ((Property*)arg1)->Name.compareTo( ((Property*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_Property_Impl( const void *arg1, const void *arg2 )
{
	const ::rtl::OUString *pArg1 = (::rtl::OUString*) arg1;
	const Property *pArg2 = (Property*) arg2;
	return pArg1->compareTo( pArg2->Name );
}

//----------------------------------------------------------------------------

SbPropertyValues::SbPropertyValues()
{
}

//----------------------------------------------------------------------------

SbPropertyValues::~SbPropertyValues()
{
	_xInfo = Reference< XPropertySetInfo >();

	for ( sal_uInt16 n = 0; n < _aPropVals.Count(); ++n )
		delete _aPropVals.GetObject( n );
}

//----------------------------------------------------------------------------

Reference< XPropertySetInfo > SbPropertyValues::getPropertySetInfo(void) throw( RuntimeException )
{
	// create on demand?
	if ( !_xInfo.is() )
	{
		SbPropertySetInfo *pInfo = new SbPropertySetInfo( _aPropVals );
		((SbPropertyValues*)this)->_xInfo = (XPropertySetInfo*)pInfo;
	}
	return _xInfo;
}

//-------------------------------------------------------------------------

sal_Int32 SbPropertyValues::GetIndex_Impl( const ::rtl::OUString &rPropName ) const
{
	PropertyValue **ppPV;
	ppPV = (PropertyValue **)
			bsearch( &rPropName, _aPropVals.GetData(), _aPropVals.Count(),
					  sizeof( PropertyValue* ),
					  SbCompare_UString_PropertyValue_Impl );
	return ppPV ? ( (ppPV-_aPropVals.GetData()) / sizeof(ppPV) ) : USHRT_MAX;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValue(
					const ::rtl::OUString& aPropertyName,
					const Any& aValue)
                    throw (::com::sun::star::beans::UnknownPropertyException,
                    ::com::sun::star::beans::PropertyVetoException,
                    ::com::sun::star::lang::IllegalArgumentException,
                    ::com::sun::star::lang::WrappedTargetException,
                    ::com::sun::star::uno::RuntimeException)
{
	sal_Int32 nIndex = GetIndex_Impl( aPropertyName );
	PropertyValue *pPropVal = _aPropVals.GetObject(
        sal::static_int_cast< sal_uInt16 >(nIndex));
	pPropVal->Value = aValue;
}

//----------------------------------------------------------------------------

Any SbPropertyValues::getPropertyValue(
					const ::rtl::OUString& aPropertyName)
		            throw(::com::sun::star::beans::UnknownPropertyException,
    				::com::sun::star::lang::WrappedTargetException,
	    			::com::sun::star::uno::RuntimeException)
{
	sal_Int32 nIndex = GetIndex_Impl( aPropertyName );
	if ( nIndex != USHRT_MAX )
		return _aPropVals.GetObject(
            sal::static_int_cast< sal_uInt16 >(nIndex))->Value;
	return Any();
}

//----------------------------------------------------------------------------

void SbPropertyValues::addPropertyChangeListener(
					const ::rtl::OUString& aPropertyName,
					const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removePropertyChangeListener(
					const ::rtl::OUString& aPropertyName,
					const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::addVetoableChangeListener(
					const ::rtl::OUString& aPropertyName,
					const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removeVetoableChangeListener(
					const ::rtl::OUString& aPropertyName,
					const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyValues::getPropertyValues(void) throw (::com::sun::star::uno::RuntimeException)
{
	Sequence<PropertyValue> aRet( _aPropVals.Count());
	for ( sal_uInt16 n = 0; n < _aPropVals.Count(); ++n )
		aRet.getArray()[n] = *_aPropVals.GetObject(n);
	return aRet;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValues(const Sequence< PropertyValue >& rPropertyValues )
                     throw (::com::sun::star::beans::UnknownPropertyException,
                     ::com::sun::star::beans::PropertyVetoException,
                     ::com::sun::star::lang::IllegalArgumentException,
                     ::com::sun::star::lang::WrappedTargetException,
                     ::com::sun::star::uno::RuntimeException)
{
	if ( _aPropVals.Count() )
		throw PropertyExistException();

	const PropertyValue *pPropVals = rPropertyValues.getConstArray();
	for ( sal_Int16 n = 0; n < rPropertyValues.getLength(); ++n )
	{
		PropertyValue *pPropVal = new PropertyValue(pPropVals[n]);
		_aPropVals.Insert( pPropVal, n );
	}
}

//============================================================================
//PropertySetInfoImpl

PropertySetInfoImpl::PropertySetInfoImpl()
{
}

sal_Int32 PropertySetInfoImpl::GetIndex_Impl( const ::rtl::OUString &rPropName ) const
{
	Property *pP;
	pP = (Property*)
			bsearch( &rPropName, _aProps.getConstArray(), _aProps.getLength(),
					  sizeof( Property ),
					  SbCompare_UString_Property_Impl );
	return pP ? sal::static_int_cast<sal_Int32>( (pP-_aProps.getConstArray()) / sizeof(pP) ) : -1;
}

Sequence< Property > PropertySetInfoImpl::getProperties(void) throw()
{
	return _aProps;
}

Property PropertySetInfoImpl::getPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException )
{
	sal_Int32 nIndex = GetIndex_Impl( Name );
	if( USHRT_MAX != nIndex )
		return _aProps.getConstArray()[ nIndex ];
	return Property();
}

sal_Bool PropertySetInfoImpl::hasPropertyByName(const ::rtl::OUString& Name) throw( RuntimeException )
{
	sal_Int32 nIndex = GetIndex_Impl( Name );
	return USHRT_MAX != nIndex;
}


//============================================================================

SbPropertySetInfo::SbPropertySetInfo()
{
}

//----------------------------------------------------------------------------

SbPropertySetInfo::SbPropertySetInfo( const SbPropertyValueArr_Impl &rPropVals )
{
	aImpl._aProps.realloc( rPropVals.Count() );
	for ( sal_uInt16 n = 0; n < rPropVals.Count(); ++n )
	{
		Property &rProp = aImpl._aProps.getArray()[n];
		const PropertyValue &rPropVal = *rPropVals.GetObject(n);
		rProp.Name = rPropVal.Name;
		rProp.Handle = rPropVal.Handle;
		rProp.Type = getCppuVoidType();
		rProp.Attributes = 0;
	}
}

//----------------------------------------------------------------------------

SbPropertySetInfo::~SbPropertySetInfo()
{
}

//-------------------------------------------------------------------------

Sequence< Property > SbPropertySetInfo::getProperties(void) throw( RuntimeException )
{
	return aImpl.getProperties();
}

Property SbPropertySetInfo::getPropertyByName(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	return aImpl.getPropertyByName( Name );
}

sal_Bool SbPropertySetInfo::hasPropertyByName(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	return aImpl.hasPropertyByName( Name );
}


//----------------------------------------------------------------------------

SbPropertyContainer::SbPropertyContainer()
{
}

//----------------------------------------------------------------------------

SbPropertyContainer::~SbPropertyContainer()
{
}

//----------------------------------------------------------------------------
void SbPropertyContainer::addProperty(const ::rtl::OUString& Name,
									  sal_Int16 Attributes,
									  const Any& DefaultValue)
	throw(  PropertyExistException, IllegalTypeException,
			IllegalArgumentException, RuntimeException )
{
    (void)Name;
    (void)Attributes;
    (void)DefaultValue;
}

//----------------------------------------------------------------------------
void SbPropertyContainer::removeProperty(const ::rtl::OUString& Name)
	throw( UnknownPropertyException, RuntimeException )
{
    (void)Name;
}

//----------------------------------------------------------------------------
// XPropertySetInfo
Sequence< Property > SbPropertyContainer::getProperties(void) throw ()
{
	return aImpl.getProperties();
}

Property SbPropertyContainer::getPropertyByName(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	return aImpl.getPropertyByName( Name );
}

sal_Bool SbPropertyContainer::hasPropertyByName(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	return aImpl.hasPropertyByName( Name );
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyContainer::getPropertyValues(void)
{
	return Sequence<PropertyValue>();
}

//----------------------------------------------------------------------------

void SbPropertyContainer::setPropertyValues(const Sequence< PropertyValue >& PropertyValues_)
{
    (void)PropertyValues_;
}

//----------------------------------------------------------------------------

void RTL_Impl_CreatePropertySet( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

    // We need at least one parameter
    // TODO: In this case < 2 is not correct ;-)
	if ( rPar.Count() < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

    // Get class names of struct
	String aServiceName( RTL_CONSTASCII_USTRINGPARAM("stardiv.uno.beans.PropertySet") );

#if 0
	// Service suchen und instanzieren
	Reference< XMultiServiceFactory > xServiceManager = getProcessServiceFactory();
	Reference< XInterface > xInterface;
	if( xProv.is() )
		xInterface = xProv->newInstance();
#else
	Reference< XInterface > xInterface = (OWeakObject*) new SbPropertyValues();
#endif

	SbxVariableRef refVar = rPar.Get(0);
	if( xInterface.is() )
	{
		// Set PropertyValues
		Any aArgAsAny = sbxToUnoValue( rPar.Get(1),
				getCppuType( (Sequence<PropertyValue>*)0 ) );
		Sequence<PropertyValue> *pArg =
				(Sequence<PropertyValue>*) aArgAsAny.getValue();
		Reference< XPropertyAccess > xPropAcc = Reference< XPropertyAccess >::query( xInterface );
		xPropAcc->setPropertyValues( *pArg );

		// Build a SbUnoObject and return it
		Any aAny;
		aAny <<= xInterface;
		SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
		if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
		{
			// Return object
			refVar->PutObject( (SbUnoObject*)xUnoObj );
			return;
		}
	}

	// Object could not be created
	refVar->PutObject( NULL );
}
