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

#define _SVX_USE_UNOGLOBALS_
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
#include <com/sun/star/awt/TextAlign.hpp>  //added by BerryJia for fixing Bug102407 2002-11-4
#include <com/sun/star/style/ParagraphAdjust.hpp>   //added by BerryJia for fixing Bug102407 2002-11-4
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/PointSequence.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <tools/urlobj.hxx>
#include <unotools/localfilehelper.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
#include <svtools/fltcall.hxx>
#include <svtools/filter.hxx>

#include <boost/scoped_ptr.hpp>
#include <svx/svdpool.hxx>
#include <rtl/uuid.h>
#include <rtl/memory.h>
#include <tools/urlobj.hxx>

#include <editeng/unoprnms.hxx>
#include <svx/unoshape.hxx>
#include <svx/unopage.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdmodel.hxx>
#include <svx/svdouno.hxx>
#include "shapeimpl.hxx"
#include "svx/unoshprp.hxx"
#include <svx/svdoashp.hxx>
#include "unopolyhelper.hxx"

// #i29181#
#include "svx/svdviter.hxx"
#include <svx/svdview.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

using ::rtl::OUString;
using namespace ::osl;
using namespace ::vos;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;

#define INTERFACE_TYPE( xint ) \
	::getCppuType((const Reference< xint >*)0)

#define QUERYINT( xint ) \
	if( rType == ::getCppuType((const Reference< xint >*)0) ) \
		aAny <<= Reference< xint >(this)

class GDIMetaFile;
class SvStream;
sal_Bool ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
							  FilterConfigItem* pFilterConfigItem = NULL, sal_Bool bPlaceable = sal_True );

/***********************************************************************
* class SvxShapeGroup                                                  *
***********************************************************************/

SvxShapeGroup::SvxShapeGroup( SdrObject* pObj, SvxDrawPage* pDrawPage  )  throw() :
	SvxShape( pObj, aSvxMapProvider.GetMap(SVXMAP_GROUP), aSvxMapProvider.GetPropertySet(SVXMAP_GROUP, SdrObject::GetGlobalDrawObjectItemPool()) ),
	mxPage( pDrawPage )
{
}

//----------------------------------------------------------------------
SvxShapeGroup::~SvxShapeGroup() throw()
{
}

//----------------------------------------------------------------------
void SvxShapeGroup::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
{
	SvxShape::Create( pNewObj, pNewPage );
	mxPage = pNewPage;
}

//----------------------------------------------------------------------
uno::Any SAL_CALL SvxShapeGroup::queryInterface( const uno::Type & rType )
	throw(uno::RuntimeException)
{
	return SvxShape::queryInterface( rType );
}

uno::Any SAL_CALL SvxShapeGroup::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
{
	uno::Any aAny;

	QUERYINT( drawing::XShapeGroup );
	else QUERYINT( drawing::XShapes );
	else QUERYINT( container::XIndexAccess );
	else QUERYINT( container::XElementAccess );
	else
		return SvxShape::queryAggregation( rType );

	return aAny;
}

void SAL_CALL SvxShapeGroup::acquire() throw ( )
{
	SvxShape::acquire();
}

void SAL_CALL SvxShapeGroup::release() throw ( )
{
	SvxShape::release();
}

uno::Sequence< uno::Type > SAL_CALL SvxShapeGroup::getTypes()
	throw (uno::RuntimeException)
{
	return SvxShape::getTypes();
}

uno::Sequence< sal_Int8 > SAL_CALL SvxShapeGroup::getImplementationId()
	throw (uno::RuntimeException)
{
	static uno::Sequence< sal_Int8 > aId;
	if( aId.getLength() == 0 )
	{
		aId.realloc( 16 );
		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
	}
	return aId;
}

// ::com::sun::star::drawing::XShape

//----------------------------------------------------------------------
OUString SAL_CALL SvxShapeGroup::getShapeType()
	throw( uno::RuntimeException )
{
	return SvxShape::getShapeType();
}

//------------------------------------------------------------------1----
awt::Point SAL_CALL SvxShapeGroup::getPosition() throw(uno::RuntimeException)
{
	return SvxShape::getPosition();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeGroup::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
{
	SvxShape::setPosition(Position);
}

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

awt::Size SAL_CALL SvxShapeGroup::getSize() throw(uno::RuntimeException)
{
	return SvxShape::getSize();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeGroup::setSize( const awt::Size& rSize )
	throw(beans::PropertyVetoException, uno::RuntimeException)
{
	SvxShape::setSize( rSize );
}

// drawing::XShapeGroup

//----------------------------------------------------------------------
void SAL_CALL SvxShapeGroup::enterGroup(  ) throw(uno::RuntimeException)
{
	// Todo
//	pDrView->EnterMarkedGroup();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeGroup::leaveGroup(  ) throw(uno::RuntimeException)
{
	// Todo
//	pDrView->LeaveOneGroup();
}

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

// XShapes
void SAL_CALL SvxShapeGroup::add( const uno::Reference< drawing::XShape >& xShape )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	SvxShape* pShape = SvxShape::getImplementation( xShape );

	if( mpObj.is()&& mxPage.is() && pShape )
	{
		SdrObject* pSdrShape = pShape->GetSdrObject();
		if( pSdrShape == NULL )
			pSdrShape = mxPage->_CreateSdrObject( xShape );

		if( pSdrShape->IsInserted() )
			pSdrShape->GetObjList()->RemoveObject( pSdrShape->GetOrdNum() );

		mpObj->GetSubList()->InsertObject( pSdrShape );
		pSdrShape->SetModel(mpObj->GetModel());

		// #85922# It makes no sense to set the layer asked
		// from the group object since these is an iteration
		// over the contained objects. In consequence, this
		// statement erases all layer information from the draw
		// objects. Layers need to be set at draw objects directly
		// and have nothing to do with grouping at all.
		// pSdrShape->SetLayer(pObject->GetLayer());

        // Establish connection between new SdrObject and its wrapper before
        // inserting the new shape into the group.  There a new wrapper
        // would be created when this connection would not already exist.
		if(pShape)
			pShape->Create( pSdrShape, mxPage.get() );

		if( mpModel )
			mpModel->SetChanged();
	}
	else
	{
		DBG_ERROR("could not add XShape to group shape!");
	}
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeGroup::remove( const uno::Reference< drawing::XShape >& xShape )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	SdrObject* pSdrShape = NULL;
	SvxShape* pShape = SvxShape::getImplementation( xShape );

	if( pShape )
		pSdrShape = pShape->GetSdrObject();

	if( !mpObj.is() || pSdrShape == NULL || pSdrShape->GetObjList()->GetOwnerObj() != mpObj.get() )
		throw uno::RuntimeException();

	SdrObjList& rList = *pSdrShape->GetObjList();

	const sal_uInt32 nObjCount = rList.GetObjCount();
	sal_uInt32 nObjNum = 0;
	while( nObjNum < nObjCount )
	{
		if(rList.GetObj( nObjNum ) == pSdrShape )
			break;
		nObjNum++;
	}

	if( nObjNum < nObjCount )
	{
		// #i29181#
		// If the SdrObject which is about to be deleted is in any selection,
		// deselect it first.
        SdrViewIter aIter( pSdrShape );

		for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
		{
			if(CONTAINER_ENTRY_NOTFOUND != pView->TryToFindMarkedObject(pSdrShape))
			{
				pView->MarkObj(pSdrShape, pView->GetSdrPageView(), sal_True, sal_False);
			}
		}

		SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
        SdrObject::Free( pObject );
	}
	else
	{
		DBG_ASSERT( 0, "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
	}

	if( mpModel )
		mpModel->SetChanged();
}

// XIndexAccess

//----------------------------------------------------------------------
sal_Int32 SAL_CALL SvxShapeGroup::getCount() throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	sal_Int32 nRetval = 0;

	if(mpObj.is() && mpObj->GetSubList())
		nRetval = mpObj->GetSubList()->GetObjCount();
	else
		throw uno::RuntimeException();

	return nRetval;
}

//----------------------------------------------------------------------
uno::Any SAL_CALL SvxShapeGroup::getByIndex( sal_Int32 Index )
	throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	if( !mpObj.is() || mpObj->GetSubList() == NULL )
		throw uno::RuntimeException();

	if( mpObj->GetSubList()->GetObjCount() <= (sal_uInt32)Index )
		throw lang::IndexOutOfBoundsException();

	SdrObject* pDestObj = mpObj->GetSubList()->GetObj( Index );

	if(pDestObj == NULL)
		throw lang::IndexOutOfBoundsException();

	Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
	return uno::makeAny( xShape );
}

// ::com::sun::star::container::XElementAccess

//----------------------------------------------------------------------
uno::Type SAL_CALL SvxShapeGroup::getElementType() throw( uno::RuntimeException )
{
	return ::getCppuType(( const Reference< drawing::XShape >*)0);
}

//----------------------------------------------------------------------
sal_Bool SAL_CALL SvxShapeGroup::hasElements() throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	return mpObj.is() && mpObj->GetSubList() && (mpObj->GetSubList()->GetObjCount() > 0);
}

