/**************************************************************
 *
 * 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 "SchXMLAxisContext.hxx"
#include "SchXMLChartContext.hxx"
#include "SchXMLTools.hxx"
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmlement.hxx>
#include <xmloff/xmlstyle.hxx>
#include <xmloff/prstylei.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>

#include <tools/debug.hxx>

#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
#include <com/sun/star/chart/ChartAxisPosition.hpp>
#include <com/sun/star/chart/ChartAxisType.hpp>
#include <com/sun/star/chart/TimeIncrement.hpp>
#include <com/sun/star/chart/TimeInterval.hpp>
#include <com/sun/star/chart/TimeUnit.hpp>
#include <com/sun/star/chart/XAxis.hpp>
#include <com/sun/star/chart/XAxisSupplier.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>

#include <com/sun/star/drawing/LineStyle.hpp>

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

using rtl::OUString;
using com::sun::star::uno::Reference;

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

static SvXMLEnumMapEntry aXMLAxisDimensionMap[] =
{
    { XML_X,  SCH_XML_AXIS_X  },
    { XML_Y,  SCH_XML_AXIS_Y  },
    { XML_Z,  SCH_XML_AXIS_Z  },
    { XML_TOKEN_INVALID, 0 }
};

static SvXMLEnumMapEntry aXMLAxisTypeMap[] =
{
    { XML_AUTO,  ::com::sun::star::chart::ChartAxisType::AUTOMATIC },
    { XML_TEXT,  ::com::sun::star::chart::ChartAxisType::CATEGORY },
    { XML_DATE,  ::com::sun::star::chart::ChartAxisType::DATE },
    { XML_TOKEN_INVALID, 0 }
};

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

class SchXMLCategoriesContext : public SvXMLImportContext
{
private:
	SchXMLImportHelper& m_rImportHelper;
	OUString& mrAddress;

public:
	SchXMLCategoriesContext( SchXMLImportHelper& rImpHelper,
								   SvXMLImport& rImport,
								   sal_uInt16 nPrefix,
								   const OUString& rLocalName,
								   OUString& rAddress );
	virtual ~SchXMLCategoriesContext();
	virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

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


class DateScaleContext : public SvXMLImportContext
{
public:
	DateScaleContext( SchXMLImportHelper& rImpHelper, SvXMLImport& rImport,
                        sal_uInt16 nPrefix, const OUString& rLocalName,
                        const Reference< beans::XPropertySet > xAxisProps );

	virtual ~DateScaleContext();
	virtual void StartElement( const Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );

private:
	SchXMLImportHelper& m_rImportHelper;
	Reference< beans::XPropertySet > m_xAxisProps;
};


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

SchXMLAxisContext::SchXMLAxisContext( SchXMLImportHelper& rImpHelper,
									  SvXMLImport& rImport, const OUString& rLocalName,
									  Reference< chart::XDiagram > xDiagram,
									  std::vector< SchXMLAxis >& rAxes,
                                      OUString & rCategoriesAddress,
                                      bool bAddMissingXAxisForNetCharts,
                                      bool bAdaptWrongPercentScaleValues,
                                      bool bAdaptXAxisOrientationForOld2DBarCharts,
                                      bool& rbAxisPositionAttributeImported ) :
		SvXMLImportContext( rImport, XML_NAMESPACE_CHART, rLocalName ),
		m_rImportHelper( rImpHelper ),
		m_xDiagram( xDiagram ),
		m_rAxes( rAxes ),
        m_rCategoriesAddress( rCategoriesAddress ),
        m_nAxisType(chart::ChartAxisType::AUTOMATIC),
        m_bAxisTypeImported(false),
        m_bDateScaleImported(false),
        m_bAddMissingXAxisForNetCharts( bAddMissingXAxisForNetCharts ),
        m_bAdaptWrongPercentScaleValues( bAdaptWrongPercentScaleValues ),
        m_bAdaptXAxisOrientationForOld2DBarCharts( bAdaptXAxisOrientationForOld2DBarCharts ),
        m_rbAxisPositionAttributeImported( rbAxisPositionAttributeImported )
{
}

SchXMLAxisContext::~SchXMLAxisContext()
{}

Reference< chart::XAxis > lcl_getChartAxis( SchXMLAxis aCurrentAxis, const Reference< chart::XDiagram > xDiagram )
{
    Reference< chart::XAxis > xAxis;
    Reference< chart::XAxisSupplier > xAxisSuppl( xDiagram, uno::UNO_QUERY );
    if( !xAxisSuppl.is() )
        return xAxis;
    if( aCurrentAxis.nAxisIndex == 0 )
        xAxis = xAxisSuppl->getAxis(aCurrentAxis.eDimension);
    else
        xAxis = xAxisSuppl->getSecondaryAxis(aCurrentAxis.eDimension);
    return xAxis;
}

/* returns a shape for the current axis's title. The property
   "Has...AxisTitle" is set to "True" to get the shape
 */
