/**************************************************************
 * 
 * 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 "SchXMLImport.hxx"
#include "SchXMLChartContext.hxx"
#include "contexts.hxx"
#include "XMLChartPropertySetMapper.hxx"
#include "SchXMLTools.hxx"

#include <tools/debug.hxx>
#include <rtl/ustrbuf.hxx>
// header for class ByteString
#include <tools/string.hxx>
#include <comphelper/processfactory.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlstyle.hxx>
#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>

#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>

#include <typeinfo>

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

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::rtl::OUStringToOString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;

namespace
{
Reference< uno::XComponentContext > lcl_getComponentContext()
{
    Reference< uno::XComponentContext > xContext;
    try
    {
        Reference< beans::XPropertySet > xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
        if( xFactProp.is())
            xFactProp->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext;
    }
    catch( uno::Exception& )
    {}

    return xContext;
}

class lcl_MatchesChartType : public ::std::unary_function< Reference< chart2::XChartType >, bool >
{
public:
    explicit lcl_MatchesChartType( const OUString & aChartTypeName ) :
            m_aChartTypeName( aChartTypeName )
    {}

    bool operator () ( const Reference< chart2::XChartType > & xChartType ) const
    {
        return (xChartType.is() &&
                xChartType->getChartType().equals( m_aChartTypeName ));
    }

private:
    OUString m_aChartTypeName;
};
} // anonymous namespace

/* ----------------------------------------
   TokenMaps for distinguishing different
   tokens in different contexts
   ----------------------------------------*/

// ----------------------------------------
// element maps
// ----------------------------------------







// ----------------------------------------
// attribute maps
// ----------------------------------------









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

SchXMLImportHelper::SchXMLImportHelper() :
		mpAutoStyles( 0 ),

		mpChartDocElemTokenMap( 0 ),
		mpTableElemTokenMap( 0 ),
		mpChartElemTokenMap( 0 ),
		mpPlotAreaElemTokenMap( 0 ),
		mpSeriesElemTokenMap( 0 ),

		mpChartAttrTokenMap( 0 ),
		mpPlotAreaAttrTokenMap( 0 ),
		mpAutoStyleAttrTokenMap( 0 ),
		mpCellAttrTokenMap( 0 ),
		mpSeriesAttrTokenMap( 0 ),
        mpRegEquationAttrTokenMap( 0 )
{
}

SchXMLImportHelper::~SchXMLImportHelper()
{
		// delete token maps
	if( mpChartDocElemTokenMap )
		delete mpChartDocElemTokenMap;
	if( mpTableElemTokenMap )
		delete mpTableElemTokenMap;
	if( mpChartElemTokenMap )
		delete mpChartElemTokenMap;
	if( mpPlotAreaElemTokenMap )
		delete mpPlotAreaElemTokenMap;
	if( mpSeriesElemTokenMap )
		delete mpSeriesElemTokenMap;

	if( mpChartAttrTokenMap )
		delete mpChartAttrTokenMap;
	if( mpPlotAreaAttrTokenMap )
		delete mpPlotAreaAttrTokenMap;
	if( mpAutoStyleAttrTokenMap )
		delete mpAutoStyleAttrTokenMap;
	if( mpCellAttrTokenMap )
		delete mpCellAttrTokenMap;
	if( mpSeriesAttrTokenMap )
		delete mpSeriesAttrTokenMap;
}

SvXMLImportContext* SchXMLImportHelper::CreateChartContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix, const OUString& rLocalName,
	const Reference< frame::XModel > xChartModel,
	const Reference< xml::sax::XAttributeList >& )
{
	SvXMLImportContext* pContext = 0;

	Reference< chart::XChartDocument > xDoc( xChartModel, uno::UNO_QUERY );
	if( xDoc.is())
	{
		mxChartDoc = xDoc;
		pContext = new SchXMLChartContext( *this, rImport, rLocalName );
	}
	else
	{
		DBG_ERROR( "No valid XChartDocument given as XModel" );
		pContext = new SvXMLImportContext( rImport, nPrefix, rLocalName );
	}

	return pContext;
}