//----------------------------------------------------------------------
// ::com::sun::star::lang::XServiceInfo

uno::Sequence< OUString > SAL_CALL SvxShapeGroup::getSupportedServiceNames()
	throw(uno::RuntimeException)
{
	return SvxShape::getSupportedServiceNames();
}

/***********************************************************************
*                                                                      *
***********************************************************************/

SvxShapeConnector::SvxShapeConnector( SdrObject* pObj )  throw() :
	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CONNECTOR), aSvxMapProvider.GetPropertySet(SVXMAP_CONNECTOR, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

//----------------------------------------------------------------------
SvxShapeConnector::~SvxShapeConnector() throw()
{
}

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

uno::Any SAL_CALL SvxShapeConnector::queryInterface( const uno::Type & rType )
	throw(uno::RuntimeException)
{
	return SvxShapeText::queryInterface( rType );
}

uno::Any SAL_CALL SvxShapeConnector::queryAggregation( const uno::Type & rType )
	throw(uno::RuntimeException)
{
	uno::Any aAny;

	QUERYINT( drawing::XConnectorShape );
	else
		return SvxShapeText::queryAggregation( rType );

	return aAny;
}

void SAL_CALL SvxShapeConnector::acquire() throw ( )
{
	SvxShapeText::acquire();
}

void SAL_CALL SvxShapeConnector::release() throw ( )
{
	SvxShapeText::release();
}
// XTypeProvider

uno::Sequence< uno::Type > SAL_CALL SvxShapeConnector::getTypes()
	throw (uno::RuntimeException)
{
	return SvxShape::getTypes();
}

uno::Sequence< sal_Int8 > SAL_CALL SvxShapeConnector::getImplementationId()
	throw (uno::RuntimeException)
{
	static uno::Sequence< sal_Int8 > aId;
	if( aId.getLength() == 0 )
	{
		aId.realloc( 16 );
		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
	}
	return aId;
}

// ::com::sun::star::drawing::XShape

//----------------------------------------------------------------------
OUString SAL_CALL SvxShapeConnector::getShapeType()
	throw( uno::RuntimeException )
{
	return SvxShapeText::getShapeType();
}

//------------------------------------------------------------------1----
awt::Point SAL_CALL SvxShapeConnector::getPosition() throw(uno::RuntimeException)
{
	return SvxShapeText::getPosition();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeConnector::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
{
	SvxShapeText::setPosition(Position);
}

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

awt::Size SAL_CALL SvxShapeConnector::getSize() throw(uno::RuntimeException)
{
	return SvxShapeText::getSize();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeConnector::setSize( const awt::Size& rSize )
	throw(beans::PropertyVetoException, uno::RuntimeException)
{
	SvxShapeText::setSize( rSize );
}

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

// XConnectorShape

void SAL_CALL SvxShapeConnector::connectStart( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType ) throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
	SvxShape* pShape = SvxShape::getImplementation( xRef );

	if( pShape )
		mpObj->ConnectToNode( sal_True, pShape->mpObj.get() );

	if( mpModel )
		mpModel->SetChanged();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeConnector::connectEnd( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType  )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
	SvxShape* pShape = SvxShape::getImplementation( xRef );

	if( mpObj.is() && pShape )
		mpObj->ConnectToNode( sal_False, pShape->mpObj.get() );

	if( mpModel )
		mpModel->SetChanged();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeConnector::disconnectBegin( const uno::Reference< drawing::XConnectableShape >&  )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
		mpObj->DisconnectFromNode( sal_True );

	if( mpModel )
		mpModel->SetChanged();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeConnector::disconnectEnd( const uno::Reference< drawing::XConnectableShape >& )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
		mpObj->DisconnectFromNode( sal_False );

	if( mpModel )
		mpModel->SetChanged();
}

//----------------------------------------------------------------------
// ::com::sun::star::lang::XServiceInfo
//----------------------------------------------------------------------
uno::Sequence< OUString > SAL_CALL SvxShapeConnector::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

/***********************************************************************
* class SvxShapeControl                                                *
***********************************************************************/
DBG_NAME(SvxShapeControl)

SvxShapeControl::SvxShapeControl( SdrObject* pObj )  throw() :
	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CONTROL), aSvxMapProvider.GetPropertySet(SVXMAP_CONTROL, SdrObject::GetGlobalDrawObjectItemPool()) )
{
    DBG_CTOR(SvxShapeControl,NULL);
	setShapeKind( OBJ_UNO );
}

//----------------------------------------------------------------------
SvxShapeControl::~SvxShapeControl() throw()
{
    DBG_DTOR(SvxShapeControl,NULL);
}

//----------------------------------------------------------------------
uno::Any SAL_CALL SvxShapeControl::queryInterface( const uno::Type & rType )
	throw(uno::RuntimeException)
{
	return SvxShapeText::queryInterface( rType );
}

uno::Any SAL_CALL SvxShapeControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
{
	uno::Any aAny;

	QUERYINT( drawing::XControlShape );
	else
		return SvxShapeText::queryAggregation( rType );

	return aAny;
}

void SAL_CALL SvxShapeControl::acquire() throw ( )
{
	SvxShapeText::acquire();
}

void SAL_CALL SvxShapeControl::release() throw ( )
{
	SvxShapeText::release();
}
// XTypeProvider

uno::Sequence< uno::Type > SAL_CALL SvxShapeControl::getTypes()
	throw (uno::RuntimeException)
{
	return SvxShape::getTypes();
}

uno::Sequence< sal_Int8 > SAL_CALL SvxShapeControl::getImplementationId()
	throw (uno::RuntimeException)
{
	static uno::Sequence< sal_Int8 > aId;
	if( aId.getLength() == 0 )
	{
		aId.realloc( 16 );
		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
	}
	return aId;
}

// ::com::sun::star::drawing::XShape

//----------------------------------------------------------------------
OUString SAL_CALL SvxShapeControl::getShapeType()
	throw( uno::RuntimeException )
{
	return SvxShapeText::getShapeType();
}

