#ifndef __opt_height_field_h__
#define __opt_height_field_h__

#include "topotypes.h"

namespace toposmooth
{
    // Smoothes values associated with vertices in a 2D triangle mesh.
    //
    // Vertices are ordered from 0 to 'num_vertices'.
    // A vertex's 2D position is given by looking up its index in the 'vertices_xy' array,
    // which contains two values (x and y) for each vertex and is 'num_vertices' * 2 numbers long.
    //
    // Connectivity information is given by the array of triangle_t structs.
    // The array 'triangles' contains 'num_triangles' elements.
    // Each triangle_t contains three vertex indices.
    //
    // A vertex's function value is given by the corresponding value in the array
    // 'original_values' (which must have 'num_values' elements).
    // Upon output, 'new_values_out' is filled with new values guaranteed to be
    // monotonically decreasing, and yet smooth and close to 'original_values'.
    //
    // The directed edges of the monotonicity graph are given by the 'edge_t' array
    // 'directed_edges', of which there are 'num_edges'.
    // Each edge_t contains indices for the edge's start and end vertices.
    // NOTE: Sources and sinks are considered to be the fixed nodes.
    //
    // The optional parameter 'stay_close_to_original_values_weight' determines how strongly
    // the output should try to stay close to the original values.
    // A value <= 0. means that they should not try to stay close at all, and the resulting
    // values will be purely smoothed.
    // The default value is 0.
    //
    // The optional parameter 'smooth_deformation_not_smooth_function', if true, means that
    // the smoothing term attempts to find a smooth deformation of the original values to
    // make them monotonic, rather than finding actually smooth values.
    // The default value is false.
    template< typename floating_type >
    void smooth_mesh2d_monotonically_decreasing(
        
        // 2D mesh.
        const size_t num_vertices,
        // there are num_vertices * 2 values in 'vertices_xy'
        const floating_type* vertices_xy,
        
        // Connectivity.
        const size_t num_triangles,
        const triangle_t* triangles,
        
        // Values in and out, one for each vertex.
        const floating_type* original_vertex_values,
        floating_type* new_vertex_values_out,
        
        // Monotonicity information.
        const size_t num_edges,
        const edge_t* directed_edges,
        
        const floating_type stay_close_to_original_values_weight = 0.,
        bool smooth_deformation_not_smooth_function = false
        
        );
}

#endif /* __opt_height_field_h__ */
