/**************************************************************
 * 
 * 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>
#include <xmloff/shapeimport.hxx>
#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,
    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, 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 = dynamic_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;
}