//------------------------------------------------------------------1----
awt::Point SAL_CALL SvxShapeControl::getPosition() throw(uno::RuntimeException)
{
	return SvxShapeText::getPosition();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeControl::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
{
	SvxShapeText::setPosition(Position);
}

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

awt::Size SAL_CALL SvxShapeControl::getSize() throw(uno::RuntimeException)
{
	return SvxShapeText::getSize();
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeControl::setSize( const awt::Size& rSize )
	throw(beans::PropertyVetoException, uno::RuntimeException)
{
	SvxShapeText::setSize( rSize );
}

//----------------------------------------------------------------------
// XControlShape

Reference< awt::XControlModel > SAL_CALL SvxShapeControl::getControl()
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	Reference< awt::XControlModel > xModel;

	SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(mpObj.get());
	if( pUnoObj )
		xModel = pUnoObj->GetUnoControlModel();

	return xModel;
}

//----------------------------------------------------------------------
void SAL_CALL SvxShapeControl::setControl( const Reference< awt::XControlModel >& xControl )
	throw( uno::RuntimeException )
{
	OGuard aGuard( Application::GetSolarMutex() );

	SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(mpObj.get());
	if( pUnoObj )
		pUnoObj->SetUnoControlModel( xControl );

	if( mpModel )
		mpModel->SetChanged();
}

// XServiceInfo
uno::Sequence< OUString > SAL_CALL SvxShapeControl::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

static struct
{
	const sal_Char* mpAPIName;
	sal_uInt16 mnAPINameLen;

	const sal_Char* mpFormName;
	sal_uInt16 mnFormNameLen;
}
SvxShapeControlPropertyMapping[] =
{
	// Warning: The first entry must be FontSlant because the any needs to be converted
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_POSTURE), MAP_CHAR_LEN("FontSlant")  }, //  const sal_Int16 => ::com::sun::star::awt::FontSlant
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTNAME), MAP_CHAR_LEN("FontName") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTSTYLENAME), MAP_CHAR_LEN("FontStyleName") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTFAMILY), MAP_CHAR_LEN("FontFamily") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTCHARSET), MAP_CHAR_LEN("FontCharset") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_HEIGHT), MAP_CHAR_LEN("FontHeight") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTPITCH), MAP_CHAR_LEN("FontPitch" ) },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_WEIGHT), MAP_CHAR_LEN("FontWeight" ) },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_UNDERLINE), MAP_CHAR_LEN("FontUnderline") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_STRIKEOUT), MAP_CHAR_LEN("FontStrikeout") },
	{ MAP_CHAR_LEN("CharKerning"), MAP_CHAR_LEN("FontKerning") },
	{ MAP_CHAR_LEN("CharWordMode"), MAP_CHAR_LEN("FontWordLineMode" ) },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_COLOR),	MAP_CHAR_LEN("TextColor") },
	{ MAP_CHAR_LEN("CharRelief"),	MAP_CHAR_LEN("FontRelief") },
	{ MAP_CHAR_LEN("CharUnderlineColor"),	MAP_CHAR_LEN("TextLineColor") },
	{ MAP_CHAR_LEN(UNO_NAME_EDIT_PARA_ADJUST), MAP_CHAR_LEN("Align") },
    { MAP_CHAR_LEN("TextVerticalAdjust"), MAP_CHAR_LEN("VerticalAlign") },
	{ MAP_CHAR_LEN("ControlBackground"), MAP_CHAR_LEN("BackgroundColor") },
	{ MAP_CHAR_LEN("ControlSymbolColor"), MAP_CHAR_LEN("SymbolColor") },
	{ MAP_CHAR_LEN("ControlBorder"), MAP_CHAR_LEN("Border") },
	{ MAP_CHAR_LEN("ControlBorderColor"), MAP_CHAR_LEN("BorderColor") },
	{ MAP_CHAR_LEN("ControlTextEmphasis"),	MAP_CHAR_LEN("FontEmphasisMark") },
    { MAP_CHAR_LEN("ImageScaleMode"),  MAP_CHAR_LEN("ScaleMode") },
	{ MAP_CHAR_LEN("ControlWritingMode"), MAP_CHAR_LEN("WritingMode") },
	//added for exporting OCX control
	{ MAP_CHAR_LEN("ControlTypeinMSO"), MAP_CHAR_LEN("ControlTypeinMSO") },
	{ MAP_CHAR_LEN("ObjIDinMSO"), MAP_CHAR_LEN("ObjIDinMSO") },
	{ NULL,0, NULL, 0 }
};

namespace
{
    static bool lcl_convertPropertyName( const OUString& rApiName, OUString& rInternalName )
    {
	    sal_uInt16 i = 0;
	    while( SvxShapeControlPropertyMapping[i].mpAPIName )
	    {
		    if( rApiName.reverseCompareToAsciiL( SvxShapeControlPropertyMapping[i].mpAPIName, SvxShapeControlPropertyMapping[i].mnAPINameLen ) == 0 )
		    {
			    rInternalName = OUString( SvxShapeControlPropertyMapping[i].mpFormName, SvxShapeControlPropertyMapping[i].mnFormNameLen, RTL_TEXTENCODING_ASCII_US );
		    }
		    ++i;
	    }
        return rInternalName.getLength() > 0;
    }

    struct EnumConversionMap
    {
        sal_Int16   nAPIValue;
        sal_Int16   nFormValue;
    };

    EnumConversionMap aMapAdjustToAlign[] =
    {
	    // note that order matters:
	    // lcl_convertTextAlignmentToParaAdjustment and lcl_convertParaAdjustmentToTextAlignment search this map from the _beginning_
	    // and use the first matching entry
	    {style::ParagraphAdjust_LEFT,			(sal_Int16)awt::TextAlign::LEFT},
	    {style::ParagraphAdjust_CENTER,			(sal_Int16)awt::TextAlign::CENTER},
	    {style::ParagraphAdjust_RIGHT,			(sal_Int16)awt::TextAlign::RIGHT},
	    {style::ParagraphAdjust_BLOCK,			(sal_Int16)awt::TextAlign::RIGHT},
	    {style::ParagraphAdjust_STRETCH,		(sal_Int16)awt::TextAlign::LEFT},
	    {-1,-1}
    };

    static void lcl_mapFormToAPIValue( Any& _rValue, const EnumConversionMap* _pMap )
    {
	    sal_Int16 nValue = sal_Int16();
	    OSL_VERIFY( _rValue >>= nValue );

        const EnumConversionMap* pEntry = _pMap;
        while ( pEntry && ( pEntry->nFormValue != -1 ) )
	    {
		    if ( nValue == pEntry->nFormValue )
		    {
			    _rValue <<= pEntry->nAPIValue;
			    return;
		    }
            ++pEntry;
	    }
    }

    static void lcl_mapAPIToFormValue( Any& _rValue, const EnumConversionMap* _pMap )
    {
	    sal_Int32 nValue = 0;
	    OSL_VERIFY( _rValue >>= nValue );

        const EnumConversionMap* pEntry = _pMap;
        while ( pEntry && ( pEntry->nAPIValue != -1 ) )
	    {
		    if ( nValue == pEntry->nAPIValue )
		    {
			    _rValue <<= pEntry->nFormValue;
			    return;
		    }
            ++pEntry;
	    }
    }

    static void lcl_convertTextAlignmentToParaAdjustment( Any& rValue )
    {
        lcl_mapFormToAPIValue( rValue, aMapAdjustToAlign );
    }

    static void lcl_convertParaAdjustmentToTextAlignment( Any& rValue )
    {
        lcl_mapAPIToFormValue( rValue, aMapAdjustToAlign );
    }

    void convertVerticalAdjustToVerticalAlign( Any& _rValue ) SAL_THROW( ( lang::IllegalArgumentException ) )
    {
        if ( !_rValue.hasValue() )
            return;

        drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
        style::VerticalAlignment    eAlign  = style::VerticalAlignment_TOP;
        if ( !( _rValue >>= eAdjust ) )
            throw lang::IllegalArgumentException();
        switch ( eAdjust )
        {
        case drawing::TextVerticalAdjust_TOP:    eAlign = style::VerticalAlignment_TOP; break;
        case drawing::TextVerticalAdjust_BOTTOM: eAlign = style::VerticalAlignment_BOTTOM; break;
        default:                                 eAlign = style::VerticalAlignment_MIDDLE; break;
        }
        _rValue <<= eAlign;
    }

    void convertVerticalAlignToVerticalAdjust( Any& _rValue )
    {
        if ( !_rValue.hasValue() )
            return;
        style::VerticalAlignment    eAlign  = style::VerticalAlignment_TOP;
        drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
        OSL_VERIFY( _rValue >>= eAlign );
        switch ( eAlign )
        {
        case style::VerticalAlignment_TOP:    eAdjust = drawing::TextVerticalAdjust_TOP; break;
        case style::VerticalAlignment_BOTTOM: eAdjust = drawing::TextVerticalAdjust_BOTTOM; break;
        default:                              eAdjust = drawing::TextVerticalAdjust_CENTER; break;
        }
        _rValue <<= eAdjust;
    }
}