Reference< drawing::XShape > SchXMLAxisContext::getTitleShape()
{
	Reference< drawing::XShape > xResult;
    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xDiaProp.is() || !xAxis.is() )
        return xResult;

    rtl::OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
	{
		case SCH_XML_AXIS_X:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = OUString::createFromAscii( "HasXAxisTitle" );
            else
                aPropName = OUString::createFromAscii( "HasSecondaryXAxisTitle" );
    		break;
		case SCH_XML_AXIS_Y:
			if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = OUString::createFromAscii( "HasYAxisTitle" );
            else
                aPropName = OUString::createFromAscii( "HasSecondaryYAxisTitle" );
    		break;
		case SCH_XML_AXIS_Z:
            aPropName = OUString::createFromAscii( "HasZAxisTitle" );
        	break;
        case SCH_XML_AXIS_UNDEF:
            DBG_ERROR( "Invalid axis" );
            break;
	}
    xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );
    xResult = Reference< drawing::XShape >( xAxis->getAxisTitle(), uno::UNO_QUERY );
	return xResult;
}

void SchXMLAxisContext::CreateGrid( OUString sAutoStyleName, bool bIsMajor )
{
    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xDiaProp.is() || !xAxis.is() )
        return;

    rtl::OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
	{
		case SCH_XML_AXIS_X:
            if( bIsMajor )
                aPropName = OUString::createFromAscii("HasXAxisGrid");
            else
                aPropName = OUString::createFromAscii("HasXAxisHelpGrid");
			break;
		case SCH_XML_AXIS_Y:
			if( bIsMajor )
                aPropName = OUString::createFromAscii("HasYAxisGrid");
            else
                aPropName = OUString::createFromAscii("HasYAxisHelpGrid");
    		break;
		case SCH_XML_AXIS_Z:
            if( bIsMajor )
                aPropName = OUString::createFromAscii("HasZAxisGrid");
            else
                aPropName = OUString::createFromAscii("HasZAxisHelpGrid");
        	break;
        case SCH_XML_AXIS_UNDEF:
            DBG_ERROR( "Invalid axis" );
            break;
	}
    xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );

    Reference< beans::XPropertySet > xGridProp;
    if( bIsMajor )
        xGridProp = xAxis->getMajorGrid();
    else
        xGridProp = xAxis->getMinorGrid();

    // set properties
	if( xGridProp.is())
	{
        // the line color is black as default, in the model it is a light gray
        xGridProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LineColor" )),
                                     uno::makeAny( COL_BLACK ));
        if( sAutoStyleName.getLength())
        {
            const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext();
            if( pStylesCtxt )
            {
                const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
                    m_rImportHelper.GetChartFamilyID(), sAutoStyleName );

                if( pStyle && pStyle->ISA( XMLPropStyleContext ))
                    (( XMLPropStyleContext* )pStyle )->FillPropertySet( xGridProp );
            }
        }
    }
}

namespace
{
enum AxisAttributeTokens
{
    XML_TOK_AXIS_DIMENSION,
    XML_TOK_AXIS_NAME,
    XML_TOK_AXIS_STYLE_NAME,
    XML_TOK_AXIS_TYPE,
    XML_TOK_AXIS_TYPE_EXT
};

SvXMLTokenMapEntry aAxisAttributeTokenMap[] =
{
    { XML_NAMESPACE_CHART,      XML_DIMENSION,  XML_TOK_AXIS_DIMENSION      },
    { XML_NAMESPACE_CHART,      XML_NAME,       XML_TOK_AXIS_NAME           },
    { XML_NAMESPACE_CHART,      XML_STYLE_NAME, XML_TOK_AXIS_STYLE_NAME     },
    { XML_NAMESPACE_CHART,      XML_AXIS_TYPE,  XML_TOK_AXIS_TYPE           },
    { XML_NAMESPACE_CHART_EXT,  XML_AXIS_TYPE,  XML_TOK_AXIS_TYPE_EXT       },
    XML_TOKEN_MAP_END
};

class AxisAttributeTokenMap : public SvXMLTokenMap
{
public:
    AxisAttributeTokenMap(): SvXMLTokenMap( aAxisAttributeTokenMap ) {}
    virtual ~AxisAttributeTokenMap() {}
};

//a AxisAttributeTokenMap Singleton
struct theAxisAttributeTokenMap : public rtl::Static< AxisAttributeTokenMap, theAxisAttributeTokenMap > {};
}

void SchXMLAxisContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
{
	// parse attributes
	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
	SchXMLImport& rImport = ( SchXMLImport& )GetImport();
    const SvXMLTokenMap& rAttrTokenMap = theAxisAttributeTokenMap::get();

	for( sal_Int16 i = 0; i < nAttrCount; i++ )
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		OUString aValue = xAttrList->getValueByIndex( i );
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

		switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
		{
			case XML_TOK_AXIS_DIMENSION:
				{
					sal_uInt16 nEnumVal;
					if( rImport.GetMM100UnitConverter().convertEnum( nEnumVal, aValue, aXMLAxisDimensionMap ))
						m_aCurrentAxis.eDimension = ( SchXMLAxisDimension )nEnumVal;
				}
				break;
			case XML_TOK_AXIS_NAME:
				m_aCurrentAxis.aName = aValue;
				break;
            case XML_TOK_AXIS_TYPE:
            case XML_TOK_AXIS_TYPE_EXT:
                sal_uInt16 nEnumVal;
                if( rImport.GetMM100UnitConverter().convertEnum( nEnumVal, aValue, aXMLAxisTypeMap ))
                {
                    m_nAxisType = nEnumVal;
					m_bAxisTypeImported = true;
                }
                break;
			case XML_TOK_AXIS_STYLE_NAME:
				m_aAutoStyleName = aValue;
				break;
		}
	}

	// check for number of axes with same dimension
	m_aCurrentAxis.nAxisIndex = 0;
	sal_Int32 nNumOfAxes = m_rAxes.size();
	for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
	{
		if( m_rAxes[ nCurrent ].eDimension == m_aCurrentAxis.eDimension )
			m_aCurrentAxis.nAxisIndex++;
	}
    CreateAxis();
}
namespace
{

Reference< chart2::XAxis > lcl_getAxis( const Reference< frame::XModel >& xChartModel,
                                            sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
{
    Reference< chart2::XAxis > xAxis;

    try
    {
        Reference< chart2::XChartDocument > xChart2Document( xChartModel, uno::UNO_QUERY );
        if( xChart2Document.is() )
        {
            Reference< chart2::XDiagram > xDiagram( xChart2Document->getFirstDiagram());
            Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
            uno::Sequence< Reference< chart2::XCoordinateSystem > >
                aCooSysSeq( xCooSysCnt->getCoordinateSystems());
            sal_Int32 nCooSysIndex = 0;
            if( nCooSysIndex < aCooSysSeq.getLength() )
            {
                Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIndex] );
                if( xCooSys.is() && nDimensionIndex < xCooSys->getDimension() )
                {
                    const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
                    if( nAxisIndex <= nMaxAxisIndex )
                        xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
                }
            }
        }
    }
    catch( uno::Exception & )
	{
		DBG_ERROR( "Couldn't get axis" );
	}

    return xAxis;
}

bool lcl_divideBy100( uno::Any& rDoubleAny )
{
    bool bChanged = false;
    double fValue=0.0;
    if( (rDoubleAny>>=fValue) && (fValue!=0.0) )
    {
        fValue/=100.0;
        rDoubleAny = uno::makeAny(fValue);
        bChanged = true;
    }
    return bChanged;
}

bool lcl_AdaptWrongPercentScaleValues(chart2::ScaleData& rScaleData)
{
    bool bChanged = lcl_divideBy100( rScaleData.Minimum );
    bChanged = lcl_divideBy100( rScaleData.Maximum ) || bChanged;
    bChanged = lcl_divideBy100( rScaleData.Origin ) || bChanged;
    bChanged = lcl_divideBy100( rScaleData.IncrementData.Distance ) || bChanged;
    return bChanged;
}

}//end anonymous namespace

