/**************************************************************
 *
 * 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_chart2.hxx"

#include "ChartDebugTrace.hxx"
#include "macros.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/chart2/AxisType.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/chart2/StackingDirection.hpp>
#include <rtl/math.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

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

#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL

namespace
{
/*
const char lcl_aSpace=' ';

void lcl_IndentedTrace( int nIndent, char* pStr )
{
    if( nIndent > 0 )
    {
        OSL_TRACE( "%*c%s", nIndent, lcl_aSpace, pStr );
    }
    else
    {
        OSL_TRACE( pStr );
    }
}

void lcl_TraceException( const uno::Exception & aEx )
{
    OSL_TRACE(
        U2C( C2U( "*** Exception caught during trace. Type: " ) +
             OUString::createFromAscii( typeid( aEx ).name()) +
             C2U( ", Message: " ) +
             aEx.Message ));
}

void lcl_TraceCategories( const Reference< data::XLabeledDataSequence > & xCat, int nIndent )
{
    if( ! xCat.is())
        return;
    try
    {
        Reference< data::XDataSequence > xValues( xCat->getValues());
        if( xValues.is())
        {
            OSL_TRACE( "%*ccategories: source: %s", nIndent, lcl_aSpace,
                       U2C( xValues->getSourceRangeRepresentation()));
        }
        Reference< data::XDataSequence > xLabel( xCat->getLabel());
        if( xLabel.is())
        {
            OSL_TRACE( "%*ccategories' label: source: %s", nIndent, lcl_aSpace,
                       U2C( xLabel->getSourceRangeRepresentation()));
        }
    }
    catch( uno::Exception & ex )
    {
        lcl_TraceException( ex );
    }
}

void lcl_TraceDataSeriesSeq( const Sequence< Reference< XDataSeries > > & aSeries, int nIndent )
{
    for( sal_Int32 j = 0; j < aSeries.getLength(); ++j )
    {
        Reference< beans::XPropertySet > xProp( aSeries[j], uno::UNO_QUERY );
        OUString aId;

        OSL_TRACE( "%*cindex %ld", nIndent, lcl_aSpace, j );

        StackingDirection aStDir;
        if( xProp.is() &&
            ( xProp->getPropertyValue( C2U( "StackingDirection" )) >>= aStDir ) &&
            aStDir != StackingDirection_NO_STACKING )
        {
            OSL_TRACE( "%*cstacking in %s", nIndent + 2, lcl_aSpace,
                       (aStDir == StackingDirection_Y_STACKING)
                       ? "y-direction" : "z-direction" );
        }

        Reference< data::XDataSource > xSource( aSeries[j], uno::UNO_QUERY );
        if( xSource.is())
        {
            Sequence< Reference< data::XLabeledDataSequence > > aSequences( xSource->getDataSequences());
            const sal_Int32 nMax = aSequences.getLength();
            for( sal_Int32 k = 0; k < nMax; ++k )
            {
                if( aSequences[k].is())
                {
                    OUString aSourceId(C2U("<none>"));
                    if( aSequences[k]->getValues().is())
                        aSourceId = aSequences[k]->getValues()->getSourceRangeRepresentation();
                    xProp.set( aSequences[k]->getValues(), uno::UNO_QUERY );
                    if( xProp.is() &&
                        ( xProp->getPropertyValue( C2U( "Role" )) >>= aId ))
                    {
                        OSL_TRACE( "%*cdata sequence %d: role: %s, source: %s",
                                   nIndent + 2, lcl_aSpace, k, U2C( aId ), U2C( aSourceId ));
                    }
                    else
                    {
                        OSL_TRACE( "%*cdata sequence %d, unknown role, source: %s",
                                   nIndent + 2, lcl_aSpace, k, U2C( aSourceId ) );
                    }

                    aSourceId = C2U("<none>");
                    if( aSequences[k]->getLabel().is())
                        aSourceId = OUString( aSequences[k]->getLabel()->getSourceRangeRepresentation());
                    xProp.set( aSequences[k]->getLabel(), uno::UNO_QUERY );
                    if( xProp.is() &&
                        ( xProp->getPropertyValue( C2U( "Role" )) >>= aId ))
                    {
                        OSL_TRACE( "%*cdata sequence label %d: role: %s, source: %s",
                                   nIndent + 2, lcl_aSpace, k, U2C( aId ), U2C( aSourceId ));
                    }
                    else
                    {
                        OSL_TRACE( "%*cdata sequence label %d: unknown role, source: %s",
                                   nIndent + 2, lcl_aSpace, k, U2C( aSourceId ) );
                    }
                }
            }
        }
    }
}

void lcl_TraceChartType( const Reference< XChartType > & xChartType, int nIndent )
{
    if( xChartType.is())
    {
        OSL_TRACE( "%*c* type: %s", nIndent, lcl_aSpace, U2C( xChartType->getChartType()) );

        lcl_IndentedTrace( nIndent + 2, "Supported Roles" );
        sal_Int32 i=0;
        Sequence< OUString > aMandRoles( xChartType->getSupportedMandatoryRoles());
        if( aMandRoles.getLength() > 0 )
        {
            lcl_IndentedTrace( nIndent + 4, "mandatory" );
            for( i=0; i<aMandRoles.getLength(); ++i )
            {
                OSL_TRACE( "%*c%s", nIndent + 6, lcl_aSpace, U2C( aMandRoles[i] ));
            }
        }
        Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles());
        if( aOptRoles.getLength() > 0 )
        {
            lcl_IndentedTrace( nIndent + 4, "optional" );
            for( i=0; i<aOptRoles.getLength(); ++i )
            {
                OSL_TRACE( "%*c%s", nIndent + 6, lcl_aSpace, U2C( aOptRoles[i] ));
            }
        }
        OSL_TRACE( "%*crole of sequence for label: %s", nIndent + 2, lcl_aSpace,
                   U2C( xChartType->getRoleOfSequenceForSeriesLabel()));

        Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
        if( xDSCnt.is())
        {
            lcl_IndentedTrace( nIndent + 2, "Data Series" );
            lcl_TraceDataSeriesSeq( xDSCnt->getDataSeries(), nIndent + 4 );
        }
    }
}

void lcl_TraceCoordinateSystem( const Reference< XCoordinateSystem > & xCooSys, int nIndent )
{
    if( xCooSys.is()) try
    {
        sal_Int32 nDim = xCooSys->getDimension();
        OSL_TRACE( "%*c* dim: %ld, type: %s", nIndent, lcl_aSpace,
                   nDim, U2C( xCooSys->getCoordinateSystemType() ));
        nIndent += 2;
        OSL_TRACE( "%*cview service-name: %s", nIndent, lcl_aSpace,
                   U2C( xCooSys->getViewServiceName() ));

        Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
        if( xProp.is())
        {
            Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo(), uno::UNO_QUERY );
            sal_Bool bSwap;
            if( xInfo.is() &&
                xInfo->hasPropertyByName( C2U("SwapXAndYAxis")) &&
                (xProp->getPropertyValue( C2U("SwapXAndYAxis")) >>= bSwap) &&
                bSwap )
            {
                lcl_IndentedTrace( nIndent, "swap x-axis and y-axis" );
            }
        }

        if( nDim >= 2 )
        {
            const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(1);
            for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
            {
                Reference< XScale > xScale( xCooSys->getAxisByDimension( 1, nI ));
                if( xScale.is())
                {
                    ScaleData aData( xScale->getScaleData());
                    if( aData.AxisType==AxisType::PERCENT )
                        lcl_IndentedTrace( nIndent, "percent stacking at y-scale" );
                }
            }
        }

        Sequence< uno::Any > aOrigin( xCooSys->getOrigin());
        double x, y, z;
        ::rtl::math::setNan( &x ), ::rtl::math::setNan( &y ), ::rtl::math::setNan( &z );
        if( aOrigin.getLength() > 0 &&
            aOrigin[0].hasValue() )
            aOrigin[0] >>= x;
        if( aOrigin.getLength() > 1 &&
            aOrigin[1].hasValue() )
            aOrigin[1] >>= y;
        if( aOrigin.getLength() > 2 &&
            aOrigin[2].hasValue() )
            aOrigin[2] >>= z;
        OSL_TRACE( "%*corigin: (%f, %f, %f)", nIndent, lcl_aSpace, x, y, z );

        Reference< XChartTypeContainer > xCTCnt( xCooSys, uno::UNO_QUERY );
        if( xCTCnt.is())
        {
            Sequence< Reference< XChartType > > aChartTypes( xCTCnt->getChartTypes());
            if( aChartTypes.getLength() > 0 )
            {
                lcl_IndentedTrace( nIndent, "Chart Types" );
                for( sal_Int32 i=0; i<aChartTypes.getLength(); ++i )
                {
                    lcl_TraceChartType( aChartTypes[i], nIndent + 2 );
                }
            }
        }
    }
    catch( uno::Exception & ex )
    {
        lcl_TraceException( ex );
    }
}

void lcl_TraceMeter(
    const Reference< XMeter > & xMeter,
    const Sequence< Reference< XCoordinateSystem > > & aCooSys,
    bool bWithCategories,
    int nIndent )
{
    try
    {
        Reference< XCoordinateSystem > xCooSys( xMeter->getCoordinateSystem());
        for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
            if( aCooSys[i] == xCooSys )
            {
                OSL_TRACE( "%*cbelongs to Coordinate System %ld.", nIndent + 2, lcl_aSpace, i );
            }
        OSL_TRACE( "%*crepresents  Dimension %ld.", nIndent + 2, lcl_aSpace, xMeter->getRepresentedDimension());
        if( bWithCategories )
        {
            Reference< XScale > xScale( xCooSys->getAxisByDimension( xMeter->getRepresentedDimension(), xMeter->getIndex() ));
            if( xScale.is())
            {
                ScaleData aData = xScale->getScaleData();
                if( aData.Categories.is())
                {
                    lcl_TraceCategories( aData.Categories, nIndent + 2 );
                }
            }
        }
    }
    catch( uno::Exception & ex )
    {
        lcl_TraceException( ex );
    }
}
*/
} // anonymous namespace
#endif