void SAL_CALL SvxShapeControl::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
{
	OUString aFormsName;
	if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
	{
		uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );
		if( xControl.is() )
		{
			uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
			if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
			{
                uno::Any aConvertedValue( aValue );
                if ( aFormsName.equalsAscii( "FontSlant" ) )
                {
                    awt::FontSlant nSlant;
                    if( !(aValue >>= nSlant ) )
                        throw lang::IllegalArgumentException();
                    aConvertedValue <<= (sal_Int16)nSlant;
                }
                else if ( aFormsName.equalsAscii( "Align" ) )
                {
                    lcl_convertParaAdjustmentToTextAlignment( aConvertedValue );
                }
                else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
                {
                    convertVerticalAdjustToVerticalAlign( aConvertedValue );
                }

                xControl->setPropertyValue( aFormsName, aConvertedValue );
			}
		}
	}
	else
	{
		SvxShape::setPropertyValue( aPropertyName, aValue );
	}
}

uno::Any SAL_CALL SvxShapeControl::getPropertyValue( const OUString& aPropertyName )
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
	OUString aFormsName;
	if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
	{
		uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );

        uno::Any aValue;
		if( xControl.is() )
		{
			uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
			if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
			{
                aValue = xControl->getPropertyValue( aFormsName );
                if ( aFormsName.equalsAscii( "FontSlant" ) )
				{
                    awt::FontSlant eSlant = awt::FontSlant_NONE;
					sal_Int16 nSlant = sal_Int16();
                    if ( aValue >>= nSlant )
                    {
                        eSlant = (awt::FontSlant)nSlant;
                    }
                    else
                    {
                        OSL_VERIFY( aValue >>= eSlant );
                    }
                    aValue <<= eSlant;
				}
				else if ( aFormsName.equalsAscii( "Align" ) )
				{
                    lcl_convertTextAlignmentToParaAdjustment( aValue );
				}
                else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
                {
                    convertVerticalAlignToVerticalAdjust( aValue );
                }
			}
		}

		return aValue;
	}
	else
	{
		return SvxShape::getPropertyValue( aPropertyName );
	}

}

// XPropertyState
beans::PropertyState SAL_CALL SvxShapeControl::getPropertyState( const ::rtl::OUString& PropertyName ) throw( beans::UnknownPropertyException, uno::RuntimeException )
{
	OUString aFormsName;
	if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
	{
		uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
		uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );

		if( xControl.is() && xPropSet.is() )
		{
			uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
			if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
			{
				return xControl->getPropertyState( aFormsName );
			}
		}

		return beans::PropertyState_DEFAULT_VALUE;
	}
	else
	{
		return SvxShape::getPropertyState( PropertyName );
	}
}

void SAL_CALL SvxShapeControl::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw( beans::UnknownPropertyException, uno::RuntimeException )
{
	OUString aFormsName;
	if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
	{
		uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
		uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );

		if( xControl.is() && xPropSet.is() )
		{
			uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
			if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
			{
				xControl->setPropertyToDefault( aFormsName );
			}
		}
	}
	else
	{
		SvxShape::setPropertyToDefault( PropertyName );
	}
}

uno::Any SAL_CALL SvxShapeControl::getPropertyDefault( const ::rtl::OUString& aPropertyName )
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
	OUString aFormsName;
	if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
	{
		uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );

		if( xControl.is() )
		{
            Any aDefault( xControl->getPropertyDefault( aFormsName ) );
            if ( aFormsName.equalsAscii( "FontSlant" ) )
			{
				sal_Int16 nSlant( 0 );
				aDefault >>= nSlant;
                aDefault <<= (awt::FontSlant)nSlant;
			}
            else if ( aFormsName.equalsAscii( "Align" ) )
            {
                lcl_convertTextAlignmentToParaAdjustment( aDefault );
            }
            else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
            {
                convertVerticalAlignToVerticalAdjust( aDefault );
            }
            return aDefault;
		}

		throw beans::UnknownPropertyException();
	}
	else
	{
		return SvxShape::getPropertyDefault( aPropertyName );
	}
}


/***********************************************************************
* class SvxShapeDimensioning                                           *
***********************************************************************/

//----------------------------------------------------------------------
SvxShapeDimensioning::SvxShapeDimensioning( SdrObject* pObj ) throw()
:	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_DIMENSIONING), aSvxMapProvider.GetPropertySet(SVXMAP_DIMENSIONING, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

//----------------------------------------------------------------------
SvxShapeDimensioning::~SvxShapeDimensioning() throw()
{
}

// ::com::sun::star::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL SvxShapeDimensioning::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

/***********************************************************************
*                                                                      *
***********************************************************************/

//----------------------------------------------------------------------
SvxShapeCircle::SvxShapeCircle( SdrObject* pObj ) throw()
:	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CIRCLE), aSvxMapProvider.GetPropertySet(SVXMAP_CIRCLE, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

//----------------------------------------------------------------------
SvxShapeCircle::~SvxShapeCircle() throw()
{
}

// ::com::sun::star::lang::XServiceInfo
// XServiceInfo
uno::Sequence< OUString > SAL_CALL SvxShapeCircle::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

/***********************************************************************
*                                                                      *
***********************************************************************/

#include <svx/svdopath.hxx>

//----------------------------------------------------------------------
SvxShapePolyPolygon::SvxShapePolyPolygon( SdrObject* pObj , drawing::PolygonKind eNew )
 throw( com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
: SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_POLYPOLYGON), aSvxMapProvider.GetPropertySet(SVXMAP_POLYPOLYGON, SdrObject::GetGlobalDrawObjectItemPool()) )
, mePolygonKind( eNew )
{
}

//----------------------------------------------------------------------
SvxShapePolyPolygon::~SvxShapePolyPolygon() throw()
{
}

basegfx::B2DPolyPolygon SAL_CALL ImplSvxPointSequenceSequenceToB2DPolyPolygon( const drawing::PointSequenceSequence* pOuterSequence) throw()
{
	basegfx::B2DPolyPolygon aRetval;

	// Zeiger auf innere sequences holen
	const drawing::PointSequence* pInnerSequence = pOuterSequence->getConstArray();
	const drawing::PointSequence* pInnerSeqEnd   = pInnerSequence + pOuterSequence->getLength();

	for(;pInnerSequence != pInnerSeqEnd; ++pInnerSequence)
	{
		// Neues Polygon vorbereiten
		basegfx::B2DPolygon aNewPolygon;

		// Zeiger auf Arrays holen
		const awt::Point* pArray	= pInnerSequence->getConstArray();
		const awt::Point* pArrayEnd = pArray + pInnerSequence->getLength();

		for(;pArray != pArrayEnd;++pArray)
		{
			aNewPolygon.append(basegfx::B2DPoint(pArray->X, pArray->Y));
		}

		// check for closed state flag
		basegfx::tools::checkClosed(aNewPolygon);

		// Neues Teilpolygon einfuegen
		aRetval.append(aNewPolygon);
	}

	return aRetval;
}

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

bool SvxShapePolyPolygon::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) 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)
{
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_POLYPOLYGON:
	{
		if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0) ) )
		{
			basegfx::B2DPolyPolygon aNewPolyPolygon(ImplSvxPointSequenceSequenceToB2DPolyPolygon( (drawing::PointSequenceSequence*)rValue.getValue()));
			SetPolygon(aNewPolyPolygon);
			return true;
		}
		break;
	}
	case OWN_ATTR_BASE_GEOMETRY:
	{
		if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0)))
		{
			if( mpObj.is() )
			{
				basegfx::B2DPolyPolygon aNewPolyPolygon;
				basegfx::B2DHomMatrix aNewHomogenMatrix;

				mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
				aNewPolyPolygon = ImplSvxPointSequenceSequenceToB2DPolyPolygon((drawing::PointSequenceSequence*)rValue.getValue());
				mpObj->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
			}
			return true;
		}
		break;
	}
	case OWN_ATTR_VALUE_POLYGON:
	{
		if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0) ))
		{
			drawing::PointSequence* pSequence = (drawing::PointSequence*)rValue.getValue();

			// Neues Polygon vorbereiten
			basegfx::B2DPolygon aNewPolygon;

			// Zeiger auf Arrays holen
			// Zeiger auf Arrays holen
			const awt::Point* pArray	= pSequence->getConstArray();
			const awt::Point* pArrayEnd = pArray + pSequence->getLength();

			for(;pArray != pArrayEnd;++pArray)
			{
				aNewPolygon.append(basegfx::B2DPoint(pArray->X, pArray->Y));
			}

			// check for closed state flag
			basegfx::tools::checkClosed(aNewPolygon);

			// Polygon setzen
			SetPolygon(basegfx::B2DPolyPolygon(aNewPolygon));
			return true;
		}
		break;
	}
	default:
        return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
	}

	throw lang::IllegalArgumentException();
}

