/**************************************************************
 *
 * 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.
 *
 *************************************************************/


#ifndef _CHART2_OBJECTIDENTIFIER_HXX
#define _CHART2_OBJECTIDENTIFIER_HXX

#include <com/sun/star/chart2/XChartType.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XCoordinateSystem.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include "TitleHelper.hxx"
#include "charttoolsdllapi.hxx"

// header for class OUString
#include <rtl/ustring.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/Point.hpp>
#include <com/sun/star/drawing/XShape.hpp>

//.............................................................................
namespace chart
{
//.............................................................................

//-----------------------------------------------------------------------------
/**
*/
enum ObjectType
{
    OBJECTTYPE_PAGE,
    OBJECTTYPE_TITLE,
    OBJECTTYPE_LEGEND,
    OBJECTTYPE_LEGEND_ENTRY,
    OBJECTTYPE_DIAGRAM,
	OBJECTTYPE_DIAGRAM_WALL,
	OBJECTTYPE_DIAGRAM_FLOOR,
    OBJECTTYPE_AXIS,
    OBJECTTYPE_AXIS_UNITLABEL,
	OBJECTTYPE_GRID,
    OBJECTTYPE_SUBGRID,
	OBJECTTYPE_DATA_SERIES,
	OBJECTTYPE_DATA_POINT,
    OBJECTTYPE_DATA_LABELS,
    OBJECTTYPE_DATA_LABEL,
    OBJECTTYPE_DATA_ERRORS,
    OBJECTTYPE_DATA_ERRORS_X,
    OBJECTTYPE_DATA_ERRORS_Y,
    OBJECTTYPE_DATA_ERRORS_Z,
    OBJECTTYPE_DATA_CURVE,//e.g. a statistical method printed as line
    OBJECTTYPE_DATA_AVERAGE_LINE,
    OBJECTTYPE_DATA_CURVE_EQUATION,
	OBJECTTYPE_DATA_STOCK_RANGE,
	OBJECTTYPE_DATA_STOCK_LOSS,
	OBJECTTYPE_DATA_STOCK_GAIN,
    OBJECTTYPE_SHAPE,
    OBJECTTYPE_UNKNOWN
};

class OOO_DLLPUBLIC_CHARTTOOLS ObjectIdentifier
{
    //CID == ClassifiedIdentifier <--> name of shape
    //semicolon, colon, equal sign and slash have special meanings in a CID
    //and are therefore not allowed in its components

    //syntax of a CID:  CID:/classification/ObjectID

    //where classification: nothing or "MultiClick" or "DragMethod=DragMethodServiceName" and "DragParameter=DragParameterString"
    //                      or a combination of these separated with a colon
    //where DragMethodServiceName can be a selfdefined servicename for special actions //todo define standard service for this purpose
    //where DragParameterString is any string you like to transport information to your special drag service
    //                            only semicolon, colon, equal sign and slash are not allowed characters
    //                            also the keywords used in the ObjectIdentifiers are not allowed

    //where ObjectID: Parent-Particle:Particle //e.g. Series=2:Point=22
    //where Particle: Type=ParticleID //e.g. Point=22
    //where Type: getStringForType( ObjectType eType ) or other string

public:
    ObjectIdentifier();
    ObjectIdentifier( const ::rtl::OUString& rObjectCID );
    ObjectIdentifier( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape );
    ObjectIdentifier( const ::com::sun::star::uno::Any& rAny );
    virtual ~ObjectIdentifier();

    ObjectIdentifier( const ObjectIdentifier& rOID );
    ObjectIdentifier& operator=( const ObjectIdentifier& rOID );
    bool operator==( const ObjectIdentifier& rOID ) const;
    bool operator!=( const ObjectIdentifier& rOID ) const;
    bool operator<( const ObjectIdentifier& rOID ) const;

