/**************************************************************
 *
 * 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 <com/sun/star/text/PositionLayoutDir.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>

#include "unointerfacetouniqueidentifiermapper.hxx"

#include <list>

#ifndef _XMLOFF_SHAPEIMPORT_HXX
#include <xmloff/shapeimport.hxx>
#endif
#include <xmloff/xmltkmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "ximpstyl.hxx"
#include "ximpshap.hxx"
#include "sdpropls.hxx"
#include <xmloff/xmlprmap.hxx>
#include "ximp3dscene.hxx"
#include "ximp3dobject.hxx"
#include "ximpgrp.hxx"
#include "ximplink.hxx"

#include <map>
#include <vector>

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::std;
using namespace ::com::sun::star;
using namespace ::xmloff::token;

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

struct ltint32
{
  bool operator()(const sal_Int32 p, sal_Int32 q) const
  {
    return p < q;
  }
};

typedef std::map<sal_Int32,com::sun::star::uno::Reference< com::sun::star::drawing::XShape >,ltint32> IdShapeMap;

struct ConnectionHint
{
	com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxConnector;
	sal_Bool  bStart;
	OUString aDestShapeId;
	sal_Int32 nDestGlueId;
};

struct XShapeCompareHelper
{
  bool operator()(com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x1,
				  com::sun::star::uno::Reference < com::sun::star::drawing::XShape > x2 ) const
  {
    return x1.get() < x2.get();
  }
};

/** this map store all glue point id mappings for shapes that had user defined glue points. This
	is needed because on insertion the glue points will get a new and unique id */
typedef std::map<sal_Int32,sal_Int32,ltint32> GluePointIdMap;
typedef std::map< com::sun::star::uno::Reference < com::sun::star::drawing::XShape >, GluePointIdMap, XShapeCompareHelper > ShapeGluePointsMap;

/** this struct is created for each startPage() call and stores information that is needed during
	import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there
	is a pointer so one can build up a stack of this structs */
struct XMLShapeImportPageContextImpl
{
	ShapeGluePointsMap		maShapeGluePointsMap;

	uno::Reference < drawing::XShapes > mxShapes;

	struct XMLShapeImportPageContextImpl* mpNext;
};

/** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */
struct XMLShapeImportHelperImpl
{
	// context for sorting shapes
	ShapeSortContext*			mpSortContext;

	IdShapeMap					maShapeIds;

	std::vector<ConnectionHint> maConnections;

	// #88546# possibility to switch progress bar handling on/off
	sal_Bool					mbHandleProgressBar;

	// stores the capability of the current model to create presentation shapes
	sal_Bool					mbIsPresentationShapesSupported;
};

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

XMLShapeImportHelper::XMLShapeImportHelper(
		SvXMLImport& rImporter,
		const uno::Reference< frame::XModel>& rModel,
		SvXMLImportPropertyMapper *pExtMapper )
:	mpPageContext(NULL),
	mxModel(rModel),

	mpPropertySetMapper(0L),
	mpPresPagePropsMapper(0L),
	mpStylesContext(0L),
	mpAutoStylesContext(0L),
	mpGroupShapeElemTokenMap(0L),
	mpFrameShapeElemTokenMap(0L),
	mp3DSceneShapeElemTokenMap(0L),
	mp3DObjectAttrTokenMap(0L),
	mp3DPolygonBasedAttrTokenMap(0L),
	mp3DCubeObjectAttrTokenMap(0L),
	mp3DSphereObjectAttrTokenMap(0L),
	mp3DSceneShapeAttrTokenMap(0L),
	mp3DLightAttrTokenMap(0L),
	mpPathShapeAttrTokenMap(0L),
	mpPolygonShapeAttrTokenMap(0L),
	msStartShape(RTL_CONSTASCII_USTRINGPARAM("StartShape")),
	msEndShape(RTL_CONSTASCII_USTRINGPARAM("EndShape")),
	msStartGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("StartGluePointIndex")),
	msEndGluePointIndex(RTL_CONSTASCII_USTRINGPARAM("EndGluePointIndex")),

	mrImporter( rImporter )
{
	mpImpl = new XMLShapeImportHelperImpl();
	mpImpl->mpSortContext = 0;

	// #88546# init to sal_False
	mpImpl->mbHandleProgressBar = sal_False;

	mpSdPropHdlFactory = new XMLSdPropHdlFactory( rModel, rImporter );

	// set lock to avoid deletion
	mpSdPropHdlFactory->acquire();

	// construct PropertySetMapper
	UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper(mpSdPropHdlFactory);
	mpPropertySetMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
	// set lock to avoid deletion
	mpPropertySetMapper->acquire();

	if( pExtMapper )
	{
		UniReference < SvXMLImportPropertyMapper > xExtMapper( pExtMapper );
		mpPropertySetMapper->ChainImportMapper( xExtMapper );
	}

	// chain text attributes
	mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter));
	mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter));

	// construct PresPagePropsMapper
	xMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLSDPresPageProps, mpSdPropHdlFactory);
	mpPresPagePropsMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
	if(mpPresPagePropsMapper)
	{
		// set lock to avoid deletion
		mpPresPagePropsMapper->acquire();
	}

	uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
	const OUString aSName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument") );
	mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService( aSName );
}

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