void SAL_CALL B2DPolyPolygonToSvxPointSequenceSequence( const basegfx::B2DPolyPolygon& rPolyPoly, drawing::PointSequenceSequence& rRetval )
{
	if( (sal_uInt32)rRetval.getLength() != rPolyPoly.count() )
		rRetval.realloc( rPolyPoly.count() );

	// Zeiger auf aeussere Arrays holen
	drawing::PointSequence* pOuterSequence = rRetval.getArray();

	for(sal_uInt32 a(0L); a < rPolyPoly.count(); a++)
	{
		// Einzelpolygon holen
		const basegfx::B2DPolygon aPoly(rPolyPoly.getB2DPolygon(a));

		// #i75974# take closed stae into account, the API polygon still uses the old closed definition
		// with last/first point are identical (cannot hold information about open polygons with identical
		// first and last point, though)
		const sal_uInt32 nPointCount(aPoly.count());
		const bool bIsClosed(aPoly.isClosed());

		// Platz in Arrays schaffen
		pOuterSequence->realloc(bIsClosed ? nPointCount + 1 : nPointCount);

		// Pointer auf arrays holen
		awt::Point* pInnerSequence = pOuterSequence->getArray();

		for(sal_uInt32 b(0L); b < nPointCount; b++)
		{
			const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(b));
			*pInnerSequence = awt::Point( basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()) );
			pInnerSequence++;
		}

		// #i75974# copy first point
		if(bIsClosed)
		{
			*pInnerSequence = *pOuterSequence->getArray();
		}

		pOuterSequence++;
	}
}

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

bool SvxShapePolyPolygon::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_POLYPOLYGON:
	{
		// PolyPolygon in eine struct PolyPolygon packen
		const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();
		drawing::PointSequenceSequence aRetval( rPolyPoly.count() );

		B2DPolyPolygonToSvxPointSequenceSequence( rPolyPoly, aRetval );

		rValue <<= aRetval;
		break;
	}
	case OWN_ATTR_BASE_GEOMETRY:
	{
		// pack a PolyPolygon in struct PolyPolygon
		basegfx::B2DPolyPolygon aNewPolyPolygon;
		basegfx::B2DHomMatrix aNewHomogenMatrix;

		if(mpObj.is())
			mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);

		drawing::PointSequenceSequence aRetval(aNewPolyPolygon.count());
		B2DPolyPolygonToSvxPointSequenceSequence(aNewPolyPolygon, aRetval);
		rValue <<= aRetval;
		break;
	}
	case OWN_ATTR_VALUE_POLYGON:
	{
		// PolyPolygon in eine struct PolyPolygon packen
		const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();

		sal_Int32 nCount = 0;
		if( rPolyPoly.count() > 0 )
			nCount = rPolyPoly.getB2DPolygon(0L).count();

		drawing::PointSequence aRetval( nCount );

		if( nCount > 0 )
		{
			// Einzelpolygon holen
			const basegfx::B2DPolygon aPoly(rPolyPoly.getB2DPolygon(0L));

			// Pointer auf arrays holen
			awt::Point* pSequence = aRetval.getArray();

			for(sal_Int32 b=0;b<nCount;b++)
			{
				const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(b));
				*pSequence++ = awt::Point( basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()) );
			}
		}

		rValue <<= aRetval;
		break;
	}
	case OWN_ATTR_VALUE_POLYGONKIND:
	{
		rValue <<= GetPolygonKind();
		break;
	}
	default:
        return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
	}

	return true;
}

//----------------------------------------------------------------------
drawing::PolygonKind SvxShapePolyPolygon::GetPolygonKind() const throw()
{
	return mePolygonKind;
}

//----------------------------------------------------------------------
void SvxShapePolyPolygon::SetPolygon(const basegfx::B2DPolyPolygon& rNew) throw()
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
		((SdrPathObj*)mpObj.get())->SetPathPoly(rNew);
}

//----------------------------------------------------------------------
basegfx::B2DPolyPolygon SvxShapePolyPolygon::GetPolygon() const throw()
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
	{
		return ((SdrPathObj*)mpObj.get())->GetPathPoly();
	}
	else
	{
		return basegfx::B2DPolyPolygon();
	}
}

// ::com::sun::star::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL SvxShapePolyPolygon::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

/***********************************************************************
* class SvxShapePolyPolygonBezier                                      *
***********************************************************************/
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <com/sun/star/drawing/FlagSequence.hpp>
//----------------------------------------------------------------------
SvxShapePolyPolygonBezier::SvxShapePolyPolygonBezier( SdrObject* pObj , drawing::PolygonKind eNew ) throw()
:	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_POLYPOLYGONBEZIER), aSvxMapProvider.GetPropertySet(SVXMAP_POLYPOLYGONBEZIER, SdrObject::GetGlobalDrawObjectItemPool()) )
,	mePolygonKind( eNew )
{
}

//----------------------------------------------------------------------
SvxShapePolyPolygonBezier::~SvxShapePolyPolygonBezier() throw()
{
}

basegfx::B2DPolyPolygon SvxConvertPolyPolygonBezierToB2DPolyPolygon(const drawing::PolyPolygonBezierCoords* pSourcePolyPolygon)
	throw( IllegalArgumentException )
{
	const sal_Int32 nOuterSequenceCount(pSourcePolyPolygon->Coordinates.getLength());
	basegfx::B2DPolyPolygon aNewPolyPolygon;

	if(pSourcePolyPolygon->Flags.getLength() != nOuterSequenceCount)
	{
		throw IllegalArgumentException();
	}

	// get pointers to inner sequence
	const drawing::PointSequence* pInnerSequence = pSourcePolyPolygon->Coordinates.getConstArray();
	const drawing::FlagSequence* pInnerSequenceFlags = pSourcePolyPolygon->Flags.getConstArray();

	for(sal_Int32 a(0); a < nOuterSequenceCount; a++)
	{
		const sal_Int32 nInnerSequenceCount(pInnerSequence->getLength());

		if(pInnerSequenceFlags->getLength() != nInnerSequenceCount)
		{
			throw IllegalArgumentException();
		}

		// prepare new polygon
		basegfx::B2DPolygon aNewPolygon;
		const awt::Point* pArray = pInnerSequence->getConstArray();
		const drawing::PolygonFlags* pArrayFlags = pInnerSequenceFlags->getConstArray();

		// get first point and flag
		basegfx::B2DPoint aNewCoordinatePair(pArray->X, pArray->Y); pArray++;
		XPolyFlags ePolyFlag((XPolyFlags)((sal_uInt16)*pArrayFlags)); pArrayFlags++;
		basegfx::B2DPoint aControlA;
		basegfx::B2DPoint aControlB;

		// first point is not allowed to be a control point
		if(XPOLY_CONTROL == ePolyFlag)
		{
			throw IllegalArgumentException();
		}

		// add first point as start point
		aNewPolygon.append(aNewCoordinatePair);

		for(sal_Int32 b(1); b < nInnerSequenceCount;)
		{
			// prepare loop
			bool bControlA(false);
			bool bControlB(false);

			// get next point and flag
			aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
			ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
			pArray++; pArrayFlags++; b++;

			if(b < nInnerSequenceCount && XPOLY_CONTROL == ePolyFlag)
			{
				aControlA = aNewCoordinatePair;
				bControlA = true;

				// get next point and flag
				aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
				ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
				pArray++; pArrayFlags++; b++;
			}

			if(b < nInnerSequenceCount && XPOLY_CONTROL == ePolyFlag)
			{
				aControlB = aNewCoordinatePair;
				bControlB = true;

				// get next point and flag
				aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
				ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
				pArray++; pArrayFlags++; b++;
			}

			// two or no control points are consumed, another one would be an error.
			// It's also an error if only one control point was read
			if(XPOLY_CONTROL == ePolyFlag || bControlA != bControlB)
			{
				throw IllegalArgumentException();
			}

			// the previous writes used the B2DPolyPoygon -> PolyPolygon converter
			// which did not create minimal PolyPolygons, but created all control points
			// as null vectors (identical points). Because of the former P(CA)(CB)-norm of
			// B2DPolygon and it's unused sign of being the zero-vector and CA and CB being
			// relative to P, an empty edge was exported as P == CA == CB. Luckily, the new
			// export format can be read without errors by the old OOo-versions, so we need only
			// to correct here at read and do not need to export a wrong but compatible version
			// for the future.
			if(bControlA
				&& aControlA.equal(aControlB)
				&& aControlA.equal(aNewPolygon.getB2DPoint(aNewPolygon.count() - 1)))
			{
				bControlA = bControlB = false;
			}

			if(bControlA)
			{
				// add bezier edge
				aNewPolygon.appendBezierSegment(aControlA, aControlB, aNewCoordinatePair);
			}
			else
			{
				// add edge
				aNewPolygon.append(aNewCoordinatePair);
			}
		}

		// next sequence
		pInnerSequence++;
		pInnerSequenceFlags++;

		// #i72807# API import uses old line start/end-equal definition for closed,
		// so we need to correct this to closed state here
		basegfx::tools::checkClosed(aNewPolygon);

		// add new subpolygon
		aNewPolyPolygon.append(aNewPolygon);
	}

	return aNewPolyPolygon;
}

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