/* ----------------------------------------
   get various token maps
   ----------------------------------------*/

const SvXMLTokenMap& SchXMLImportHelper::GetDocElemTokenMap()
{
	if( ! mpChartDocElemTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aDocElemTokenMap[] =
        {
	        { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES,	XML_TOK_DOC_AUTOSTYLES	},
	        { XML_NAMESPACE_OFFICE, XML_STYLES,			    XML_TOK_DOC_STYLES	},
	        { XML_NAMESPACE_OFFICE, XML_META, 				XML_TOK_DOC_META	},
	        { XML_NAMESPACE_OFFICE, XML_BODY, 				XML_TOK_DOC_BODY	},
	        XML_TOKEN_MAP_END
        };

		mpChartDocElemTokenMap = new SvXMLTokenMap( aDocElemTokenMap );
    } // if( ! mpChartDocElemTokenMap )

	return *mpChartDocElemTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetTableElemTokenMap()
{
	if( ! mpTableElemTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aTableElemTokenMap[] =
    {
	    { XML_NAMESPACE_TABLE,	XML_TABLE_HEADER_COLUMNS,	XML_TOK_TABLE_HEADER_COLS	},
	    { XML_NAMESPACE_TABLE,	XML_TABLE_COLUMNS,			XML_TOK_TABLE_COLUMNS		},
	    { XML_NAMESPACE_TABLE,	XML_TABLE_COLUMN,			XML_TOK_TABLE_COLUMN		},
	    { XML_NAMESPACE_TABLE,	XML_TABLE_HEADER_ROWS,		XML_TOK_TABLE_HEADER_ROWS	},
	    { XML_NAMESPACE_TABLE,	XML_TABLE_ROWS,			    XML_TOK_TABLE_ROWS 			},
	    { XML_NAMESPACE_TABLE,	XML_TABLE_ROW,				XML_TOK_TABLE_ROW 			},
	    XML_TOKEN_MAP_END
    };

		mpTableElemTokenMap = new SvXMLTokenMap( aTableElemTokenMap );
    } // if( ! mpTableElemTokenMap )

	return *mpTableElemTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetChartElemTokenMap()
{
	if( ! mpChartElemTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aChartElemTokenMap[] =
        {
	        { XML_NAMESPACE_CHART,	XML_PLOT_AREA,				XML_TOK_CHART_PLOT_AREA		},
	        { XML_NAMESPACE_CHART,	XML_TITLE,					XML_TOK_CHART_TITLE			},
	        { XML_NAMESPACE_CHART,	XML_SUBTITLE,				XML_TOK_CHART_SUBTITLE		},
	        { XML_NAMESPACE_CHART,	XML_LEGEND,				XML_TOK_CHART_LEGEND		},
	        { XML_NAMESPACE_TABLE,	XML_TABLE,					XML_TOK_CHART_TABLE			},
	        XML_TOKEN_MAP_END
        };

		mpChartElemTokenMap = new SvXMLTokenMap( aChartElemTokenMap );
    } // if( ! mpChartElemTokenMap )

	return *mpChartElemTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetPlotAreaElemTokenMap()
{
	if( ! mpPlotAreaElemTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aPlotAreaElemTokenMap[] =
{
    { XML_NAMESPACE_CHART_EXT,	XML_COORDINATE_REGION,		XML_TOK_PA_COORDINATE_REGION_EXT },
    { XML_NAMESPACE_CHART,	XML_COORDINATE_REGION,		XML_TOK_PA_COORDINATE_REGION },
	{ XML_NAMESPACE_CHART,	XML_AXIS,					XML_TOK_PA_AXIS				},
	{ XML_NAMESPACE_CHART,	XML_SERIES,				    XML_TOK_PA_SERIES			},
	{ XML_NAMESPACE_CHART,	XML_WALL,					XML_TOK_PA_WALL				},
	{ XML_NAMESPACE_CHART,	XML_FLOOR,					XML_TOK_PA_FLOOR			},
	{ XML_NAMESPACE_DR3D,	XML_LIGHT,					XML_TOK_PA_LIGHT_SOURCE		},
	{ XML_NAMESPACE_CHART,  XML_STOCK_GAIN_MARKER,      XML_TOK_PA_STOCK_GAIN       },
	{ XML_NAMESPACE_CHART,  XML_STOCK_LOSS_MARKER,      XML_TOK_PA_STOCK_LOSS       },
	{ XML_NAMESPACE_CHART,  XML_STOCK_RANGE_LINE,       XML_TOK_PA_STOCK_RANGE      },
	XML_TOKEN_MAP_END
};

		mpPlotAreaElemTokenMap = new SvXMLTokenMap( aPlotAreaElemTokenMap );
    } // if( ! mpPlotAreaElemTokenMap )

	return *mpPlotAreaElemTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetSeriesElemTokenMap()
{
	if( ! mpSeriesElemTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aSeriesElemTokenMap[] =
{
	{ XML_NAMESPACE_CHART,	XML_DATA_POINT,	      XML_TOK_SERIES_DATA_POINT       },
	{ XML_NAMESPACE_CHART,	XML_DOMAIN,		      XML_TOK_SERIES_DOMAIN	          },
    { XML_NAMESPACE_CHART,	XML_MEAN_VALUE,       XML_TOK_SERIES_MEAN_VALUE_LINE  },
    { XML_NAMESPACE_CHART,	XML_REGRESSION_CURVE, XML_TOK_SERIES_REGRESSION_CURVE },
    { XML_NAMESPACE_CHART,	XML_ERROR_INDICATOR,  XML_TOK_SERIES_ERROR_INDICATOR  },
	XML_TOKEN_MAP_END
};

		mpSeriesElemTokenMap = new SvXMLTokenMap( aSeriesElemTokenMap );
    } // if( ! mpSeriesElemTokenMap )

	return *mpSeriesElemTokenMap;
}

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

const SvXMLTokenMap& SchXMLImportHelper::GetChartAttrTokenMap()
{
	if( ! mpChartAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aChartAttrTokenMap[] =
{
    { XML_NAMESPACE_XLINK,  XML_HREF,                   XML_TOK_CHART_HREF          },
	{ XML_NAMESPACE_CHART,	XML_CLASS,					XML_TOK_CHART_CLASS			},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,					XML_TOK_CHART_WIDTH			},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,				    XML_TOK_CHART_HEIGHT		},
	{ XML_NAMESPACE_CHART,	XML_STYLE_NAME,			    XML_TOK_CHART_STYLE_NAME	},
    { XML_NAMESPACE_CHART,  XML_COLUMN_MAPPING,         XML_TOK_CHART_COL_MAPPING   },
    { XML_NAMESPACE_CHART,  XML_ROW_MAPPING,            XML_TOK_CHART_ROW_MAPPING   },
	XML_TOKEN_MAP_END
};

		mpChartAttrTokenMap = new SvXMLTokenMap( aChartAttrTokenMap );
    } // if( ! mpChartAttrTokenMap )

	return *mpChartAttrTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetPlotAreaAttrTokenMap()
{
	if( ! mpPlotAreaAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aPlotAreaAttrTokenMap[] =
{
    { XML_NAMESPACE_SVG,    XML_X,                      XML_TOK_PA_X                 },
    { XML_NAMESPACE_SVG,    XML_Y,                      XML_TOK_PA_Y                 },
    { XML_NAMESPACE_SVG,    XML_WIDTH,                  XML_TOK_PA_WIDTH             },
    { XML_NAMESPACE_SVG,    XML_HEIGHT,                 XML_TOK_PA_HEIGHT            },
    { XML_NAMESPACE_CHART,  XML_STYLE_NAME,             XML_TOK_PA_STYLE_NAME        },
    { XML_NAMESPACE_TABLE,  XML_CELL_RANGE_ADDRESS,     XML_TOK_PA_CHART_ADDRESS     },
    { XML_NAMESPACE_CHART,  XML_DATA_SOURCE_HAS_LABELS, XML_TOK_PA_DS_HAS_LABELS     },
    { XML_NAMESPACE_DR3D,   XML_TRANSFORM,              XML_TOK_PA_TRANSFORM         },
    { XML_NAMESPACE_DR3D,   XML_VRP,                    XML_TOK_PA_VRP               },
    { XML_NAMESPACE_DR3D,   XML_VPN,                    XML_TOK_PA_VPN               },
    { XML_NAMESPACE_DR3D,   XML_VUP,                    XML_TOK_PA_VUP               },
    { XML_NAMESPACE_DR3D,   XML_PROJECTION,             XML_TOK_PA_PROJECTION        },
    { XML_NAMESPACE_DR3D,   XML_DISTANCE,               XML_TOK_PA_DISTANCE          },
    { XML_NAMESPACE_DR3D,   XML_FOCAL_LENGTH,           XML_TOK_PA_FOCAL_LENGTH      },
    { XML_NAMESPACE_DR3D,   XML_SHADOW_SLANT,           XML_TOK_PA_SHADOW_SLANT      },
    { XML_NAMESPACE_DR3D,   XML_SHADE_MODE,             XML_TOK_PA_SHADE_MODE        },
    { XML_NAMESPACE_DR3D,   XML_AMBIENT_COLOR,          XML_TOK_PA_AMBIENT_COLOR     },
    { XML_NAMESPACE_DR3D,   XML_LIGHTING_MODE,          XML_TOK_PA_LIGHTING_MODE     },
    XML_TOKEN_MAP_END
};

		mpPlotAreaAttrTokenMap = new SvXMLTokenMap( aPlotAreaAttrTokenMap );
    } // if( ! mpPlotAreaAttrTokenMap )

	return *mpPlotAreaAttrTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetAutoStyleAttrTokenMap()
{
	if( ! mpAutoStyleAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aAutoStyleAttrTokenMap[] =
{
	{ XML_NAMESPACE_STYLE,	XML_FAMILY,				    XML_TOK_AS_FAMILY			},
	{ XML_NAMESPACE_STYLE,	XML_NAME,					XML_TOK_AS_NAME				},
	XML_TOKEN_MAP_END
};

		mpAutoStyleAttrTokenMap = new SvXMLTokenMap( aAutoStyleAttrTokenMap );
    } // if( ! mpAutoStyleAttrTokenMap )

	return *mpAutoStyleAttrTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetCellAttrTokenMap()
{
	if( ! mpCellAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aCellAttrTokenMap[] =
{
	{ XML_NAMESPACE_OFFICE,	XML_VALUE_TYPE,			    XML_TOK_CELL_VAL_TYPE		},
	{ XML_NAMESPACE_OFFICE,	XML_VALUE,					XML_TOK_CELL_VALUE			},
	XML_TOKEN_MAP_END
};

		mpCellAttrTokenMap = new SvXMLTokenMap( aCellAttrTokenMap );
    } // if( ! mpCellAttrTokenMap )

	return *mpCellAttrTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetSeriesAttrTokenMap()
{
	if( ! mpSeriesAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aSeriesAttrTokenMap[] =
{
	{ XML_NAMESPACE_CHART,	XML_VALUES_CELL_RANGE_ADDRESS,	XML_TOK_SERIES_CELL_RANGE	 },
	{ XML_NAMESPACE_CHART,	XML_LABEL_CELL_ADDRESS,         XML_TOK_SERIES_LABEL_ADDRESS },
	{ XML_NAMESPACE_CHART,	XML_ATTACHED_AXIS,				XML_TOK_SERIES_ATTACHED_AXIS },
	{ XML_NAMESPACE_CHART,	XML_STYLE_NAME, 				XML_TOK_SERIES_STYLE_NAME	 },
	{ XML_NAMESPACE_CHART,	XML_CLASS, 					    XML_TOK_SERIES_CHART_CLASS	 },
	XML_TOKEN_MAP_END
};

		mpSeriesAttrTokenMap = new SvXMLTokenMap( aSeriesAttrTokenMap );
    } // if( ! mpSeriesAttrTokenMap )

	return *mpSeriesAttrTokenMap;
}

const SvXMLTokenMap& SchXMLImportHelper::GetRegEquationAttrTokenMap()
{
	if( ! mpRegEquationAttrTokenMap )
    {
        static __FAR_DATA SvXMLTokenMapEntry aRegressionEquationAttrTokenMap[] =
{
    { XML_NAMESPACE_CHART,  XML_STYLE_NAME,             XML_TOK_REGEQ_STYLE_NAME         },
    { XML_NAMESPACE_CHART,  XML_DISPLAY_EQUATION,       XML_TOK_REGEQ_DISPLAY_EQUATION   },
    { XML_NAMESPACE_CHART,  XML_DISPLAY_R_SQUARE,       XML_TOK_REGEQ_DISPLAY_R_SQUARE   },
    { XML_NAMESPACE_SVG,    XML_X,                      XML_TOK_REGEQ_POS_X              },
    { XML_NAMESPACE_SVG,    XML_Y,                      XML_TOK_REGEQ_POS_Y              },
    XML_TOKEN_MAP_END
};

		mpRegEquationAttrTokenMap = new SvXMLTokenMap( aRegressionEquationAttrTokenMap );
    } // if( ! mpRegEquationAttrTokenMap )

	return *mpRegEquationAttrTokenMap;
}

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

//static
void SchXMLImportHelper::DeleteDataSeries(
                    const Reference< chart2::XDataSeries > & xSeries,
                    const Reference< chart2::XChartDocument > & xDoc )
{
    if( xDoc.is() )
    try
    {
        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
            xDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
            xCooSysCnt->getCoordinateSystems());
        
        sal_Int32 nCooSysIndex = 0;
        for( nCooSysIndex=0; nCooSysIndex<aCooSysSeq.getLength(); nCooSysIndex++ )
        {
            Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[ nCooSysIndex ], uno::UNO_QUERY_THROW );
            Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());

            sal_Int32 nChartTypeIndex = 0;
            for( nChartTypeIndex=0; nChartTypeIndex<aChartTypes.getLength(); nChartTypeIndex++ )
            {
                Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nChartTypeIndex], uno::UNO_QUERY_THROW );
                Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries());

                sal_Int32 nSeriesIndex = 0;
                for( nSeriesIndex=0; nSeriesIndex<aSeriesSeq.getLength(); nSeriesIndex++ )
                {
                    if( xSeries==aSeriesSeq[nSeriesIndex] )
                    {
                        xSeriesCnt->removeDataSeries(xSeries);
                        return;
                    }
                }
            }
        }
    }
    catch( uno::Exception & ex )
    {
        (void)ex; // avoid warning for pro build
        OSL_ENSURE( false, OUStringToOString(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
                        OUString::createFromAscii( typeid( ex ).name()) +
                        OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
                        ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
    }
}

// static
Reference< chart2::XDataSeries > SchXMLImportHelper::GetNewDataSeries(
    const Reference< chart2::XChartDocument > & xDoc,
    sal_Int32 nCoordinateSystemIndex,
    const OUString & rChartTypeName,
    bool bPushLastChartType /* = false */ )
{
    Reference< chart2::XDataSeries > xResult;
    if(!xDoc.is())
        return xResult;

    try
    {
        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
            xDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
        Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
            xCooSysCnt->getCoordinateSystems());
        Reference< uno::XComponentContext > xContext( lcl_getComponentContext());

        if( nCoordinateSystemIndex < aCooSysSeq.getLength())
        {
            Reference< chart2::XChartType > xCurrentType;
            {
                Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[ nCoordinateSystemIndex ], uno::UNO_QUERY_THROW );
                Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
                // find matching chart type group
                const Reference< chart2::XChartType > * pBegin = aChartTypes.getConstArray();
                const Reference< chart2::XChartType > * pEnd = pBegin + aChartTypes.getLength();
                const Reference< chart2::XChartType > * pIt =
                    ::std::find_if( pBegin, pEnd, lcl_MatchesChartType( rChartTypeName ));
                if( pIt != pEnd )
                    xCurrentType.set( *pIt );
                // if chart type is set at series and differs from current one,
                // create a new chart type
                if( !xCurrentType.is())
                {
                    xCurrentType.set(
                        xContext->getServiceManager()->createInstanceWithContext( rChartTypeName, xContext ),
                        uno::UNO_QUERY );
                    if( xCurrentType.is())
                    {
                        if( bPushLastChartType && aChartTypes.getLength())
                        {
                            sal_Int32 nIndex( aChartTypes.getLength() - 1 );
                            aChartTypes.realloc( aChartTypes.getLength() + 1 );
                            aChartTypes[ nIndex + 1 ] = aChartTypes[ nIndex ];
                            aChartTypes[ nIndex ] = xCurrentType;
                            xCTCnt->setChartTypes( aChartTypes );
                        }
                        else
                            xCTCnt->addChartType( xCurrentType );
                    }
                }
            }

            if( xCurrentType.is())
            {
                Reference< chart2::XDataSeriesContainer > xSeriesCnt( xCurrentType, uno::UNO_QUERY_THROW );
                Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries());

                if( xContext.is() )
                {
                    xResult.set(
                        xContext->getServiceManager()->createInstanceWithContext(
                            OUString::createFromAscii("com.sun.star.chart2.DataSeries"),
                            xContext ), uno::UNO_QUERY_THROW );
                }
                if( xResult.is() )
                    xSeriesCnt->addDataSeries( xResult );
            }
        }
    }
    catch( uno::Exception & ex )
    {
        (void)ex; // avoid warning for pro build
        OSL_ENSURE( false, OUStringToOString(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught. Type: " )) +
                        OUString::createFromAscii( typeid( ex ).name()) +
                        OUString( RTL_CONSTASCII_USTRINGPARAM( ", Message: " )) +
                        ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
    }
    return xResult;
}

// static
Reference< chart2::data::XLabeledDataSequence > SchXMLImportHelper::GetNewLabeledDataSequence()
{
    // @todo: remove this asap
    OSL_ENSURE( false, "Do not call this method" );
    Reference< chart2::data::XLabeledDataSequence >  xResult;
    // DO NOT USED -- DEPRECATED. Use SchXMLTools::GetNewLabeledDataSequence() instead
    return xResult;
}

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

// #110680#
SchXMLImport::SchXMLImport(
	const Reference< lang::XMultiServiceFactory >& xServiceFactory,
	sal_uInt16 nImportFlags ) :
        SvXMLImport( xServiceFactory, nImportFlags )
{
    GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
    GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);

    mbIsGraphicLoadOnDemandSupported = false;
}