namespace chart
{
namespace debug
{

#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL

void ChartDebugTraceDocument(
    const Reference< XChartDocument > & /*xDoc*/,
    int /*nIndent*/ )
{
    /*
#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
    try
    {
        OSL_TRACE( "%*cas %sternal data", nIndent, 'h',
                   xDoc->hasInternalDataProvider() ? "in": "ex" );

        Reference< lang::XMultiServiceFactory > xCTManager( xDoc->getChartTypeManager(), uno::UNO_QUERY );
        if( xCTManager.is())
        {
            Sequence< OUString > aServiceNames( xCTManager->getAvailableServiceNames());
            OSL_TRACE( "%*c ChartTypeManager has %ld entries", nIndent, '*', aServiceNames.getLength());
# if OSL_DEBUG_LEVEL >= (CHART_TRACE_OSL_DEBUG_LEVEL + 1)
            for( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
            {
                OSL_TRACE( "%*c%s", nIndent + 2, lcl_aSpace, U2C( aServiceNames[i] ));
            }
# endif
        }
        Reference< XDiagram > xDiagram( xDoc->getFirstDiagram());
        lcl_IndentedTrace( nIndent, "* Diagram" );
        ChartDebugTraceDiagram( xDiagram, nIndent + 2 );
    }
    catch( uno::Exception & ex )
    {
        lcl_TraceException( ex );
    }
#endif
    */
}

void ChartDebugTraceDiagram(
    const Reference< XDiagram > & /*xDiagram*/,
    int /*nIndent*/ )
{
    /*
#if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
    try
    {
        Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
        Sequence< Reference< XCoordinateSystem > > aCooSys( xCooSysCnt->getCoordinateSystems() );
        if( aCooSys.getLength() > 0 )
        {
            lcl_IndentedTrace( nIndent, "CoordinateSystems" );
            for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
                lcl_TraceCoordinateSystem( aCooSys[i], nIndent + 2 );
        }
        else
        {
            lcl_IndentedTrace( nIndent, "<No Coordinate Systems>" );
        }

        Reference< XAxisContainer > xAxisCnt( xDiagram, uno::UNO_QUERY_THROW );
        Sequence< Reference< XAxis > > aAxes( xAxisCnt->getAxes() );
        if( aAxes.getLength() > 0 )
        {
            lcl_IndentedTrace( nIndent, "Axes" );
            for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
                lcl_TraceMeter( Reference< XMeter >( aAxes[i], uno::UNO_QUERY ), aCooSys, true, nIndent + 2 );
        }
        else
        {
            lcl_IndentedTrace( nIndent, "<No Axes>" );
        }

        Reference< XGridContainer > xGridCnt( xDiagram, uno::UNO_QUERY_THROW );
        Sequence< Reference< XGrid > > aGrids( xGridCnt->getGrids() );
        if( aGrids.getLength() > 0 )
        {
            lcl_IndentedTrace( nIndent, "Grids" );
            for( sal_Int32 i=0; i<aGrids.getLength(); ++i )
                lcl_TraceMeter( Reference< XMeter >( aGrids[i], uno::UNO_QUERY ), aCooSys, false, nIndent + 2 );
        }
        else
        {
            lcl_IndentedTrace( nIndent, "<No Grids>" );
        }
    }
    catch( uno::Exception & ex )
    {
        lcl_TraceException( ex );
    }

#endif

*/
}
#endif

} // namespace debug
} //  namespace chart