XMLShapeImportHelper::~XMLShapeImportHelper()
{
	DBG_ASSERT( mpImpl->maConnections.empty(), "XMLShapeImportHelper::restoreConnections() was not called!" );

	// cleanup factory, decrease refcount. Should lead to destruction.
	if(mpSdPropHdlFactory)
	{
		mpSdPropHdlFactory->release();
		mpSdPropHdlFactory = 0L;
	}

	// cleanup mapper, decrease refcount. Should lead to destruction.
	if(mpPropertySetMapper)
	{
		mpPropertySetMapper->release();
		mpPropertySetMapper = 0L;
	}

	// cleanup presPage mapper, decrease refcount. Should lead to destruction.
	if(mpPresPagePropsMapper)
	{
		mpPresPagePropsMapper->release();
		mpPresPagePropsMapper = 0L;
	}

	if(mpGroupShapeElemTokenMap) delete mpGroupShapeElemTokenMap;
	if(mpFrameShapeElemTokenMap) delete mpFrameShapeElemTokenMap;
/*
	if(mpShapeAttrTokenMap) delete mpShapeAttrTokenMap;
	if(mpRectShapeAttrTokenMap) delete mpRectShapeAttrTokenMap;
	if(mpLineShapeAttrTokenMap) delete mpLineShapeAttrTokenMap;
	if(mpEllipseShapeAttrTokenMap) delete mpEllipseShapeAttrTokenMap;
	if(mpTextBoxShapeAttrTokenMap) delete mpTextBoxShapeAttrTokenMap;
	if(mpControlShapeAttrTokenMap) delete mpControlShapeAttrTokenMap;
	if(mpPageShapeAttrTokenMap) delete mpPageShapeAttrTokenMap;
	if(mpGraphicObjectShapeAttrTokenMap) delete mpGraphicObjectShapeAttrTokenMap;
*/
	if(mpPolygonShapeAttrTokenMap) delete mpPolygonShapeAttrTokenMap;
	if(mpPathShapeAttrTokenMap) delete mpPathShapeAttrTokenMap;
	if(mp3DSceneShapeElemTokenMap) delete mp3DSceneShapeElemTokenMap;
	if(mp3DObjectAttrTokenMap) delete mp3DObjectAttrTokenMap;
	if(mp3DPolygonBasedAttrTokenMap) delete mp3DPolygonBasedAttrTokenMap;
	if(mp3DCubeObjectAttrTokenMap) delete mp3DCubeObjectAttrTokenMap;
	if(mp3DSphereObjectAttrTokenMap) delete mp3DSphereObjectAttrTokenMap;
	if(mp3DSceneShapeAttrTokenMap) delete mp3DSceneShapeAttrTokenMap;
	if(mp3DLightAttrTokenMap) delete mp3DLightAttrTokenMap;

	// Styles or AutoStyles context?
	if(mpStylesContext)
	{
		mpStylesContext->Clear();
		mpStylesContext->ReleaseRef();
	}

	if(mpAutoStylesContext)
	{
		mpAutoStylesContext->Clear();
		mpAutoStylesContext->ReleaseRef();
	}

	delete mpImpl;
}

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



const SvXMLTokenMap& XMLShapeImportHelper::GetGroupShapeElemTokenMap()
{
	if(!mpGroupShapeElemTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry aGroupShapeElemTokenMap[] =
{
	{ XML_NAMESPACE_DRAW,			XML_G,				XML_TOK_GROUP_GROUP			},
	{ XML_NAMESPACE_DRAW,			XML_RECT,			XML_TOK_GROUP_RECT			},
	{ XML_NAMESPACE_DRAW,			XML_LINE,			XML_TOK_GROUP_LINE			},
	{ XML_NAMESPACE_DRAW,			XML_CIRCLE,		    XML_TOK_GROUP_CIRCLE		},
	{ XML_NAMESPACE_DRAW,			XML_ELLIPSE,		XML_TOK_GROUP_ELLIPSE		},
	{ XML_NAMESPACE_DRAW,			XML_POLYGON,		XML_TOK_GROUP_POLYGON		},
	{ XML_NAMESPACE_DRAW,			XML_POLYLINE,		XML_TOK_GROUP_POLYLINE		},
	{ XML_NAMESPACE_DRAW,			XML_PATH,			XML_TOK_GROUP_PATH			},

	{ XML_NAMESPACE_DRAW,			XML_CONTROL,		XML_TOK_GROUP_CONTROL		},
	{ XML_NAMESPACE_DRAW,			XML_CONNECTOR,		XML_TOK_GROUP_CONNECTOR		},
	{ XML_NAMESPACE_DRAW,			XML_MEASURE,		XML_TOK_GROUP_MEASURE		},
	{ XML_NAMESPACE_DRAW,			XML_PAGE_THUMBNAIL, XML_TOK_GROUP_PAGE			},
	{ XML_NAMESPACE_DRAW,			XML_CAPTION,		XML_TOK_GROUP_CAPTION		},

	{ XML_NAMESPACE_CHART,			XML_CHART,			XML_TOK_GROUP_CHART			},
	{ XML_NAMESPACE_DR3D,			XML_SCENE,			XML_TOK_GROUP_3DSCENE		},

	{ XML_NAMESPACE_DRAW,			XML_FRAME, 			XML_TOK_GROUP_FRAME			},
	{ XML_NAMESPACE_DRAW,			XML_CUSTOM_SHAPE,	XML_TOK_GROUP_CUSTOM_SHAPE	},

	{ XML_NAMESPACE_DRAW,			XML_CUSTOM_SHAPE,	XML_TOK_GROUP_CUSTOM_SHAPE	},
	{ XML_NAMESPACE_OFFICE,			XML_ANNOTATION,		XML_TOK_GROUP_ANNOTATION	},
	{ XML_NAMESPACE_DRAW,			XML_A,				XML_TOK_GROUP_A				},

    XML_TOKEN_MAP_END
};

		mpGroupShapeElemTokenMap = new SvXMLTokenMap(aGroupShapeElemTokenMap);
    } // if(!mpGroupShapeElemTokenMap)

	return *mpGroupShapeElemTokenMap;
}