bool SvxShapePolyPolygonBezier::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) 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)
{
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
	{
		if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PolyPolygonBezierCoords*)0) ) )
		{
			basegfx::B2DPolyPolygon aNewPolyPolygon(SvxConvertPolyPolygonBezierToB2DPolyPolygon( (drawing::PolyPolygonBezierCoords*)rValue.getValue()));
			SetPolygon(aNewPolyPolygon);
			return true;
		}
		break;
	}
	case OWN_ATTR_BASE_GEOMETRY:
	{
		if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PolyPolygonBezierCoords*)0)) )
		{
			if( mpObj.is() )
			{
				basegfx::B2DPolyPolygon aNewPolyPolygon;
				basegfx::B2DHomMatrix aNewHomogenMatrix;

				mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
				aNewPolyPolygon = SvxConvertPolyPolygonBezierToB2DPolyPolygon((drawing::PolyPolygonBezierCoords*)rValue.getValue());
				mpObj->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
			}
			return true;
		}
		break;
	}
	default:
        return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
	}

	throw IllegalArgumentException();
}

void SvxConvertB2DPolyPolygonToPolyPolygonBezier( const basegfx::B2DPolyPolygon& rPolyPoly, drawing::PolyPolygonBezierCoords& rRetval )
{
	// use PolyPolygon converter as base. Since PolyPolygonBezierCoords uses
	// integer coordinates, this is no precision loss at all.
	const PolyPolygon aPolyPoly(rPolyPoly);

	// Polygone innerhalb vrobereiten
	rRetval.Coordinates.realloc((sal_Int32)aPolyPoly.Count());
	rRetval.Flags.realloc((sal_Int32)aPolyPoly.Count());

	// Zeiger auf aeussere Arrays holen
	drawing::PointSequence* pOuterSequence = rRetval.Coordinates.getArray();
	drawing::FlagSequence*  pOuterFlags = rRetval.Flags.getArray();

	for(sal_uInt16 a=0;a<aPolyPoly.Count();a++)
	{
		// Einzelpolygon holen
		const Polygon& rPoly = aPolyPoly[a];

		// Platz in Arrays schaffen
		pOuterSequence->realloc((sal_Int32)rPoly.GetSize());
		pOuterFlags->realloc((sal_Int32)rPoly.GetSize());

		// Pointer auf arrays holen
		awt::Point* pInnerSequence = pOuterSequence->getArray();
		drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray();

		for(sal_uInt16 b=0;b<rPoly.GetSize();b++)
		{
			*pInnerSequence++ = awt::Point( rPoly[b].X(), rPoly[b].Y() );
			*pInnerFlags++ = (drawing::PolygonFlags)((sal_uInt16)rPoly.GetFlags(b));
		}

		pOuterSequence++;
		pOuterFlags++;
	}
}

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

bool SvxShapePolyPolygonBezier::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
	{
		// PolyPolygon in eine struct PolyPolygon packen
		const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();
		drawing::PolyPolygonBezierCoords aRetval;
		SvxConvertB2DPolyPolygonToPolyPolygonBezier(rPolyPoly, aRetval );

		rValue <<= aRetval;
		break;
	}
	case OWN_ATTR_BASE_GEOMETRY:
	{
		// PolyPolygon in eine struct PolyPolygon packen
		basegfx::B2DPolyPolygon aNewPolyPolygon;
		basegfx::B2DHomMatrix aNewHomogenMatrix;
		mpObj.get()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
		drawing::PolyPolygonBezierCoords aRetval;
		SvxConvertB2DPolyPolygonToPolyPolygonBezier(aNewPolyPolygon, aRetval);

		rValue <<= aRetval;
		break;
	}
	case OWN_ATTR_VALUE_POLYGONKIND:
	{
		rValue <<= mePolygonKind;
		break;
	}
	default:
        return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
	}
	return true;
}

//----------------------------------------------------------------------
drawing::PolygonKind SvxShapePolyPolygonBezier::GetPolygonKind() const throw()
{
	return mePolygonKind;
}

//----------------------------------------------------------------------
void SvxShapePolyPolygonBezier::SetPolygon(const basegfx::B2DPolyPolygon& rNew) throw()
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
		static_cast<SdrPathObj*>(mpObj.get())->SetPathPoly(rNew);
}

//----------------------------------------------------------------------
basegfx::B2DPolyPolygon SvxShapePolyPolygonBezier::GetPolygon() const throw()
{
	OGuard aGuard( Application::GetSolarMutex() );

	if(mpObj.is())
	{
		return static_cast<SdrPathObj*>(mpObj.get())->GetPathPoly();
	}
	else
	{
		return basegfx::B2DPolyPolygon();
	}
}


// ::com::sun::star::lang::XServiceInfo
uno::Sequence< OUString > SAL_CALL SvxShapePolyPolygonBezier::getSupportedServiceNames() throw( uno::RuntimeException )
{
	return SvxShapeText::getSupportedServiceNames();
}

/***********************************************************************
* class SvxGraphicObject                                               *
***********************************************************************/
#include <com/sun/star/awt/XBitmap.hpp>
#include <vcl/cvtgrf.hxx>
#include <svx/svdograf.hxx>
#ifndef SVX_LIGHT
#ifndef _SFXDOCFILE_HXX
#include <sfx2/docfile.hxx>
#endif
#include <sfx2/linkmgr.hxx>
#include <sfx2/app.hxx>
#include <sfx2/fcontnr.hxx>
#endif

#include "toolkit/helper/vclunohelper.hxx"