void SchXMLAxisContext::CreateAxis()
{
    m_rAxes.push_back( m_aCurrentAxis );

    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    if( !xDiaProp.is() )
        return;
    rtl::OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
	{
		case SCH_XML_AXIS_X:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = OUString::createFromAscii("HasXAxis");
            else
                aPropName = OUString::createFromAscii("HasSecondaryXAxis");
			break;
		case SCH_XML_AXIS_Y:
			if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = OUString::createFromAscii("HasYAxis");
            else
                aPropName = OUString::createFromAscii("HasSecondaryYAxis");
    		break;
		case SCH_XML_AXIS_Z:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = OUString::createFromAscii("HasXAxis");
            else
                aPropName = OUString::createFromAscii("HasSecondaryXAxis");
        	break;
        case SCH_XML_AXIS_UNDEF:
            DBG_ERROR( "Invalid axis" );
            break;
    }
    try
    {
        xDiaProp->setPropertyValue( aPropName, uno::makeAny(sal_True) );
    }
    catch( beans::UnknownPropertyException & )
    {
        DBG_ERROR( "Couldn't turn on axis" );
    }
    if( m_aCurrentAxis.eDimension==SCH_XML_AXIS_Z )
    {
        bool bSettingZAxisSuccedded = false;
        try
        {
            xDiaProp->getPropertyValue( aPropName ) >>= bSettingZAxisSuccedded;
        }
        catch( beans::UnknownPropertyException & )
        {
            DBG_ERROR( "Couldn't turn on z axis" );
        }
        if( !bSettingZAxisSuccedded )
            return;
    }


    m_xAxisProps = Reference<beans::XPropertySet>( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ), uno::UNO_QUERY );

    if( m_bAddMissingXAxisForNetCharts && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y && m_aCurrentAxis.nAxisIndex==0 )
    {
        try
        {
            xDiaProp->setPropertyValue( OUString::createFromAscii( "HasXAxis" ), uno::makeAny(sal_True) );
        }
        catch( beans::UnknownPropertyException & )
        {
            DBG_ERROR( "Couldn't turn on x axis" );
        }
    }

	// set properties
	if( m_xAxisProps.is())
	{
        uno::Any aTrueBool( uno::makeAny( sal_True ));
        uno::Any aFalseBool( uno::makeAny( sal_False ));

        // #i109879# the line color is black as default, in the model it is a light gray
        m_xAxisProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LineColor" )),
                                     uno::makeAny( COL_BLACK ));

        m_xAxisProps->setPropertyValue( OUString::createFromAscii( "DisplayLabels" ), aFalseBool );

        // #88077# AutoOrigin 'on' is default
        m_xAxisProps->setPropertyValue( OUString::createFromAscii( "AutoOrigin" ), aTrueBool );

        if( m_bAxisTypeImported )
            m_xAxisProps->setPropertyValue( OUString::createFromAscii( "AxisType" ), uno::makeAny(m_nAxisType) );

        if( m_aAutoStyleName.getLength())
        {
            const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext();
            if( pStylesCtxt )
            {
                const SvXMLStyleContext* pStyle = pStylesCtxt->FindStyleChildContext(
                    m_rImportHelper.GetChartFamilyID(), m_aAutoStyleName );

                if( pStyle && pStyle->ISA( XMLPropStyleContext ))
                {
                    // note: SvXMLStyleContext::FillPropertySet is not const
                    XMLPropStyleContext * pPropStyleContext = const_cast< XMLPropStyleContext * >( dynamic_cast< const XMLPropStyleContext * >( pStyle ));
                    if( pPropStyleContext )
                        pPropStyleContext->FillPropertySet( m_xAxisProps );

                    if( m_bAdaptWrongPercentScaleValues && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y )
                    {
                        //set scale data of added x axis back to default
                        Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
                                            m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
                        if( xAxis.is() )
                        {
                            chart2::ScaleData aScaleData( xAxis->getScaleData());
                            if( lcl_AdaptWrongPercentScaleValues(aScaleData) )
                                xAxis->setScaleData( aScaleData );
                        }
                    }

                    if( m_bAddMissingXAxisForNetCharts )
                    {
                        //copy style from y axis to added x axis:

                        Reference< chart::XAxisSupplier > xAxisSuppl( xDiaProp, uno::UNO_QUERY );
		                if( xAxisSuppl.is() )
                        {
                            Reference< beans::XPropertySet > xXAxisProp( xAxisSuppl->getAxis(0), uno::UNO_QUERY );
                            (( XMLPropStyleContext* )pStyle )->FillPropertySet( xXAxisProp );
                        }

                        //set scale data of added x axis back to default
                        Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
                                            0 /*nDimensionIndex*/, 0 /*nAxisIndex*/ ) );
                        if( xAxis.is() )
                        {
                            chart2::ScaleData aScaleData;
                            aScaleData.AxisType = chart2::AxisType::CATEGORY;
                            aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                            xAxis->setScaleData( aScaleData );
                        }

                        //set line style of added x axis to invisible
                        Reference< beans::XPropertySet > xNewAxisProp( xAxis, uno::UNO_QUERY );
                        if( xNewAxisProp.is() )
                        {
                            xNewAxisProp->setPropertyValue( OUString::createFromAscii("LineStyle")
                                , uno::makeAny(drawing::LineStyle_NONE));
                        }
                    }

                    if( m_bAdaptXAxisOrientationForOld2DBarCharts && m_aCurrentAxis.eDimension == SCH_XML_AXIS_X )
                    {
                        bool bIs3DChart = false;
                        if( xDiaProp.is() && ( xDiaProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Dim3D"))) >>= bIs3DChart )
                            && !bIs3DChart )
                        {
                            Reference< chart2::XChartDocument > xChart2Document( GetImport().GetModel(), uno::UNO_QUERY );
                            if( xChart2Document.is() )
                            {
                                Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xChart2Document->getFirstDiagram(), uno::UNO_QUERY );
                                if( xCooSysCnt.is() )
                                {
                                    uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
                                    if( aCooSysSeq.getLength() )
                                    {
                                        bool bSwapXandYAxis = false;
                                        Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] );
                                        Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
                                        if( xCooSysProp.is() && ( xCooSysProp->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("SwapXAndYAxis"))) >>= bSwapXandYAxis )
                                            && bSwapXandYAxis )
                                        {
                                            Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( 0, m_aCurrentAxis.nAxisIndex );
                                            if( xAxis.is() )
                                            {
                                                chart2::ScaleData aScaleData = xAxis->getScaleData();
                                                aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
                                                xAxis->setScaleData( aScaleData );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    m_rbAxisPositionAttributeImported = m_rbAxisPositionAttributeImported || SchXMLTools::getPropertyFromContext(
                        OUString(RTL_CONSTASCII_USTRINGPARAM("CrossoverPosition")), pPropStyleContext, pStylesCtxt ).hasValue();
                }
            }
        }
    }
}

