/*
 *  $Id: selection-point.c 27855 2025-04-18 09:57:38Z yeti-dn $
 *  Copyright (C) 2024 David Necas (Yeti).
 *  E-mail: yeti@gwyddion.net.
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along with this program; if not, write to the
 *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "config.h"

#include "libgwyddion/macros.h"
#include "libgwyddion/math.h"
#include "libgwyddion/selection-point.h"

enum {
    OBJECT_SIZE = 2
};

struct _GwySelectionPointPrivate {
    gint dummy;
};

static void crop(GwySelection *selection,
                 gdouble xmin,
                 gdouble ymin,
                 gdouble xmax,
                 gdouble ymax);
static void move(GwySelection *selection,
                 gdouble vx,
                 gdouble vy);

static GObjectClass *parent_class = NULL;

G_DEFINE_TYPE(GwySelectionPoint, gwy_selection_point, GWY_TYPE_SELECTION)

static void
gwy_selection_point_class_init(GwySelectionPointClass *klass)
{
    GwySelectionClass *sel_class = GWY_SELECTION_CLASS(klass);

    parent_class = gwy_selection_point_parent_class;

    sel_class->object_size = OBJECT_SIZE;
    sel_class->crop = crop;
    sel_class->move = move;
}

static void
gwy_selection_point_init(GwySelectionPoint *selection)
{
    G_GNUC_UNUSED GwySelectionPointPrivate *priv;

    priv = selection->priv = gwy_selection_point_get_instance_private(selection);
}

static void
crop(GwySelection *selection, gdouble xmin, gdouble ymin, gdouble xmax, gdouble ymax)
{
    guint n = gwy_selection_get_n_objects(selection);
    gdouble *data = g_memdup(gwy_selection_get_data_array(selection), n*OBJECT_SIZE);

    for (guint i = 0; i < n; i++) {
        data[OBJECT_SIZE*i + 0] = fmax(fmin(data[OBJECT_SIZE*i + 0], xmax), xmin);
        data[OBJECT_SIZE*i + 1] = fmax(fmin(data[OBJECT_SIZE*i + 1], ymax), ymin);
    }

    gwy_selection_set_data(selection, n, data);
    g_free(data);
}

static void
move(GwySelection *selection, gdouble vx, gdouble vy)
{
    gdouble v[OBJECT_SIZE] = { vx, vy };
    gwy_selection_move_objects(selection, v);
}

/**
 * gwy_selection_point_new:
 *
 * Creates a new point selection.
 *
 * Returns: A new selection object.
 **/
GwySelection*
gwy_selection_point_new(void)
{
    return (GwySelection*)g_object_new(GWY_TYPE_SELECTION_POINT, NULL);
}

/**
 * SECTION:selection-point
 * @title: GwySelectionPoint
 * @short_description: Point selection
 *
 * #GwySelectionPoint represents points. Selection data consist of pairs of coordinates (@x, @y).
 **/

/* vim: set cin columns=120 tw=118 et ts=4 sw=4 cino=>1s,e0,n0,f0,{0,}0,^0,\:1s,=0,g1s,h0,t0,+1s,c3,(0,u0 : */