//----------------------------------------------------------------------
SvxGraphicObject::SvxGraphicObject( SdrObject* pObj ) throw()
:	SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_GRAPHICOBJECT), aSvxMapProvider.GetPropertySet(SVXMAP_GRAPHICOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

//----------------------------------------------------------------------
SvxGraphicObject::~SvxGraphicObject() throw()
{
}

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

bool SvxGraphicObject::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) 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)
{
	bool bOk = false;
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_FILLBITMAP:
	{
		if( rValue.getValue() )
		{
			if( rValue.getValueType() == ::getCppuType(( const uno::Sequence< sal_Int8 >*)0) )
			{
				uno::Sequence<sal_Int8>* pSeq( (uno::Sequence<sal_Int8>*)rValue.getValue() );
				SvMemoryStream	aMemStm;
				Graphic			aGraphic;

				aMemStm.SetBuffer( (char*)pSeq->getConstArray(), pSeq->getLength(), sal_False, pSeq->getLength() );

				if( GraphicConverter::Import( aMemStm, aGraphic ) == ERRCODE_NONE )
				{
					static_cast<SdrGrafObj*>(mpObj.get())->SetGraphic(aGraphic);
					bOk = true;
				}
			}
		}
		else if( (rValue.getValueType() == awt::XBitmap::static_type()) || (rValue.getValueType() == graphic::XGraphic::static_type()))
		{
			Reference< graphic::XGraphic> xGraphic( rValue, UNO_QUERY );
			if( xGraphic.is() )
			{
				((SdrGrafObj*)mpObj.get())->SetGraphic(Graphic(xGraphic));
				bOk = true;
			}
			else
			{
				// Bitmap in das Objekt packen
				Reference< awt::XBitmap > xBmp( rValue, UNO_QUERY );
				if( xBmp.is() )
				{
					// Bitmap einsetzen
					Graphic aGraphic(VCLUnoHelper::GetBitmap( xBmp ));
					((SdrGrafObj*)mpObj.get())->SetGraphic(aGraphic);
					bOk = true;
				}
			}
		}
		break;
	}
	case OWN_ATTR_GRAFURL:
	{
		OUString aURL;
		if( rValue >>= aURL )
		{
			if( aURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 )
			{
				// graphic manager url
				aURL = aURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 );
				String aTmpStr(aURL);
				ByteString aUniqueID( aTmpStr, RTL_TEXTENCODING_UTF8 );
				GraphicObject aGrafObj( aUniqueID );

				// #101808# since loading a graphic can cause a reschedule of the office
				//			it is possible that our shape is removed while where in this
				//			method.
				if( mpObj.is() )
				{
					static_cast<SdrGrafObj*>(mpObj.get())->ReleaseGraphicLink();
					static_cast<SdrGrafObj*>(mpObj.get())->SetGraphicObject( aGrafObj );
				}
			}
			else if( aURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPKGPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPKGPREFIX ) ) != 0 )
			{
				// normal link
				String				aFilterName;
				const SfxFilter*	pSfxFilter = NULL;
				SfxMedium			aSfxMedium( aURL, STREAM_READ | STREAM_SHARE_DENYNONE, sal_False );

                // SfxFilterMatcher::GuessFilter() may ``taste'' linked files, so we must be sure we are authorized to access them
                sfx2::LinkManager *linkManager = NULL;
                if (mpModel) {
                    linkManager = mpModel->GetLinkManager();
                }
                if ( ( linkManager == NULL ) ||
                     ( !linkManager->urlIsVendor( aURL ) && linkManager->GetUserAllowsLinkUpdate( SFX_APP()->GetTopWindow() ) ) ) {
                    SFX_APP()->GetFilterMatcher().GuessFilter( aSfxMedium, &pSfxFilter, SFX_FILTER_IMPORT, SFX_FILTER_NOTINSTALLED | SFX_FILTER_EXECUTABLE );
                }

				if( !pSfxFilter )
				{
					INetURLObject aURLObj( aURL );

					if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
					{
						String aValidURL;

						if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aURL, aValidURL ) )
							aURLObj = INetURLObject( aValidURL );
					}

					if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
					{
						GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter();
						aFilterName = pGrfFilter->GetImportFormatName( pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
					}
				}
				else
					aFilterName = pSfxFilter->GetFilterName();

				// #101808# since loading a graphic can cause a reschedule of the office
				//			it is possible that our shape is removed while where in this
				//			method.
				if( mpObj.is() )
					static_cast<SdrGrafObj*>(mpObj.get())->SetGraphicLink( aURL, aFilterName );

			}
			bOk = true;
		}
		break;
	}

	case OWN_ATTR_GRAFSTREAMURL:
	{
		OUString aStreamURL;

		if( rValue >>= aStreamURL )
		{
			if( aStreamURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPKGPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPKGPREFIX ) ) != 0 )
				aStreamURL = OUString();

			if( mpObj.is() )
			{
				static_cast<SdrGrafObj*>(mpObj.get())->SetGrafStreamURL( aStreamURL );
				static_cast<SdrGrafObj*>(mpObj.get())->ForceSwapOut();
			}
			bOk = true;
		}
		break;
	}

	case OWN_ATTR_VALUE_GRAPHIC:
    {
		Reference< graphic::XGraphic > xGraphic( rValue, uno::UNO_QUERY );
		if( xGraphic.is() )
		{
	    	static_cast< SdrGrafObj*>( mpObj.get() )->SetGraphic( xGraphic );
			bOk = true;
		}
		break;
    }
	default:
        return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
	}

	if( !bOk )
		throw lang::IllegalArgumentException();

	if( mpModel )
		mpModel->SetChanged();

	return true;
}

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

bool SvxGraphicObject::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	switch( pProperty->nWID )
	{
	case OWN_ATTR_VALUE_FILLBITMAP:
	{
		sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
		const Graphic& rGraphic = static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphic();

		if(rGraphic.GetType() != GRAPHIC_GDIMETAFILE)
		{
			// Objekt in eine Bitmap packen
			Reference< ::com::sun::star::awt::XBitmap >  xBitmap( VCLUnoHelper::CreateBitmap(static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphic().GetBitmapEx()) );
			rValue <<= xBitmap;
		}
		else
		{
			SvMemoryStream aDestStrm( 65535, 65535 );

			ConvertGDIMetaFileToWMF( rGraphic.GetGDIMetaFile(), aDestStrm, NULL, sal_False );
            const uno::Sequence<sal_Int8> aSeq(
                static_cast< const sal_Int8* >(aDestStrm.GetData()),
                aDestStrm.GetEndOfData());
			rValue <<= aSeq;
		}
		if ( bSwapped )
			static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
		break;
	}

	case OWN_ATTR_GRAFURL:
	{
		if( static_cast< SdrGrafObj*>( mpObj.get() )->IsLinkedGraphic() )
		{
			rValue <<= OUString( static_cast< SdrGrafObj*>( mpObj.get() )->GetFileName() );
		}
		else
		{
			sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
			const GraphicObject& rGrafObj = static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphicObject(true);
			OUString aURL( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
			aURL += OUString::createFromAscii( rGrafObj.GetUniqueID().GetBuffer() );
			rValue <<= aURL;
			if ( bSwapped )
				static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
		}
		break;
	}

	case OWN_ATTR_REPLACEMENTGRAFURL:
	{
		const GraphicObject* pGrafObj = static_cast< SdrGrafObj* >(mpObj.get())->GetReplacementGraphicObject();

        if(pGrafObj)
        {
			OUString aURL(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
			aURL += OUString::createFromAscii(pGrafObj->GetUniqueID().GetBuffer());
			rValue <<= aURL;
        }

		break;
	}

    case OWN_ATTR_GRAFSTREAMURL:
	{
		const OUString	aStreamURL( ( (SdrGrafObj*) mpObj.get() )->GetGrafStreamURL() );
		if( aStreamURL.getLength() )
			rValue <<= aStreamURL;
		break;
	}

	case OWN_ATTR_VALUE_GRAPHIC:
    {
		sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
        Reference< graphic::XGraphic > xGraphic( static_cast< SdrGrafObj* >( mpObj.get() )->GetGraphic().GetXGraphic() );
		rValue <<= xGraphic;
		if ( bSwapped )
			static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
		break;
    }

	case OWN_ATTR_GRAPHIC_STREAM:
	{
		rValue <<= static_cast< SdrGrafObj* >( mpObj.get() )->getInputStream();
		break;
	}
	default:
        return SvxShapeText::getPropertyValueImpl(rName, pProperty,rValue);
	}

	return true;
}

///////////////////////////////////////////////////////////////////////

SvxShapeCaption::SvxShapeCaption( SdrObject* pObj ) throw()
: SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CAPTION), aSvxMapProvider.GetPropertySet(SVXMAP_CAPTION, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

SvxShapeCaption::~SvxShapeCaption() throw()
{
}

/***********************************************************************
* class SvxCustomShape                                                   *
***********************************************************************/

SvxCustomShape::SvxCustomShape( SdrObject* pObj )  throw() :
	SvxShapeText( pObj, aSvxMapProvider.GetMap( SVXMAP_CUSTOMSHAPE ), aSvxMapProvider.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool()) )
{
}

//----------------------------------------------------------------------
SvxCustomShape::~SvxCustomShape() throw()
{
}

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

void SvxCustomShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
{
	SvxShapeText::Create( pNewObj, pNewPage );
}

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