// #110680#
SchXMLImport::SchXMLImport(
	const Reference< lang::XMultiServiceFactory >& xServiceFactory,
	Reference< frame::XModel > xModel,
	Reference< document::XGraphicObjectResolver >& rGrfContainer,
	sal_Bool /*bLoadDoc*/, sal_Bool bShowProgress )
:	SvXMLImport( xServiceFactory, xModel, rGrfContainer )
{
    GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
    GetNamespaceMap().Add( GetXMLToken(XML_NP_CHART_EXT), GetXMLToken(XML_N_CHART_EXT), XML_NAMESPACE_CHART_EXT);

	// get status indicator (if requested)
	if( bShowProgress )
	{
		Reference< frame::XController > xController( xModel->getCurrentController());
		if( xController.is())
		{
			Reference< frame::XFrame > xFrame( xController->getFrame());
			if( xFrame.is())
			{
				Reference< task::XStatusIndicatorSupplier > xFactory( xFrame, uno::UNO_QUERY );
				if( xFactory.is())
				{
					mxStatusIndicator = xFactory->getStatusIndicator();
				}
			}
		}
	}

	// add progress view
	if( mxStatusIndicator.is())
	{
		const OUString aText( RTL_CONSTASCII_USTRINGPARAM( "XML Import" ));
		mxStatusIndicator->start( aText, 100 );		// use percentage as values
	}
}