    static rtl::OUString createClassifiedIdentifierForObject(
          const ::com::sun::star::uno::Reference<
                    ::com::sun::star::uno::XInterface >& xObject
        , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    static rtl::OUString createClassifiedIdentifierForParticle(
        const rtl::OUString& rParticle );

    static rtl::OUString createClassifiedIdentifierForParticles(
            const rtl::OUString& rParentParticle
          , const rtl::OUString& rChildParticle
          , const rtl::OUString& rDragMethodServiceName = rtl::OUString()
          , const rtl::OUString& rDragParameterString = rtl::OUString() );

    static rtl::OUString createClassifiedIdentifierForGrid(
          const ::com::sun::star::uno::Reference<
                    ::com::sun::star::chart2::XAxis >& xAxis
        , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel
        , sal_Int32 nSubIndex = -1 );//-1: main grid, 0: first subgrid etc

    SAL_DLLPRIVATE static rtl::OUString createParticleForDiagram(
          const ::com::sun::star::uno::Reference<
                    ::com::sun::star::chart2::XDiagram >& xDiagram
        , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );


    static rtl::OUString createParticleForCoordinateSystem(
          const ::com::sun::star::uno::Reference<
                    ::com::sun::star::chart2::XCoordinateSystem >& xCooSys
        , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    static rtl::OUString createParticleForAxis(
                      sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );

    static rtl::OUString createParticleForGrid(
                      sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex );

    static rtl::OUString createParticleForSeries( sal_Int32 nDiagramIndex, sal_Int32 nCooSysIndex
            , sal_Int32 nChartTypeIndex, sal_Int32 nSeriesIndex );

    static rtl::OUString createParticleForLegend(
          const ::com::sun::star::uno::Reference<
                    ::com::sun::star::chart2::XLegend >& xLegend
        , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    static rtl::OUString addChildParticle( const rtl::OUString& rParticle, const rtl::OUString& rChildParticle );
    static rtl::OUString createChildParticleWithIndex( ObjectType eObjectType, sal_Int32 nIndex );
    static sal_Int32 getIndexFromParticleOrCID( const rtl::OUString& rParticleOrCID );

    static rtl::OUString createClassifiedIdentifier(
        enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_SERIES
        , const rtl::OUString& rParticleID );//e.g. SeriesID

    static rtl::OUString createClassifiedIdentifierWithParent(
        enum ObjectType //e.g. OBJECTTYPE_DATA_POINT or OBJECTTYPE_GRID
        , const rtl::OUString& rParticleID //for points or subgrids this is an Index or otherwise an identifier from the model object
        , const rtl::OUString& rParentPartical //e.g. "Series=SeriesID" or "Grid=GridId"
        , const rtl::OUString& rDragMethodServiceName = rtl::OUString()
        , const rtl::OUString& rDragParameterString = rtl::OUString()
        );

    static bool isCID( const rtl::OUString& rName );
    static rtl::OUString getDragMethodServiceName( const rtl::OUString& rClassifiedIdentifier );
    static rtl::OUString getDragParameterString( const rtl::OUString& rCID );
    static bool isDragableObject( const rtl::OUString& rClassifiedIdentifier );
    bool isDragableObject();
    static bool isRotateableObject( const rtl::OUString& rClassifiedIdentifier );
    static bool isMultiClickObject( const rtl::OUString& rClassifiedIdentifier );
    static bool areSiblings( const rtl::OUString& rCID1, const rtl::OUString& rCID2 );//identical object is no sibling
    static bool areIdenticalObjects( const ::rtl::OUString& rCID1, const ::rtl::OUString& rCID2 );

    static rtl::OUString getStringForType( ObjectType eObjectType );
    static ObjectType    getObjectType( const rtl::OUString& rCID );
    ObjectType getObjectType();

    static rtl::OUString createSeriesSubObjectStub( ObjectType eSubObjectType
                    , const rtl::OUString& rSeriesParticle
                    , const rtl::OUString& rDragMethodServiceName = rtl::OUString()
                    , const rtl::OUString& rDragParameterString = rtl::OUString() );
    static rtl::OUString createPointCID( const rtl::OUString& rPointCID_Stub, sal_Int32 nIndex  );

    static rtl::OUString createDataCurveCID( const rtl::OUString& rSeriesParticle, sal_Int32 nCurveIndex, bool bAverageLine );
    static rtl::OUString createDataCurveEquationCID( const rtl::OUString& rSeriesParticle, sal_Int32 nCurveIndex );

    SAL_DLLPRIVATE static rtl::OUString getObjectID( const rtl::OUString& rCID );
    static rtl::OUString getParticleID( const rtl::OUString& rCID );
    static rtl::OUString getFullParentParticle( const rtl::OUString& rCID );

    //returns the series particle of a CID when the CID is a child of the series
    static rtl::OUString getSeriesParticleFromCID( const rtl::OUString& rCID );

    //return the model object that is indicated by rObjectCID
    static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
            getObjectPropertySet(
                  const rtl::OUString& rObjectCID
                , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );
    static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
            getObjectPropertySet(
                  const rtl::OUString& rObjectCID
                , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::chart2::XChartDocument >& xChartDocument );

    //return the axis object that belongs to rObjectCID if any
    static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >
            getAxisForCID(
                  const rtl::OUString& rObjectCID
                , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    //return the series object that belongs to rObjectCID if any
    static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >
            getDataSeriesForCID(
                  const rtl::OUString& rObjectCID
                , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >
            getDiagramForCID(
                  const rtl::OUString& rObjectCID
                , const ::com::sun::star::uno::Reference<
                    ::com::sun::star::frame::XModel >& xChartModel );

    static const ::rtl::OUString& getPieSegmentDragMethodServiceName();
    static ::rtl::OUString createPieSegmentDragParameterString(
          sal_Int32 nOffsetPercent
        , const ::com::sun::star::awt::Point& rMinimumPosition
        , const ::com::sun::star::awt::Point& rMaximumPosition );
    static bool parsePieSegmentDragParameterString( const rtl::OUString& rDragParameterString
        , sal_Int32& rOffsetPercent
        , ::com::sun::star::awt::Point& rMinimumPosition
        , ::com::sun::star::awt::Point& rMaximumPosition );

    static TitleHelper::eTitleType getTitleTypeForCID( const ::rtl::OUString& rCID );

    static ::rtl::OUString getMovedSeriesCID( const ::rtl::OUString& rObjectCID, sal_Bool bForward );

    bool isValid() const;
    bool isAutoGeneratedObject() const;
    bool isAdditionalShape() const;
    ::rtl::OUString getObjectCID() const;
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > getAdditionalShape() const;
    ::com::sun::star::uno::Any getAny() const;

private:
    // #i12587# support for shapes in chart
    // For autogenerated chart objects a CID is specified in m_aObjectCID,
    // for all other objects m_xAdditionalShape is set.
    // Note, that if m_aObjectCID is set, m_xAdditionalShape must be empty
    // and vice versa.
    ::rtl::OUString m_aObjectCID;
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > m_xAdditionalShape;
};

//.............................................................................
} //namespace chart
//.............................................................................
#endif