const SvXMLTokenMap& XMLShapeImportHelper::GetFrameShapeElemTokenMap()
{
	if(!mpFrameShapeElemTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry aFrameShapeElemTokenMap[] =
{
	{ XML_NAMESPACE_DRAW,			XML_TEXT_BOX,		XML_TOK_FRAME_TEXT_BOX		},
	{ XML_NAMESPACE_DRAW,			XML_IMAGE,			XML_TOK_FRAME_IMAGE			},
	{ XML_NAMESPACE_DRAW,			XML_OBJECT,		    XML_TOK_FRAME_OBJECT		},
	{ XML_NAMESPACE_DRAW,			XML_OBJECT_OLE,	    XML_TOK_FRAME_OBJECT_OLE	},
	{ XML_NAMESPACE_DRAW,			XML_PLUGIN,		    XML_TOK_FRAME_PLUGIN		},
	{ XML_NAMESPACE_DRAW,			XML_FLOATING_FRAME, XML_TOK_FRAME_FLOATING_FRAME},
	{ XML_NAMESPACE_DRAW,			XML_APPLET,		    XML_TOK_FRAME_APPLET		},
	{ XML_NAMESPACE_TABLE,			XML_TABLE,			XML_TOK_FRAME_TABLE			},
	XML_TOKEN_MAP_END
};

		mpFrameShapeElemTokenMap = new SvXMLTokenMap(aFrameShapeElemTokenMap);
    } // if(!mpFrameShapeElemTokenMap)

	return *mpFrameShapeElemTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeElemTokenMap()
{
	if(!mp3DSceneShapeElemTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeElemTokenMap[] =
{
	{ XML_NAMESPACE_DR3D,			XML_SCENE,		XML_TOK_3DSCENE_3DSCENE		},
	{ XML_NAMESPACE_DR3D,			XML_CUBE,		XML_TOK_3DSCENE_3DCUBE		},
	{ XML_NAMESPACE_DR3D,			XML_SPHERE,	    XML_TOK_3DSCENE_3DSPHERE	},
	{ XML_NAMESPACE_DR3D,			XML_ROTATE,	    XML_TOK_3DSCENE_3DLATHE		},
	{ XML_NAMESPACE_DR3D,			XML_EXTRUDE,	XML_TOK_3DSCENE_3DEXTRUDE	},
	XML_TOKEN_MAP_END
};

		mp3DSceneShapeElemTokenMap = new SvXMLTokenMap(a3DSceneShapeElemTokenMap);
    } // if(!mp3DSceneShapeElemTokenMap)

	return *mp3DSceneShapeElemTokenMap;
}

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

const SvXMLTokenMap& XMLShapeImportHelper::GetShapeAttrTokenMap()
{
	if(!mpShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_DRAW,			XML_NAME,				XML_TOK_SHAPE_NAME							},
	{ XML_NAMESPACE_DRAW,			XML_STYLE_NAME,		    XML_TOK_SHAPE_DRAWSTYLE_NAME_GRAPHICS		},
	{ XML_NAMESPACE_PRESENTATION,	XML_CLASS,				XML_TOK_SHAPE_PRESENTATION_CLASS			},
	{ XML_NAMESPACE_PRESENTATION,	XML_STYLE_NAME,		    XML_TOK_SHAPE_DRAWSTYLE_NAME_PRESENTATION	},
	{ XML_NAMESPACE_SVG,			XML_TRANSFORM,			XML_TOK_SHAPE_TRANSFORM						},
	{ XML_NAMESPACE_PRESENTATION,	XML_PLACEHOLDER,		XML_TOK_SHAPE_IS_PLACEHOLDER				},
	{ XML_NAMESPACE_PRESENTATION,	XML_USER_TRANSFORMED,	XML_TOK_SHAPE_IS_USER_TRANSFORMED			},
	XML_TOKEN_MAP_END
};

		mpShapeAttrTokenMap = new SvXMLTokenMap(aShapeAttrTokenMap);
        }

	return *mpShapeAttrTokenMap;
}
*/
//////////////////////////////////////////////////////////////////////////////


const SvXMLTokenMap& XMLShapeImportHelper::Get3DObjectAttrTokenMap()
{
	if(!mp3DObjectAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DObjectAttrTokenMap[] =
{
	{ XML_NAMESPACE_DRAW,			XML_STYLE_NAME,		    XML_TOK_3DOBJECT_DRAWSTYLE_NAME		},
	{ XML_NAMESPACE_DR3D,			XML_TRANSFORM,			XML_TOK_3DOBJECT_TRANSFORM			},
	XML_TOKEN_MAP_END
};

		mp3DObjectAttrTokenMap = new SvXMLTokenMap(a3DObjectAttrTokenMap);
    } // if(!mp3DObjectAttrTokenMap)

	return *mp3DObjectAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::Get3DPolygonBasedAttrTokenMap()
{
	if(!mp3DPolygonBasedAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DPolygonBasedAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,			XML_VIEWBOX,			XML_TOK_3DPOLYGONBASED_VIEWBOX		},
	{ XML_NAMESPACE_SVG,			XML_D,					XML_TOK_3DPOLYGONBASED_D			},
	XML_TOKEN_MAP_END
};

		mp3DPolygonBasedAttrTokenMap = new SvXMLTokenMap(a3DPolygonBasedAttrTokenMap);
    } // if(!mp3DPolygonBasedAttrTokenMap)

	return *mp3DPolygonBasedAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::Get3DCubeObjectAttrTokenMap()
{
	if(!mp3DCubeObjectAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DCubeObjectAttrTokenMap[] =
{
	{ XML_NAMESPACE_DR3D,			XML_MIN_EDGE,			XML_TOK_3DCUBEOBJ_MINEDGE	},
	{ XML_NAMESPACE_DR3D,			XML_MAX_EDGE,			XML_TOK_3DCUBEOBJ_MAXEDGE	},
	XML_TOKEN_MAP_END
};

		mp3DCubeObjectAttrTokenMap = new SvXMLTokenMap(a3DCubeObjectAttrTokenMap);
    } // if(!mp3DCubeObjectAttrTokenMap)

	return *mp3DCubeObjectAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::Get3DSphereObjectAttrTokenMap()
{
	if(!mp3DSphereObjectAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DSphereObjectAttrTokenMap[] =
{
	{ XML_NAMESPACE_DR3D,			XML_CENTER, 			XML_TOK_3DSPHEREOBJ_CENTER	},
	{ XML_NAMESPACE_DR3D,			XML_SIZE,				XML_TOK_3DSPHEREOBJ_SIZE	},
	XML_TOKEN_MAP_END
};

		mp3DSphereObjectAttrTokenMap = new SvXMLTokenMap(a3DSphereObjectAttrTokenMap);
    } // if(!mp3DSphereObjectAttrTokenMap)

	return *mp3DSphereObjectAttrTokenMap;
}

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

const SvXMLTokenMap& XMLShapeImportHelper::GetRectShapeAttrTokenMap()
{
	if(!mpRectShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aRectShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X,					XML_TOK_RECTSHAPE_X					},
	{ XML_NAMESPACE_SVG,	XML_Y,					XML_TOK_RECTSHAPE_Y					},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,				XML_TOK_RECTSHAPE_WIDTH				},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,			    XML_TOK_RECTSHAPE_HEIGHT			},
	{ XML_NAMESPACE_DRAW,	XML_CORNER_RADIUS,		XML_TOK_RECTSHAPE_CORNER_RADIUS		},
	XML_TOKEN_MAP_END
};

		mpRectShapeAttrTokenMap = new SvXMLTokenMap(aRectShapeAttrTokenMap);
        }

	return *mpRectShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::GetLineShapeAttrTokenMap()
{
	if(!mpLineShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aLineShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X1,             XML_TOK_LINESHAPE_X1				},
	{ XML_NAMESPACE_SVG,	XML_Y1,				XML_TOK_LINESHAPE_Y1				},
	{ XML_NAMESPACE_SVG,	XML_X2,				XML_TOK_LINESHAPE_X2				},
	{ XML_NAMESPACE_SVG,	XML_Y2,				XML_TOK_LINESHAPE_Y2				},
	XML_TOKEN_MAP_END
};

		mpLineShapeAttrTokenMap = new SvXMLTokenMap(aLineShapeAttrTokenMap);
        }

	return *mpLineShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::GetEllipseShapeAttrTokenMap()
{
	if(!mpEllipseShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aEllipseShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_RX,				XML_TOK_ELLIPSESHAPE_RX				},
	{ XML_NAMESPACE_SVG,	XML_RY,				XML_TOK_ELLIPSESHAPE_RY				},
	{ XML_NAMESPACE_SVG,	XML_CX,				XML_TOK_ELLIPSESHAPE_CX				},
	{ XML_NAMESPACE_SVG,	XML_CY,				XML_TOK_ELLIPSESHAPE_CY				},
	{ XML_NAMESPACE_SVG,	XML_R,				XML_TOK_ELLIPSESHAPE_R				},
	XML_TOKEN_MAP_END
};

		mpEllipseShapeAttrTokenMap = new SvXMLTokenMap(aEllipseShapeAttrTokenMap);
        }

	return *mpEllipseShapeAttrTokenMap;
}

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