void SchXMLAxisContext::SetAxisTitle()
{
    if( !m_aCurrentAxis.aTitle.getLength() )
        return;

    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xAxis.is() )
        return;

    Reference< beans::XPropertySet > xTitleProp( xAxis->getAxisTitle() );
    if( xTitleProp.is() )
    {
        try
        {
            xTitleProp->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "String" )), uno::makeAny(m_aCurrentAxis.aTitle) );
        }
        catch( beans::UnknownPropertyException & )
        {
            DBG_ERROR( "Property String for Title not available" );
        }
    }
}

//-----------------------------------------------------------------------
namespace
{
enum AxisChildTokens
{
    XML_TOK_AXIS_TITLE,
    XML_TOK_AXIS_CATEGORIES,
    XML_TOK_AXIS_GRID,
    XML_TOK_AXIS_DATE_SCALE,
    XML_TOK_AXIS_DATE_SCALE_EXT
};

SvXMLTokenMapEntry aAxisChildTokenMap[] =
{
    { XML_NAMESPACE_CHART,      XML_TITLE,              XML_TOK_AXIS_TITLE          },
	{ XML_NAMESPACE_CHART,      XML_CATEGORIES,         XML_TOK_AXIS_CATEGORIES     },
	{ XML_NAMESPACE_CHART,      XML_GRID,               XML_TOK_AXIS_GRID           },
    { XML_NAMESPACE_CHART,      XML_DATE_SCALE,         XML_TOK_AXIS_DATE_SCALE     },
    { XML_NAMESPACE_CHART_EXT,  XML_DATE_SCALE,         XML_TOK_AXIS_DATE_SCALE_EXT },
    XML_TOKEN_MAP_END
};

class AxisChildTokenMap : public SvXMLTokenMap
{
public:
    AxisChildTokenMap(): SvXMLTokenMap( aAxisChildTokenMap ) {}
    virtual ~AxisChildTokenMap() {}
};

//a AxisChildTokenMap Singleton
struct theAxisChildTokenMap : public rtl::Static< AxisChildTokenMap, theAxisChildTokenMap > {};
}