SchXMLImport::~SchXMLImport() throw ()
{
	// stop progress view
	if( mxStatusIndicator.is())
	{
		mxStatusIndicator->end();
		mxStatusIndicator->reset();
	}

    uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );
    if( xChartDoc.is() && xChartDoc->hasControllersLocked() )
        xChartDoc->unlockControllers();
}

// create the main context (subcontexts are created
// by the one created here)
SvXMLImportContext *SchXMLImport::CreateContext( sal_uInt16 nPrefix, const OUString& rLocalName,
	const Reference< xml::sax::XAttributeList >& xAttrList )
{
	SvXMLImportContext* pContext = 0;

	// accept <office:document>
	if( XML_NAMESPACE_OFFICE == nPrefix &&
		( IsXMLToken( rLocalName, XML_DOCUMENT_STYLES) ||
          IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT) ))
	{
		pContext = new SchXMLDocContext( maImportHelper, *this, nPrefix, rLocalName );
	} else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
		        ( IsXMLToken(rLocalName, XML_DOCUMENT) ||
		          (IsXMLToken(rLocalName, XML_DOCUMENT_META)
                   && (getImportFlags() & IMPORT_META) )) )
    {
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
            GetModel(), uno::UNO_QUERY);
        // mst@: right now, this seems to be not supported, so it is untested
        if (xDPS.is()) {
            uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
                mxServiceFactory->createInstance(
                    ::rtl::OUString::createFromAscii(
                        "com.sun.star.xml.dom.SAXDocumentBuilder")),
                    uno::UNO_QUERY_THROW);
            pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
                ? new SvXMLMetaDocumentContext(*this,
                            XML_NAMESPACE_OFFICE, rLocalName,
                            xDPS->getDocumentProperties(), xDocBuilder)
                // flat OpenDocument file format
                : new SchXMLFlatDocContext_Impl(
                            maImportHelper, *this, nPrefix, rLocalName,
                            xDPS->getDocumentProperties(), xDocBuilder);
        } else {
            pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
		        ? SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList )
                : new SchXMLDocContext( maImportHelper, *this,
                                        nPrefix, rLocalName );
        }
	} else {
		pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
	}

	return pContext;
}