const SvXMLTokenMap& XMLShapeImportHelper::GetPolygonShapeAttrTokenMap()
{
	if(!mpPolygonShapeAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry aPolygonShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_VIEWBOX,			XML_TOK_POLYGONSHAPE_VIEWBOX		},
	{ XML_NAMESPACE_DRAW,	XML_POINTS, 			XML_TOK_POLYGONSHAPE_POINTS			},
	XML_TOKEN_MAP_END
};

		mpPolygonShapeAttrTokenMap = new SvXMLTokenMap(aPolygonShapeAttrTokenMap);
    } // if(!mpPolygonShapeAttrTokenMap)

	return *mpPolygonShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::GetPathShapeAttrTokenMap()
{
	if(!mpPathShapeAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry aPathShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_VIEWBOX,			XML_TOK_PATHSHAPE_VIEWBOX			},
	{ XML_NAMESPACE_SVG,	XML_D,					XML_TOK_PATHSHAPE_D					},
	XML_TOKEN_MAP_END
};

		mpPathShapeAttrTokenMap = new SvXMLTokenMap(aPathShapeAttrTokenMap);
    } // if(!mpPathShapeAttrTokenMap)

	return *mpPathShapeAttrTokenMap;
}
/*
//////////////////////////////////////////////////////////////////////////////


const SvXMLTokenMap& XMLShapeImportHelper::GetTextBoxShapeAttrTokenMap()
{
	if(!mpTextBoxShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aTextBoxShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X,					XML_TOK_TEXTBOXSHAPE_X				},
	{ XML_NAMESPACE_SVG,	XML_Y,					XML_TOK_TEXTBOXSHAPE_Y				},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,				XML_TOK_TEXTBOXSHAPE_WIDTH			},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,			    XML_TOK_TEXTBOXSHAPE_HEIGHT			},
	XML_TOKEN_MAP_END
};

		mpTextBoxShapeAttrTokenMap = new SvXMLTokenMap(aTextBoxShapeAttrTokenMap);
        }

	return *mpTextBoxShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::GetControlShapeAttrTokenMap()
{
	if(!mpControlShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aControlShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X,					XML_TOK_CONTROLSHAPE_X				},
	{ XML_NAMESPACE_SVG,	XML_Y,					XML_TOK_CONTROLSHAPE_Y				},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,				XML_TOK_CONTROLSHAPE_WIDTH			},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,			    XML_TOK_CONTROLSHAPE_HEIGHT			},
	XML_TOKEN_MAP_END
};

		mpControlShapeAttrTokenMap = new SvXMLTokenMap(aControlShapeAttrTokenMap);
        }

	return *mpControlShapeAttrTokenMap;
}
*/
//////////////////////////////////////////////////////////////////////////////


const SvXMLTokenMap& XMLShapeImportHelper::Get3DSceneShapeAttrTokenMap()
{
	if(!mp3DSceneShapeAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DSceneShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_DR3D,	XML_TRANSFORM,			XML_TOK_3DSCENESHAPE_TRANSFORM		},
	{ XML_NAMESPACE_DR3D,	XML_VRP,				XML_TOK_3DSCENESHAPE_VRP			},
	{ XML_NAMESPACE_DR3D,	XML_VPN,				XML_TOK_3DSCENESHAPE_VPN			},
	{ XML_NAMESPACE_DR3D,	XML_VUP,				XML_TOK_3DSCENESHAPE_VUP			},
	{ XML_NAMESPACE_DR3D,	XML_PROJECTION,		    XML_TOK_3DSCENESHAPE_PROJECTION		},
	{ XML_NAMESPACE_DR3D,	XML_DISTANCE,			XML_TOK_3DSCENESHAPE_DISTANCE		},
	{ XML_NAMESPACE_DR3D,	XML_FOCAL_LENGTH,		XML_TOK_3DSCENESHAPE_FOCAL_LENGTH	},
	{ XML_NAMESPACE_DR3D,	XML_SHADOW_SLANT,		XML_TOK_3DSCENESHAPE_SHADOW_SLANT	},
	{ XML_NAMESPACE_DR3D,	XML_SHADE_MODE,		    XML_TOK_3DSCENESHAPE_SHADE_MODE		},
	{ XML_NAMESPACE_DR3D,	XML_AMBIENT_COLOR,		XML_TOK_3DSCENESHAPE_AMBIENT_COLOR	},
	{ XML_NAMESPACE_DR3D,	XML_LIGHTING_MODE,		XML_TOK_3DSCENESHAPE_LIGHTING_MODE	},
	XML_TOKEN_MAP_END
};

		mp3DSceneShapeAttrTokenMap = new SvXMLTokenMap(a3DSceneShapeAttrTokenMap);
    } // if(!mp3DSceneShapeAttrTokenMap)

	return *mp3DSceneShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::Get3DLightAttrTokenMap()
{
	if(!mp3DLightAttrTokenMap)
    {
        static __FAR_DATA SvXMLTokenMapEntry a3DLightAttrTokenMap[] =
{
	{ XML_NAMESPACE_DR3D,	XML_DIFFUSE_COLOR,		XML_TOK_3DLIGHT_DIFFUSE_COLOR		},
	{ XML_NAMESPACE_DR3D,	XML_DIRECTION,			XML_TOK_3DLIGHT_DIRECTION			},
	{ XML_NAMESPACE_DR3D,	XML_ENABLED,			XML_TOK_3DLIGHT_ENABLED				},
	{ XML_NAMESPACE_DR3D,	XML_SPECULAR,			XML_TOK_3DLIGHT_SPECULAR			},
	XML_TOKEN_MAP_END
};

		mp3DLightAttrTokenMap = new SvXMLTokenMap(a3DLightAttrTokenMap);
    } // if(!mp3DLightAttrTokenMap)

	return *mp3DLightAttrTokenMap;
}

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

