/***************************************************************************
                        qgsgeometryeditutils.h
  -------------------------------------------------------------------
Date                 : 21 Jan 2015
Copyright            : (C) 2015 by Marco Hugentobler
email                : marco.hugentobler at sourcepole dot com
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef QGSGEOMETRYEDITUTILS_H
#define QGSGEOMETRYEDITUTILS_H

class QgsAbstractGeometry;
class QgsCurve;
class QgsGeometryEngine;
class QgsVectorLayer;

#define SIP_NO_FILE

#include "qgsgeometry.h"
#include "qgsfeatureid.h"
#include <QMap>
#include <memory>

/**
 * \ingroup core
 * \class QgsGeometryEditUtils
 * \brief Convenience functions for geometry editing
 * \note not available in Python bindings
 * \since QGIS 2.10
 */
class QgsGeometryEditUtils
{
  public:

    /**
     * Add an interior \a ring to a \a geometry.
     * Ownership of the \a ring is transferred.
     * \returns 0 in case of success (ring added), 1 problem with geometry type, 2 ring not closed,
     * 3 ring is not valid geometry, 4 ring not disjoint with existing rings, 5 no polygon found which contained the ring
     */
    static QgsGeometry::OperationResult addRing( QgsAbstractGeometry *geometry, std::unique_ptr< QgsCurve > ring );

    /**
     * Add a \a part to multi type \a geometry.
     * Ownership of the \a part is transferred.
     * \returns 0 in case of success, 1 if not a multigeometry, 2 if part is not a valid geometry, 3 if new polygon ring
     * not disjoint with existing polygons of the feature
     */
    static QgsGeometry::OperationResult addPart( QgsAbstractGeometry *geometry, std::unique_ptr< QgsAbstractGeometry > part );

    /**
     * Deletes a ring from a geometry.
     * \returns TRUE if delete was successful
     */
    static bool deleteRing( QgsAbstractGeometry *geom, int ringNum, int partNum = 0 );

    /**
     * Deletes a part from a geometry.
     * \returns TRUE if delete was successful
     */
    static bool deletePart( QgsAbstractGeometry *geom, int partNum );

    /**
     * Alters a geometry so that it avoids intersections with features from all open vector layers.
     * \param geom geometry to alter
     * \param avoidIntersectionsLayers list of layers to check for intersections
     * \param ignoreFeatures map of layer to feature id of features to ignore
     */
    static std::unique_ptr< QgsAbstractGeometry > avoidIntersections( const QgsAbstractGeometry &geom,
        const QList<QgsVectorLayer *> &avoidIntersectionsLayers,
        const QHash<QgsVectorLayer *, QSet<QgsFeatureId> > &ignoreFeatures = ( QHash<QgsVectorLayer *, QSet<QgsFeatureId> >() ) );
};

#endif // QGSGEOMETRYEDITUTILS_H