SvXMLImportContext* SchXMLImport::CreateStylesContext(
    const OUString& rLocalName,
    const Reference<xml::sax::XAttributeList>& xAttrList )
{
    //#i103287# make sure that the version information is set before importing all the properties (especially stroke-opacity!)
    SchXMLTools::setBuildIDAtImportInfo( GetModel(), getImportInfo() );

    SvXMLStylesContext* pStylesCtxt =
        new SvXMLStylesContext( *(this), XML_NAMESPACE_OFFICE, rLocalName, xAttrList );

    // set context at base class, so that all auto-style classes are imported
    SetAutoStyles( pStylesCtxt );
    maImportHelper.SetAutoStylesContext( pStylesCtxt );

    return pStylesCtxt;
}

void SAL_CALL SchXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
	throw(lang::IllegalArgumentException, uno::RuntimeException)
{
    uno::Reference< chart2::XChartDocument > xOldDoc( GetModel(), uno::UNO_QUERY );
    if( xOldDoc.is() && xOldDoc->hasControllersLocked() )
        xOldDoc->unlockControllers();

    SvXMLImport::setTargetDocument( xDoc );

    //set data provider and number formatter
    // try to get an XDataProvider and set it
    // @todo: if we have our own data, we must not use the parent as data provider
    uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY );

    if( xChartDoc.is() )
    try
    {
        //prevent rebuild of view during load ( necesarry especially if loaded not via load api, which is the case for example if binary files are loaded )
        xChartDoc->lockControllers();

        uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
        uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
        bool bHasOwnData = true;
        if( xChild.is() && xDataReceiver.is())
        {
            Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
            if( xFact.is() )
            {
                //if the parent has a number formatter we will use the numberformatter of the parent
                Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xFact, uno::UNO_QUERY );
                xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );

                if ( !xChartDoc->getDataProvider().is() )
                {
                    const OUString aDataProviderServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.data.DataProvider"));
                    const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames());
                    const OUString * pBegin = aServiceNames.getConstArray();
                    const OUString * pEnd = pBegin + aServiceNames.getLength();
                    if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
                    {
                        Reference< chart2::data::XDataProvider > xProvider(
                            xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
                        if( xProvider.is())
                        {
                            xDataReceiver->attachDataProvider( xProvider );
                            bHasOwnData = false;
                        }
                    }
                }
                else
                    bHasOwnData = false;
            }