const SvXMLTokenMap& XMLShapeImportHelper::GetPageShapeAttrTokenMap()
{
	if(!mpPageShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aPageShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X,					XML_TOK_PAGESHAPE_X				},
	{ XML_NAMESPACE_SVG,	XML_Y,					XML_TOK_PAGESHAPE_Y				},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,				XML_TOK_PAGESHAPE_WIDTH			},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,			    XML_TOK_PAGESHAPE_HEIGHT		},
	XML_TOKEN_MAP_END
};

		mpPageShapeAttrTokenMap = new SvXMLTokenMap(aPageShapeAttrTokenMap);
        }

	return *mpPageShapeAttrTokenMap;
}

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


const SvXMLTokenMap& XMLShapeImportHelper::GetGraphicObjectShapeAttrTokenMap()
{
	if(!mpGraphicObjectShapeAttrTokenMap)
    {
    static __FAR_DATA SvXMLTokenMapEntry aGraphicObjectShapeAttrTokenMap[] =
{
	{ XML_NAMESPACE_SVG,	XML_X,					XML_TOK_GOSHAPE_X					},
	{ XML_NAMESPACE_SVG,	XML_Y,					XML_TOK_GOSHAPE_Y					},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,				XML_TOK_GOSHAPE_WIDTH				},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT, 			XML_TOK_GOSHAPE_HEIGHT				},
	{ XML_NAMESPACE_XLINK,	XML_HREF,				XML_TOK_GOSHAPE_URL					},
	XML_TOKEN_MAP_END
};

		mpGraphicObjectShapeAttrTokenMap = new SvXMLTokenMap(aGraphicObjectShapeAttrTokenMap);
        }

	return *mpGraphicObjectShapeAttrTokenMap;
}
*/
//////////////////////////////////////////////////////////////////////////////

SvXMLShapeContext* XMLShapeImportHelper::Create3DSceneChildContext(
	SvXMLImport& rImport,
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes)
{
	SdXMLShapeContext *pContext = 0L;

	if(rShapes.is())
	{
		const SvXMLTokenMap& rTokenMap = Get3DSceneShapeElemTokenMap();
		switch(rTokenMap.Get(p_nPrefix, rLocalName))
		{
			case XML_TOK_3DSCENE_3DSCENE:
			{
				// dr3d:3dscene inside dr3d:3dscene context
				pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
				break;
			}
			case XML_TOK_3DSCENE_3DCUBE:
			{
				// dr3d:3dcube inside dr3d:3dscene context
				pContext = new SdXML3DCubeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
				break;
			}
			case XML_TOK_3DSCENE_3DSPHERE:
			{
				// dr3d:3dsphere inside dr3d:3dscene context
				pContext = new SdXML3DSphereObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
				break;
			}
			case XML_TOK_3DSCENE_3DLATHE:
			{
				// dr3d:3dlathe inside dr3d:3dscene context
				pContext = new SdXML3DLatheObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
				break;
			}
			case XML_TOK_3DSCENE_3DEXTRUDE:
			{
				// dr3d:3dextrude inside dr3d:3dscene context
				pContext = new SdXML3DExtrudeObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False);
				break;
			}
		}
	}

	// now parse the attribute list and call the child context for each unknown attribute
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 a(0); a < nAttrCount; a++)
	{
		const OUString& rAttrName = xAttrList->getNameByIndex(a);
		OUString aLocalName;
		sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
		const OUString aValue( xAttrList->getValueByIndex(a) );

		pContext->processAttribute( nPrefix, aLocalName, aValue );
	}

	return pContext;
}

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

void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext* pNew)
{
	mpStylesContext = pNew;
	mpStylesContext->AddRef();
}

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

void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext* pNew)
{
	mpAutoStylesContext = pNew;
	mpAutoStylesContext->AddRef();
}

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