SvXMLImportContext* SchXMLAxisContext::CreateChildContext(
	sal_uInt16 p_nPrefix,
	const OUString& rLocalName,
	const Reference< xml::sax::XAttributeList >& xAttrList )
{
	SvXMLImportContext* pContext = 0;
    const SvXMLTokenMap& rTokenMap = theAxisChildTokenMap::get();

	switch( rTokenMap.Get( p_nPrefix, rLocalName ))
	{
		case XML_TOK_AXIS_TITLE:
        {
            Reference< drawing::XShape > xTitleShape = getTitleShape();
			pContext = new SchXMLTitleContext( m_rImportHelper, GetImport(), rLocalName,
											   m_aCurrentAxis.aTitle,
											   xTitleShape );
		}
        break;

        case XML_TOK_AXIS_CATEGORIES:
			pContext = new SchXMLCategoriesContext( m_rImportHelper, GetImport(),
														  p_nPrefix, rLocalName,
														  m_rCategoriesAddress );
            m_aCurrentAxis.bHasCategories = true;
			break;

        case XML_TOK_AXIS_DATE_SCALE:
        case XML_TOK_AXIS_DATE_SCALE_EXT:
            pContext = new DateScaleContext( m_rImportHelper, GetImport(),
                            p_nPrefix, rLocalName, m_xAxisProps );
            m_bDateScaleImported = true;
            break;

        case XML_TOK_AXIS_GRID:
		{
			sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
			bool bIsMajor = true;		// default value for class is "major"
			OUString sAutoStyleName;

			for( sal_Int16 i = 0; i < nAttrCount; i++ )
			{
				OUString sAttrName = xAttrList->getNameByIndex( i );
				OUString aLocalName;
				sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

				if( nPrefix == XML_NAMESPACE_CHART )
				{
					if( IsXMLToken( aLocalName, XML_CLASS ) )
					{
						if( IsXMLToken( xAttrList->getValueByIndex( i ), XML_MINOR ) )
							bIsMajor = false;
					}
					else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
						sAutoStyleName = xAttrList->getValueByIndex( i );
				}
			}

			CreateGrid( sAutoStyleName, bIsMajor );

			// don't create a context => use default context. grid elements are empty
			pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
		}
        break;

        default:
			pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
            break;
    }

	return pContext;
}

void SchXMLAxisContext::EndElement()
{
    if( !m_bDateScaleImported && m_nAxisType==chart::ChartAxisType::AUTOMATIC )
    {
        Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
        if( xAxis.is() )
        {
            chart2::ScaleData aScaleData( xAxis->getScaleData());
            aScaleData.AutoDateAxis = false;//different default for older documents
            xAxis->setScaleData( aScaleData );
        }
    }

    SetAxisTitle();
}

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

namespace
{

Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem > xCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
{
    Reference< chart2::XAxis > xAxis;
    try
    {
        xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
    }
    catch( uno::Exception & )
    {
    }
    return xAxis;
}

} // anonymous namespace