//             else we have no parent => we have our own data

            if( bHasOwnData && ! xChartDoc->hasInternalDataProvider() )
                xChartDoc->createInternalDataProvider( sal_False );
        }
    }
    catch( uno::Exception & rEx )
    {
#ifdef DBG_UTIL
		String aStr( rEx.Message );
		ByteString aBStr( aStr, RTL_TEXTENCODING_ASCII_US );
		DBG_ERROR1( "SchXMLChartContext::StartElement(): Exception caught: %s", aBStr.GetBuffer());
#else
        (void)rEx; // avoid warning for pro build
#endif
    }
}

// export components ========================================

// first version: everything comes from one storage

Sequence< OUString > SAL_CALL SchXMLImport_getSupportedServiceNames() throw()
{
	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisImporter" ) );
	const Sequence< OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

OUString SAL_CALL SchXMLImport_getImplementationName() throw()
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport" ) );
}

Reference< uno::XInterface > SAL_CALL SchXMLImport_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
{
	// #110680#
	// return (cppu::OWeakObject*)new SchXMLImport();
	return (cppu::OWeakObject*)new SchXMLImport(rSMgr);
}

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

// multiple storage version: one for content / styles / meta

Sequence< OUString > SAL_CALL SchXMLImport_Styles_getSupportedServiceNames() throw()
{
	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisStylesImporter" ) );
	const Sequence< OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

OUString SAL_CALL SchXMLImport_Styles_getImplementationName() throw()
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Styles" ) );
}