SvXMLShapeContext* XMLShapeImportHelper::CreateGroupChildContext(
	SvXMLImport& rImport,
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    sal_Bool bTemporaryShape)
{
	SdXMLShapeContext *pContext = 0L;

	const SvXMLTokenMap& rTokenMap = GetGroupShapeElemTokenMap();
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;

	switch(rTokenMap.Get(p_nPrefix, rLocalName))
	{
		case XML_TOK_GROUP_GROUP:
		{
			// draw:g inside group context (RECURSIVE)
			pContext = new SdXMLGroupShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
			break;
		}
		case XML_TOK_GROUP_3DSCENE:
		{
			// dr3d:3dscene inside group context
			pContext = new SdXML3DSceneShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
			break;
		}
		case XML_TOK_GROUP_RECT:
		{
			// draw:rect inside group context
			pContext = new SdXMLRectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_LINE:
		{
			// draw:line inside group context
			pContext = new SdXMLLineShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CIRCLE:
		case XML_TOK_GROUP_ELLIPSE:
		{
			// draw:circle or draw:ellipse inside group context
			pContext = new SdXMLEllipseShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_POLYGON:
		case XML_TOK_GROUP_POLYLINE:
		{
			// draw:polygon or draw:polyline inside group context
			pContext = new SdXMLPolygonShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes,
				rTokenMap.Get(p_nPrefix, rLocalName) == XML_TOK_GROUP_POLYGON ? sal_True : sal_False, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_PATH:
		{
			// draw:path inside group context
			pContext = new SdXMLPathShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape);
			break;
		}
		case XML_TOK_GROUP_FRAME:
		{
			// text:text-box inside group context
			pContext = new SdXMLFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CONTROL:
		{
			// draw:control inside group context
			pContext = new SdXMLControlShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CONNECTOR:
		{
			// draw:connector inside group context
			pContext = new SdXMLConnectorShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_MEASURE:
		{
			// draw:measure inside group context
			pContext = new SdXMLMeasureShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_PAGE:
		{
			// draw:page inside group context
			pContext = new SdXMLPageShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CAPTION:
        case XML_TOK_GROUP_ANNOTATION:
		{
			// draw:caption inside group context
			pContext = new SdXMLCaptionShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CHART:
		{
			// chart:chart inside group context
			pContext = new SdXMLChartShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, bTemporaryShape );
			break;
		}
		case XML_TOK_GROUP_CUSTOM_SHAPE:
		{
			// draw:customshape
			pContext = new SdXMLCustomShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
 		case XML_TOK_GROUP_A:
 		{
 			return new SdXMLShapeLinkContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
 		}
		// add other shapes here...
		default:
			return new SvXMLShapeContext( rImport, p_nPrefix, rLocalName, bTemporaryShape );
	}

	// now parse the attribute list and call the child context for each unknown attribute
	for(sal_Int16 a(0); a < nAttrCount; a++)
	{
		const OUString& rAttrName = xAttrList->getNameByIndex(a);
		OUString aLocalName;
		sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
		const OUString aValue( xAttrList->getValueByIndex(a) );

		pContext->processAttribute( nPrefix, aLocalName, aValue );
	}

	return pContext;
}

// This method is called from SdXMLFrameContext to create children of drawe:frame
SvXMLShapeContext* XMLShapeImportHelper::CreateFrameChildContext(
	SvXMLImport& rImport,
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& rAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
	const uno::Reference< xml::sax::XAttributeList>& rFrameAttrList)
{
	SdXMLShapeContext *pContext = 0L;

	const SvXMLTokenMap& rTokenMap = GetFrameShapeElemTokenMap();

	SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList );
	if( rFrameAttrList.is() )
		pAttrList->AppendAttributeList( rFrameAttrList );
	uno::Reference < xml::sax::XAttributeList > xAttrList = pAttrList;


	switch(rTokenMap.Get(p_nPrefix, rLocalName))
	{
		case XML_TOK_FRAME_TEXT_BOX:
		{
			// text:text-box inside group context
			pContext = new SdXMLTextBoxShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		case XML_TOK_FRAME_IMAGE:
		{
			// office:image inside group context
			pContext = new SdXMLGraphicObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		case XML_TOK_FRAME_OBJECT:
		case XML_TOK_FRAME_OBJECT_OLE:
		{
			// draw:object or draw:object_ole
			pContext = new SdXMLObjectShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		case XML_TOK_FRAME_TABLE:
		{
			// draw:object or draw:object_ole
			if( rImport.IsTableShapeSupported() )
				pContext = new SdXMLTableShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes );
			break;

		}
		case XML_TOK_FRAME_PLUGIN:
		{
			// draw:plugin
			pContext = new SdXMLPluginShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		case XML_TOK_FRAME_FLOATING_FRAME:
		{
			// draw:floating-frame
			pContext = new SdXMLFloatingFrameShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		case XML_TOK_FRAME_APPLET:
		{
			// draw:applet
			pContext = new SdXMLAppletShapeContext( rImport, p_nPrefix, rLocalName, xAttrList, rShapes, sal_False );
			break;
		}
		// add other shapes here...
		default:
			break;
	}

	if( pContext )
	{
		// now parse the attribute list and call the child context for each unknown attribute
		sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
		for(sal_Int16 a(0); a < nAttrCount; a++)
		{
			const OUString& rAttrName = xAttrList->getNameByIndex(a);
			OUString aLocalName;
			sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
			const OUString aValue( xAttrList->getValueByIndex(a) );

			pContext->processAttribute( nPrefix, aLocalName, aValue );
		}
	}

	return pContext;
}

SvXMLImportContext *XMLShapeImportHelper::CreateFrameChildContext(
	SvXMLImportContext *pThisContext,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList>& xAttrList )
{
	SvXMLImportContext * pContext = NULL;

	SdXMLFrameShapeContext *pFrameContext = PTR_CAST( SdXMLFrameShapeContext, pThisContext );
	if( pFrameContext )
		pContext = pFrameContext->CreateChildContext( nPrefix, rLocalName, xAttrList );

	return pContext;
}


/** this function is called whenever the implementation classes like to add this new
	shape to the given XShapes.
*/
void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape,
									 const uno::Reference< xml::sax::XAttributeList >&,
									 uno::Reference< drawing::XShapes >& rShapes)
{
	if( rShape.is() && rShapes.is() )
	{
		// add new shape to parent
		rShapes->add( rShape );
	}
}

/** this function is called whenever the implementation classes have finished importing
	a shape to the given XShapes. The shape is already inserted into its XShapes and
	all properties and styles are set.
*/
void XMLShapeImportHelper::finishShape(
		com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >&,
		com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&)
{
    // --> OD 2004-08-10 #i28749#, #i36248# - set property <PositionLayoutDir>
    // to <PositionInHoriL2R>, if it exists and the import states that
    // the shape positioning attributes are in horizontal left-to-right
    // layout. This is the case for the OpenOffice.org file format.
    // This setting is done for Writer documents, because the property
    // only exists at service com::sun::star::text::Shape - the Writer
    // UNO service for shapes.
    // The value indicates that the positioning attributes are given
    // in horizontal left-to-right layout. The property is evaluated
    // during the first positioning of the shape in order to convert
    // the shape position given in the OpenOffice.org file format to
    // the one for the OASIS Open Office file format.
    uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
    if ( xPropSet.is() )
    {
        if ( mrImporter.IsShapePositionInHoriL2R() &&
             xPropSet->getPropertySetInfo()->hasPropertyByName(
                OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir"))) )
        {
            uno::Any aPosLayoutDir;
            aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
            xPropSet->setPropertyValue(
                OUString(RTL_CONSTASCII_USTRINGPARAM("PositionLayoutDir")),
                aPosLayoutDir );
        }
    }
    // <--
}

// helper functions for z-order sorting
struct ZOrderHint
{
	sal_Int32 nIs;
	sal_Int32 nShould;

	int operator<(const ZOrderHint& rComp) const { return nShould < rComp.nShould; }
};

class ShapeSortContext
{
public:
	uno::Reference< drawing::XShapes > mxShapes;
	list<ZOrderHint>			  maZOrderList;
	list<ZOrderHint>			  maUnsortedList;

	sal_Int32					  mnCurrentZ;
	ShapeSortContext*			  mpParentContext;
	const OUString				  msZOrder;

	ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext = NULL );

	void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
};

ShapeSortContext::ShapeSortContext( uno::Reference< drawing::XShapes >& rShapes, ShapeSortContext* pParentContext )
:	mxShapes( rShapes ), mnCurrentZ( 0 ), mpParentContext( pParentContext ),
	msZOrder(RTL_CONSTASCII_USTRINGPARAM("ZOrder"))
{
}

void ShapeSortContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
{
	uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
	uno::Reference< beans::XPropertySet > xPropSet;
	aAny >>= xPropSet;

	if( xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( msZOrder ) )
	{
		aAny <<= nDestPos;
		xPropSet->setPropertyValue( msZOrder, aAny );

		list<ZOrderHint>::iterator aIter = maZOrderList.begin();
		list<ZOrderHint>::iterator aEnd = maZOrderList.end();

		while( aIter != aEnd )
		{
			if( (*aIter).nIs < nSourcePos )
			{
				DBG_ASSERT( (*aIter).nIs >= nDestPos, "Shape sorting failed" );
				(*aIter).nIs++;
			}
			aIter++;
		}

		aIter = maUnsortedList.begin();
		aEnd = maUnsortedList.end();

		while( aIter != aEnd )
		{
			if( (*aIter).nIs < nSourcePos )
			{
				DBG_ASSERT( (*aIter).nIs >= nDestPos, "shape sorting failed" );
				(*aIter).nIs++;
			}
			aIter++;
		}
	}
}

void XMLShapeImportHelper::pushGroupForSorting( uno::Reference< drawing::XShapes >& rShapes )
{
	mpImpl->mpSortContext = new ShapeSortContext( rShapes, mpImpl->mpSortContext );
}

void XMLShapeImportHelper::popGroupAndSort()
{
	DBG_ASSERT( mpImpl->mpSortContext, "No context to sort!" );
	if( mpImpl->mpSortContext == NULL )
		return;

	try
	{
		list<ZOrderHint>& rZList = mpImpl->mpSortContext->maZOrderList;
		list<ZOrderHint>& rUnsortedList = mpImpl->mpSortContext->maUnsortedList;

		// sort shapes
		if( !rZList.empty() )
		{
			// only do something if we have shapes to sort

			// check if there are more shapes than inserted with ::shapeWithZIndexAdded()
			// This can happen if there where already shapes on the page before import
			// Since the writer may delete some of this shapes during import, we need
			// to do this here and not in our c'tor anymore

			// check if we have more shapes than we know of
			sal_Int32 nCount = mpImpl->mpSortContext->mxShapes->getCount();

			nCount -= rZList.size();
			nCount -= rUnsortedList.size();


			if( nCount > 0 )
			{
				// first update offsets of added shapes
				list<ZOrderHint>::iterator aIter( rZList.begin() );
				while( aIter != rZList.end() )
					(*aIter++).nIs += nCount;

				aIter = rUnsortedList.begin();
				while( aIter != rUnsortedList.end() )
					(*aIter++).nIs += nCount;

				// second add the already existing shapes in the unsorted list
				ZOrderHint aNewHint;

				do
				{
					nCount--;

					aNewHint.nIs = nCount;
					aNewHint.nShould = -1;

					rUnsortedList.insert(rUnsortedList.begin(), aNewHint);
				}
				while( nCount );
			}

			// sort z ordered shapes
			rZList.sort();

			// this is the current index, all shapes before that
			// index are finished
			sal_Int32 nIndex = 0;
			while( !rZList.empty() )
			{
				list<ZOrderHint>::iterator aIter( rZList.begin() );

				while( nIndex < (*aIter).nShould && !rUnsortedList.empty() )
				{
					ZOrderHint aGapHint( *rUnsortedList.begin() );
					rUnsortedList.pop_front();

					mpImpl->mpSortContext->moveShape( aGapHint.nIs, nIndex++ );
				}

				if( (*aIter).nIs != nIndex )
					mpImpl->mpSortContext->moveShape( (*aIter).nIs, nIndex );

				rZList.pop_front();
				nIndex++;
			}
		}
	}
	catch( uno::Exception& )
	{
		DBG_ERROR("exception while sorting shapes, sorting failed!");
	}

	// put parent on top and delete current context, were done
	ShapeSortContext* pContext = mpImpl->mpSortContext;
	mpImpl->mpSortContext = pContext->mpParentContext;
	delete pContext;
}

void XMLShapeImportHelper::shapeWithZIndexAdded( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >&, sal_Int32 nZIndex )
{
	if( mpImpl->mpSortContext)
	{
		ZOrderHint aNewHint;
		aNewHint.nIs = mpImpl->mpSortContext->mnCurrentZ++;
		aNewHint.nShould = nZIndex;

		if( nZIndex == -1 )
		{
			// don't care, so add to unsorted list
			mpImpl->mpSortContext->maUnsortedList.push_back(aNewHint);
		}
		else
		{
			// insert into sort list
			mpImpl->mpSortContext->maZOrderList.push_back(aNewHint);
		}
	}
}

void XMLShapeImportHelper::addShapeConnection( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rConnectorShape,
						 sal_Bool bStart,
						 const rtl::OUString& rDestShapeId,
						 sal_Int32 nDestGlueId )
{
	ConnectionHint aHint;
	aHint.mxConnector = rConnectorShape;
	aHint.bStart = bStart;
	aHint.aDestShapeId = rDestShapeId;
	aHint.nDestGlueId = nDestGlueId;

	mpImpl->maConnections.push_back( aHint );
}

void XMLShapeImportHelper::restoreConnections()
{
	if( !mpImpl->maConnections.empty() )
	{
		uno::Any aAny;

		const vector<ConnectionHint>::size_type nCount = mpImpl->maConnections.size();
		for( vector<ConnectionHint>::size_type i = 0; i < nCount; i++ )
		{
			ConnectionHint& rHint = mpImpl->maConnections[i];
			uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
			if( xConnector.is() )
			{
				// #86637# remember line deltas
				uno::Any aLine1Delta;
				uno::Any aLine2Delta;
				uno::Any aLine3Delta;
				OUString aStr1(RTL_CONSTASCII_USTRINGPARAM("EdgeLine1Delta"));
				OUString aStr2(RTL_CONSTASCII_USTRINGPARAM("EdgeLine2Delta"));
				OUString aStr3(RTL_CONSTASCII_USTRINGPARAM("EdgeLine3Delta"));
				aLine1Delta = xConnector->getPropertyValue(aStr1);
				aLine2Delta = xConnector->getPropertyValue(aStr2);
				aLine3Delta = xConnector->getPropertyValue(aStr3);

				// #86637# simply setting these values WILL force the connector to do
				// an new layout promptly. So the line delta values have to be rescued
				// and restored around connector changes.
				uno::Reference< drawing::XShape > xShape(
					mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
				if( xShape.is() )
				{
					aAny <<= xShape;
					xConnector->setPropertyValue( rHint.bStart ? msStartShape : msEndShape, aAny );

					sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId : getGluePointId( xShape, rHint.nDestGlueId );
					aAny <<= nGlueId;
					xConnector->setPropertyValue( rHint.bStart ? msStartGluePointIndex : msEndGluePointIndex, aAny );
				}

				// #86637# restore line deltas
				xConnector->setPropertyValue(aStr1, aLine1Delta );
				xConnector->setPropertyValue(aStr2, aLine2Delta );
				xConnector->setPropertyValue(aStr3, aLine3Delta );
			}
		}
		mpImpl->maConnections.clear();
	}
}

SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
{
	UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
	UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory );
	SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );

	// chain text attributes
	pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
	return pResult;
}

/** creates a shape property set mapper that can be used for non shape elements.
	Only current feature is that the ShapeUserDefinedAttributes property is not included in this one. */
SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateExternalShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
{
	UniReference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
	UniReference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, 1 );
	SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );

	// chain text attributes
	pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
	return pResult;
}

/** adds a mapping for a glue point identifier from an xml file to the identifier created after inserting
	the new glue point into the core. The saved mappings can be retrieved by getGluePointId() */
void XMLShapeImportHelper::addGluePointMapping( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
						  sal_Int32 nSourceId, sal_Int32 nDestinnationId )
{
	if( mpPageContext )
		mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
}

/** find mapping for given DestinationID. This allows to extract the original draw:id imported with a draw:glue-point */
sal_Int32 XMLShapeImportHelper::findGluePointMapping(
    const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape,
    sal_Int32 nDestinnationId ) const
{
    if( mpPageContext )
    {
        ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );

        if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
        {
            GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin();
            GluePointIdMap::iterator aShapeIdEnd  = (*aShapeIter).second.end();

            while ( aShapeIdIter != aShapeIdEnd )
            {
                if ( (*aShapeIdIter).second == nDestinnationId )
                {
                    return (*aShapeIdIter).first;
                }

                aShapeIdIter++;
            }
        }
    }

    return -1;
}

/** moves all current DestinationId's by n */
void XMLShapeImportHelper::moveGluePointMapping( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, const sal_Int32 n )
{
	if( mpPageContext )
	{
		ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
		if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
		{
			GluePointIdMap::iterator aShapeIdIter = (*aShapeIter).second.begin();
			GluePointIdMap::iterator aShapeIdEnd  = (*aShapeIter).second.end();
			while ( aShapeIdIter != aShapeIdEnd )
			{
				if ( (*aShapeIdIter).second != -1 )
					(*aShapeIdIter).second += n;
				aShapeIdIter++;
			}
		}
	}
}

/** retrieves a mapping for a glue point identifier from the current xml file to the identifier created after
	inserting the new glue point into the core. The mapping must be initialized first with addGluePointMapping() */
sal_Int32 XMLShapeImportHelper::getGluePointId( const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape, sal_Int32 nSourceId )
{
	if( mpPageContext )
	{
		ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
		if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
		{
			GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
			if( aIdIter != (*aShapeIter).second.end() )
				return (*aIdIter).second;
		}
	}

	return -1;
}

/** this method must be calling before the first shape is imported for the given page */
void XMLShapeImportHelper::startPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& rShapes )
{
	XMLShapeImportPageContextImpl* pOldContext = mpPageContext;
	mpPageContext = new XMLShapeImportPageContextImpl();
	mpPageContext->mpNext = pOldContext;
	mpPageContext->mxShapes = rShapes;
}

/** this method must be calling after the last shape is imported for the given page */
void XMLShapeImportHelper::endPage( com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >&
#ifdef DBG_UTIL
rShapes
#endif
)
{
	DBG_ASSERT( mpPageContext && (mpPageContext->mxShapes == rShapes), "wrong call to endPage(), no startPage called or wrong page" );
	if( NULL == mpPageContext )
		return;

	restoreConnections();

	XMLShapeImportPageContextImpl* pNextContext = mpPageContext->mpNext;
	delete mpPageContext;
	mpPageContext = pNextContext;
}

// #88546#
/** defines if the import should increment the progress bar or not */
void XMLShapeImportHelper::enableHandleProgressBar( sal_Bool bEnable )
{
	mpImpl->mbHandleProgressBar = bEnable;
}

sal_Bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const
{
	return mpImpl->mbHandleProgressBar;
}

/** queries the capability of the current model to create presentation shapes */
sal_Bool XMLShapeImportHelper::IsPresentationShapesSupported()
{
	return mpImpl->mbIsPresentationShapesSupported;
}

const rtl::Reference< XMLTableImport >& XMLShapeImportHelper::GetShapeTableImport()
{
	if( !mxShapeTableImport.is() )
	{
		rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrImporter.GetModel(), mrImporter ) );
		rtl::Reference< XMLPropertySetMapper > xPropertySetMapper( new XMLShapePropertySetMapper( xFactory.get() ) );
		mxShapeTableImport = new XMLTableImport( mrImporter, xPropertySetMapper, xFactory );
	}

	return mxShapeTableImport;
}

void SvXMLShapeContext::setHyperlink( const OUString& rHyperlink )
{
	msHyperlink = rHyperlink;
}