uno::Any SAL_CALL SvxCustomShape::queryInterface( const uno::Type & rType )
	throw(uno::RuntimeException)
{
    return SvxShapeText::queryInterface( rType );
}

uno::Any SAL_CALL SvxCustomShape::queryAggregation( const uno::Type & rType )
	throw(uno::RuntimeException)
{
	::com::sun::star::uno::Any aReturn = SvxShapeText::queryAggregation( rType );
    if ( !aReturn.hasValue() )
		aReturn = ::cppu::queryInterface(rType, static_cast<drawing::XEnhancedCustomShapeDefaulter*>(this) );
	return aReturn;
}

void SAL_CALL SvxCustomShape::acquire() throw ( )
{
	SvxShapeText::acquire();
}

void SAL_CALL SvxCustomShape::release() throw ( )
{
	SvxShapeText::release();
}

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

uno::Sequence< uno::Type > SAL_CALL SvxCustomShape::getTypes()
	throw (uno::RuntimeException)
{
	return SvxShapeText::getTypes();
}

uno::Sequence< sal_Int8 > SAL_CALL SvxCustomShape::getImplementationId()
	throw (uno::RuntimeException)
{
	static uno::Sequence< sal_Int8 > aId;
	if( aId.getLength() == 0 )
	{
		aId.realloc( 16 );
		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
	}
	return aId;
}

// ::com::sun::star::drawing::XShape

//----------------------------------------------------------------------
OUString SAL_CALL SvxCustomShape::getShapeType()
	throw( uno::RuntimeException )
{
	return SvxShape::getShapeType();
}

//------------------------------------------------------------------1----
awt::Point SAL_CALL SvxCustomShape::getPosition() throw(uno::RuntimeException)
{
	OGuard aGuard( Application::GetSolarMutex() );
	if ( mpModel && mpObj.is() )
	{
		SdrAShapeObjGeoData aCustomShapeGeoData;
		((SdrObjCustomShape*)mpObj.get())->SaveGeoData( aCustomShapeGeoData );

		sal_Bool bMirroredX = sal_False;
		sal_Bool bMirroredY = sal_False;

		if ( mpObj.is() )
		{
			bMirroredX = ( ((SdrObjCustomShape*)mpObj.get())->IsMirroredX() );
			bMirroredY = ( ((SdrObjCustomShape*)mpObj.get())->IsMirroredY() );
		}
		// get aRect, this is the unrotated snaprect
		Rectangle aRect(((SdrObjCustomShape*)mpObj.get())->GetLogicRect());
		Rectangle aRectangle( aRect );

		if ( bMirroredX || bMirroredY )
		{	// we have to retrieve the unmirrored rect

			GeoStat aNewGeo( aCustomShapeGeoData.aGeo );
			if ( bMirroredX )
			{
				Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
				Rectangle aBoundRect( aPol.GetBoundRect() );

				Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
				Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
				sal_uInt16 i;
				sal_uInt16 nPntAnz=aPol.GetSize();
				for (i=0; i<nPntAnz; i++)
				{
					MirrorPoint(aPol[i],aRef1,aRef2);
				}
				// Polygon wenden und etwas schieben
				Polygon aPol0(aPol);
				aPol[0]=aPol0[1];
				aPol[1]=aPol0[0];
				aPol[2]=aPol0[3];
				aPol[3]=aPol0[2];
				aPol[4]=aPol0[1];
				Poly2Rect(aPol,aRectangle,aNewGeo);
			}
			if ( bMirroredY )
			{
				Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
				Rectangle aBoundRect( aPol.GetBoundRect() );

				Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
				Point aRef2( aRef1.X() + 1000, aRef1.Y() );
				sal_uInt16 i;
				sal_uInt16 nPntAnz=aPol.GetSize();
				for (i=0; i<nPntAnz; i++)
				{
					MirrorPoint(aPol[i],aRef1,aRef2);
				}
				// Polygon wenden und etwas schieben
				Polygon aPol0(aPol);
				aPol[0]=aPol0[1];
				aPol[1]=aPol0[0];
				aPol[2]=aPol0[3];
				aPol[3]=aPol0[2];
				aPol[4]=aPol0[1];
				Poly2Rect( aPol, aRectangle, aNewGeo );
			}
		}
		Point aPt( aRectangle.TopLeft() );

		if( mpModel->IsWriter() )
			aPt -= mpObj->GetAnchorPos();

		ForceMetricTo100th_mm(aPt);
		return ::com::sun::star::awt::Point( aPt.X(), aPt.Y() );
	}
	else
		return SvxShape::getPosition();
}

//----------------------------------------------------------------------
void SAL_CALL SvxCustomShape::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
{
	SvxShapeText::setPosition(Position);
}

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

awt::Size SAL_CALL SvxCustomShape::getSize() throw(uno::RuntimeException)
{
	return SvxShapeText::getSize();
}

//----------------------------------------------------------------------
void SAL_CALL SvxCustomShape::setSize( const awt::Size& rSize )
	throw(beans::PropertyVetoException, uno::RuntimeException)
{
	SvxShapeText::setSize( rSize );
}

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

//----------------------------------------------------------------------
void SAL_CALL SvxCustomShape::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
{
	OGuard aGuard( Application::GetSolarMutex() );
    SdrObject* pObject = mpObj.get();

    sal_Bool bCustomShapeGeometry = pObject && aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CustomShapeGeometry" ) );

	sal_Bool bMirroredX = sal_False;
	sal_Bool bMirroredY = sal_False;

	if ( bCustomShapeGeometry )
	{
		bMirroredX = ( ((SdrObjCustomShape*)pObject)->IsMirroredX() );
		bMirroredY = ( ((SdrObjCustomShape*)pObject)->IsMirroredY() );
	}

	SvxShape::setPropertyValue( aPropertyName, aValue );

	if ( bCustomShapeGeometry )
	{
		((SdrObjCustomShape*)pObject)->MergeDefaultAttributes(0);
		Rectangle aRect( pObject->GetSnapRect() );

		// #i38892#
		bool bNeedsMirrorX = ((SdrObjCustomShape*)pObject)->IsMirroredX() != bMirroredX;
		bool bNeedsMirrorY = ((SdrObjCustomShape*)pObject)->IsMirroredY() != bMirroredY;

		boost::scoped_ptr< SdrGluePointList > pListCopy;
		if( bNeedsMirrorX || bNeedsMirrorY )
		{
			const SdrGluePointList* pList = pObject->GetGluePointList();
			if( pList )
				pListCopy.reset( new SdrGluePointList(*pList) );
		}

        if ( bNeedsMirrorX )
		{
			Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
			Point aBottom( aTop.X(), aTop.Y() + 1000 );
			pObject->NbcMirror( aTop, aBottom );
			// NbcMirroring is flipping the current mirror state,
			// so we have to set the correct state again
   			((SdrObjCustomShape*)pObject)->SetMirroredX( bMirroredX ? sal_False : sal_True );
		}
		if ( bNeedsMirrorY )
		{
			Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
			Point aRight( aLeft.X() + 1000, aLeft.Y() );
			pObject->NbcMirror( aLeft, aRight );
			// NbcMirroring is flipping the current mirror state,
			// so we have to set the correct state again
   			((SdrObjCustomShape*)pObject)->SetMirroredY( bMirroredY ? sal_False : sal_True );
		}

		if( pListCopy )
		{
			SdrGluePointList* pNewList = const_cast< SdrGluePointList* >( pObject->GetGluePointList() );
			if(pNewList)
				*pNewList = *pListCopy;
		}
	}
}

bool SvxCustomShape::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	switch( pProperty->nWID )
	{
	case SDRATTR_ROTATEANGLE:
	{
		double fAngle = static_cast<SdrObjCustomShape*>(mpObj.get())->GetObjectRotation();
		fAngle *= 100;
		rValue <<= (sal_Int32)fAngle;
		return true;
	}
	default:
        return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
	}
}
//----------------------------------------------------------------------

void SvxCustomShape::createCustomShapeDefaults( const rtl::OUString& rValueType ) throw (::com::sun::star::uno::RuntimeException)
{
	((SdrObjCustomShape*)mpObj.get())->MergeDefaultAttributes( &rValueType );
}