Reference< uno::XInterface > SAL_CALL SchXMLImport_Styles_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
{
	// #110680#
	// return (cppu::OWeakObject*)new SchXMLImport( IMPORT_STYLES );
	return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_STYLES );
}

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

Sequence< OUString > SAL_CALL SchXMLImport_Content_getSupportedServiceNames() throw()
{
	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisContentImporter" ) );
	const Sequence< OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

OUString SAL_CALL SchXMLImport_Content_getImplementationName() throw()
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Content" ) );
}

Reference< uno::XInterface > SAL_CALL SchXMLImport_Content_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
{
	// #110680#
	// return (cppu::OWeakObject*)new SchXMLImport( IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS );
	return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS );
}

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

Sequence< OUString > SAL_CALL SchXMLImport_Meta_getSupportedServiceNames() throw()
{
	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Chart.XMLOasisMetaImporter" ) );
	const Sequence< OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

OUString SAL_CALL SchXMLImport_Meta_getImplementationName() throw()
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SchXMLImport.Meta" ) );
}

Reference< uno::XInterface > SAL_CALL SchXMLImport_Meta_createInstance(const Reference< lang::XMultiServiceFactory > & rSMgr) throw( uno::Exception )
{
	// #110680#
	// return (cppu::OWeakObject*)new SchXMLImport( IMPORT_META );
	return (cppu::OWeakObject*)new SchXMLImport( rSMgr, IMPORT_META );
}

// XServiceInfo
OUString SAL_CALL SchXMLImport::getImplementationName() throw( uno::RuntimeException )
{
    switch( getImportFlags())
    {
        case IMPORT_ALL:
            return SchXMLImport_getImplementationName();
        case IMPORT_STYLES:
            return SchXMLImport_Styles_getImplementationName();
        case ( IMPORT_CONTENT | IMPORT_AUTOSTYLES | IMPORT_FONTDECLS ):
            return SchXMLImport_Content_getImplementationName();
        case IMPORT_META:
            return SchXMLImport_Meta_getImplementationName();

        case IMPORT_SETTINGS:
        // there is no settings component in chart
        default:
            return OUString::createFromAscii( "SchXMLImport" );
    }
}