void SchXMLAxisContext::CorrectAxisPositions( const Reference< chart2::XChartDocument >& xNewDoc,
                          const OUString& rChartTypeServiceName,
                          const OUString& rODFVersionOfFile,
                          bool bAxisPositionAttributeImported )
{
    if( ( !rODFVersionOfFile.getLength() || rODFVersionOfFile.equalsAscii("1.0")
        || rODFVersionOfFile.equalsAscii("1.1")
        || ( rODFVersionOfFile.equalsAscii("1.2") && !bAxisPositionAttributeImported ) ) )
    {
        try
        {
            Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
            uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
            if( aCooSysSeq.getLength() )
            {
                Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[0] );
                if( xCooSys.is() )
                {
                    Reference< chart2::XAxis > xMainXAxis = lcl_getAxis( xCooSys, 0, 0 );
                    Reference< chart2::XAxis > xMainYAxis = lcl_getAxis( xCooSys, 1, 0 );
                    //Reference< chart2::XAxis > xMajorZAxis = lcl_getAxis( xCooSys, 2, 0 );
                    Reference< chart2::XAxis > xSecondaryXAxis = lcl_getAxis( xCooSys, 0, 1 );
                    Reference< chart2::XAxis > xSecondaryYAxis = lcl_getAxis( xCooSys, 1, 1 );

                    Reference< beans::XPropertySet > xMainXAxisProp( xMainXAxis, uno::UNO_QUERY );
                    Reference< beans::XPropertySet > xMainYAxisProp( xMainYAxis, uno::UNO_QUERY );
                    Reference< beans::XPropertySet > xSecondaryXAxisProp( xSecondaryXAxis, uno::UNO_QUERY );
                    Reference< beans::XPropertySet > xSecondaryYAxisProp( xSecondaryYAxis, uno::UNO_QUERY );

                    if( xMainXAxisProp.is() && xMainYAxisProp.is() )
                    {
                        chart2::ScaleData aMainXScale = xMainXAxis->getScaleData();
                        if( 0 == rChartTypeServiceName.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ScatterChartType" ) ) )
                        {
                            xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) );
                            double fCrossoverValue = 0.0;
                            aMainXScale.Origin >>= fCrossoverValue;
                            xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverValue")
                                    , uno::makeAny( fCrossoverValue ) );

                            if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
                            {
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) );
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
                                if( xSecondaryYAxisProp.is() )
                                    xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
                            }
                            else
                            {
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) );
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
                                if( xSecondaryYAxisProp.is() )
                                    xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
                            }
                        }
                        else
                        {
                            if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
                            {
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
                                if( xSecondaryYAxisProp.is() )
                                    xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                        , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
                            }
                            else
                            {
                                xMainYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                    , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
                                if( xSecondaryYAxisProp.is() )
                                    xSecondaryYAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                        , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
                            }
                        }

                        chart2::ScaleData aMainYScale = xMainYAxis->getScaleData();
                        xMainXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_VALUE) );
                        double fCrossoverValue = 0.0;
                        aMainYScale.Origin >>= fCrossoverValue;
                        xMainXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverValue")
                                , uno::makeAny( fCrossoverValue ) );

                        if( aMainYScale.Orientation == chart2::AxisOrientation_REVERSE )
                        {
                            xMainXAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END) );
                            xMainXAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
                            if( xSecondaryXAxisProp.is() )
                                xSecondaryXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_START) );
                        }
                        else
                        {
                            xMainXAxisProp->setPropertyValue( OUString::createFromAscii("LabelPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START) );
                            xMainXAxisProp->setPropertyValue( OUString::createFromAscii("MarkPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS) );
                            if( xSecondaryXAxisProp.is() )
                                xSecondaryXAxisProp->setPropertyValue( OUString::createFromAscii("CrossoverPosition")
                                , uno::makeAny( ::com::sun::star::chart::ChartAxisPosition_END) );
                        }
                    }
                }
            }
        }
        catch( uno::Exception & )
        {
        }
    }
}

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

SchXMLCategoriesContext::SchXMLCategoriesContext(
	SchXMLImportHelper& rImpHelper,
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	OUString& rAddress ) :
		SvXMLImportContext( rImport, nPrefix, rLocalName ),
		m_rImportHelper( rImpHelper ),
		mrAddress( rAddress )
{
}

SchXMLCategoriesContext::~SchXMLCategoriesContext()
{
}

void SchXMLCategoriesContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
{
	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;

	for( sal_Int16 i = 0; i < nAttrCount; i++ )
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

		if( nPrefix == XML_NAMESPACE_TABLE &&
			IsXMLToken( aLocalName, XML_CELL_RANGE_ADDRESS ) )
		{
            Reference< chart2::XChartDocument > xNewDoc( GetImport().GetModel(), uno::UNO_QUERY );
			mrAddress = xAttrList->getValueByIndex( i );
		}
	}
}

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

DateScaleContext::DateScaleContext(
    SchXMLImportHelper& rImpHelper,
    SvXMLImport& rImport,
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference< beans::XPropertySet > xAxisProps ) :
        SvXMLImportContext( rImport, nPrefix, rLocalName ),
        m_rImportHelper( rImpHelper ),
        m_xAxisProps( xAxisProps )
{
}

DateScaleContext::~DateScaleContext()
{
}

