/**************************************************************
 * 
 * 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 swich 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;
}

/** 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( 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;
}