namespace
{
enum DateScaleAttributeTokens
{
    XML_TOK_DATESCALE_BASE_TIME_UNIT,
    XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE,
    XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT,
    XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE,
    XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT
};

SvXMLTokenMapEntry aDateScaleAttributeTokenMap[] =
{
    { XML_NAMESPACE_CHART,  XML_BASE_TIME_UNIT,         XML_TOK_DATESCALE_BASE_TIME_UNIT  },
    { XML_NAMESPACE_CHART,  XML_MAJOR_INTERVAL_VALUE,   XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE  },
    { XML_NAMESPACE_CHART,  XML_MAJOR_INTERVAL_UNIT,    XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT  },
    { XML_NAMESPACE_CHART,  XML_MINOR_INTERVAL_VALUE,   XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE  },
    { XML_NAMESPACE_CHART,  XML_MINOR_INTERVAL_UNIT,    XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT  },
    XML_TOKEN_MAP_END
};

class DateScaleAttributeTokenMap : public SvXMLTokenMap
{
public:
    DateScaleAttributeTokenMap(): SvXMLTokenMap( aDateScaleAttributeTokenMap ) {}
    virtual ~DateScaleAttributeTokenMap() {}
};

struct theDateScaleAttributeTokenMap : public rtl::Static< DateScaleAttributeTokenMap, theDateScaleAttributeTokenMap > {};

sal_Int32 lcl_getTimeUnit( const OUString& rValue )
{
    sal_Int32 nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY;
    if( IsXMLToken( rValue, XML_DAYS ) )
        nTimeUnit = ::com::sun::star::chart::TimeUnit::DAY;
    else if( IsXMLToken( rValue, XML_MONTHS ) )
        nTimeUnit = ::com::sun::star::chart::TimeUnit::MONTH;
    else if( IsXMLToken( rValue, XML_YEARS ) )
        nTimeUnit = ::com::sun::star::chart::TimeUnit::YEAR;
    return nTimeUnit;
}

}

void DateScaleContext::StartElement( const Reference< xml::sax::XAttributeList >& xAttrList )
{
    if( !m_xAxisProps.is() )
        return;

    // parse attributes
	sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0;
	const SvXMLTokenMap& rAttrTokenMap = theDateScaleAttributeTokenMap::get();

    bool bSetNewIncrement=false;
    chart::TimeIncrement aIncrement;
    m_xAxisProps->getPropertyValue( OUString::createFromAscii( "TimeIncrement" )) >>= aIncrement;

	for( sal_Int16 i = 0; i < nAttrCount; i++ )
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		OUString aValue = xAttrList->getValueByIndex( i );
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );

		switch( rAttrTokenMap.Get( nPrefix, aLocalName ))
		{
            case XML_TOK_DATESCALE_BASE_TIME_UNIT:
                {
                    aIncrement.TimeResolution = uno::makeAny( lcl_getTimeUnit(aValue) );
                    bSetNewIncrement = true;
                }
                break;
            case XML_TOK_DATESCALE_MAJOR_INTERVAL_VALUE:
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MajorTimeInterval >>= aInterval;
                    SvXMLUnitConverter::convertNumber( aInterval.Number, aValue );
                    aIncrement.MajorTimeInterval = uno::makeAny(aInterval);
                    bSetNewIncrement = true;
                }
                break;
            case XML_TOK_DATESCALE_MAJOR_INTERVAL_UNIT:
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MajorTimeInterval >>= aInterval;
                    aInterval.TimeUnit = lcl_getTimeUnit(aValue);
                    aIncrement.MajorTimeInterval = uno::makeAny(aInterval);
                    bSetNewIncrement = true;
                }
                break;
            case XML_TOK_DATESCALE_MINOR_INTERVAL_VALUE:
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MinorTimeInterval >>= aInterval;
                    SvXMLUnitConverter::convertNumber( aInterval.Number, aValue );
                    aIncrement.MinorTimeInterval = uno::makeAny(aInterval);
                    bSetNewIncrement = true;
                }
                break;
            case XML_TOK_DATESCALE_MINOR_INTERVAL_UNIT:
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MinorTimeInterval >>= aInterval;
                    aInterval.TimeUnit = lcl_getTimeUnit(aValue);
                    aIncrement.MinorTimeInterval = uno::makeAny(aInterval);
                    bSetNewIncrement = true;
                }
                break;
		}
	}

    if( bSetNewIncrement )
        m_xAxisProps->setPropertyValue( OUString::createFromAscii( "TimeIncrement" ), uno::makeAny( aIncrement ) );
}

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