#pragma once
/*
 *  $Id: brick.h 30051 2026-06-12 13:19:37Z vojtakl4 $
 *  Copyright (C) 2003-2025 David Necas (Yeti), Petr Klapetek.
 *  E-mail: yeti@gwyddion.net, klapetek@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.
 */

#ifndef __GWY_BRICK_H__
#define __GWY_BRICK_H__

#include <libgwyddion/unit.h>
#include <libgwyddion/enums.h>
#include <libgwyddion/field.h>
#include <libgwyddion/line.h>

G_BEGIN_DECLS

typedef enum {
    GWY_BRICK_TRANSPOSE_XYZ = 0,
    GWY_BRICK_TRANSPOSE_XZY = 1,
    GWY_BRICK_TRANSPOSE_YXZ = 2,
    GWY_BRICK_TRANSPOSE_YZX = 3,
    GWY_BRICK_TRANSPOSE_ZXY = 4,
    GWY_BRICK_TRANSPOSE_ZYX = 5,
} GwyBrickTransposeType;

#define GWY_TYPE_BRICK            (gwy_brick_get_type())
#define GWY_BRICK(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GWY_TYPE_BRICK, GwyBrick))
#define GWY_BRICK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), GWY_TYPE_BRICK, GwyBrickClass))
#define GWY_IS_BRICK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GWY_TYPE_BRICK))
#define GWY_IS_BRICK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GWY_TYPE_BRICK))
#define GWY_BRICK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GWY_TYPE_BRICK, GwyBrickClass))

typedef struct _GwyBrick        GwyBrick;
typedef struct _GwyBrickClass   GwyBrickClass;
typedef struct _GwyBrickPrivate GwyBrickPrivate;

struct _GwyBrick {
    GObject parent_instance;
    GwyBrickPrivate *priv;

    gint xres;
    gint yres;
    gint zres;

    gdouble xreal;
    gdouble yreal;
    gdouble zreal;

    gdouble xoff;
    gdouble yoff;
    gdouble zoff;
};

struct _GwyBrickClass {
    GObjectClass parent_class;

    void (*data_changed)(GwyBrick *brick);

    /*< private >*/
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
};

GType           gwy_brick_get_type               (void)                                G_GNUC_CONST;
GwyBrick*       gwy_brick_new                    (gint xres,
                                                  gint yres,
                                                  gint zres,
                                                  gdouble xreal,
                                                  gdouble yreal,
                                                  gdouble zreal,
                                                  gboolean nullme)                     G_GNUC_MALLOC;
GwyBrick*       gwy_brick_new_alike              (GwyBrick *model,
                                                  gboolean nullme)                     G_GNUC_MALLOC;
GwyBrick*       gwy_brick_copy                   (GwyBrick *brick)                     G_GNUC_MALLOC;
void            gwy_brick_assign                 (GwyBrick *destination,
                                                  GwyBrick *source);
void            gwy_brick_resize                 (GwyBrick *brick,
                                                  gint xres,
                                                  gint yres,
                                                  gint zres);
void            gwy_brick_crop                   (GwyBrick *brick,
                                                  gint xpos,
                                                  gint ypos,
                                                  gint zpos,
                                                  gint width,
                                                  gint height,
                                                  gint depth);
GwyBrick*       gwy_brick_new_part               (GwyBrick *brick,
                                                  gint xpos,
                                                  gint ypos,
                                                  gint zpos,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_data_changed           (GwyBrick *brick);
void            gwy_brick_copy_data              (GwyBrick *src,
                                                  GwyBrick *dest);
void            gwy_brick_resample               (GwyBrick *brick,
                                                  gint xres,
                                                  gint yres,
                                                  gint zres,
                                                  GwyInterpolationType interpolation);
gint            gwy_brick_get_xres               (GwyBrick *brick);
gint            gwy_brick_get_yres               (GwyBrick *brick);
gint            gwy_brick_get_zres               (GwyBrick *brick);
gdouble         gwy_brick_get_xreal              (GwyBrick *brick);
gdouble         gwy_brick_get_yreal              (GwyBrick *brick);
gdouble         gwy_brick_get_zreal              (GwyBrick *brick);
gdouble         gwy_brick_get_xoffset            (GwyBrick *brick);
gdouble         gwy_brick_get_yoffset            (GwyBrick *brick);
gdouble         gwy_brick_get_zoffset            (GwyBrick *brick);
const gdouble*  gwy_brick_get_data_const         (GwyBrick *brick);
gdouble*        gwy_brick_get_data               (GwyBrick *brick);
gdouble*        gwy_brick_get_data_with_size     (GwyBrick *brick,
		                                  gsize *out_count);
void            gwy_brick_set_data_with_size     (GwyBrick *brick,
		                                  gdouble *data,
		                                  gsize data_count);
void            gwy_brick_invalidate             (GwyBrick *brick);
void            gwy_brick_set_xreal              (GwyBrick *brick,
                                                  gdouble xreal);
void            gwy_brick_set_yreal              (GwyBrick *brick,
                                                  gdouble yreal);
void            gwy_brick_set_zreal              (GwyBrick *brick,
                                                  gdouble zreal);
void            gwy_brick_set_xoffset            (GwyBrick *brick,
                                                  gdouble xoffset);
void            gwy_brick_set_yoffset            (GwyBrick *brick,
                                                  gdouble yoffset);
void            gwy_brick_set_zoffset            (GwyBrick *brick,
                                                  gdouble zoffset);
gdouble         gwy_brick_get_dx                 (GwyBrick *brick);
gdouble         gwy_brick_get_dy                 (GwyBrick *brick);
gdouble         gwy_brick_get_dz                 (GwyBrick *brick);
GwyUnit*        gwy_brick_get_unit_x             (GwyBrick *brick);
GwyUnit*        gwy_brick_get_unit_y             (GwyBrick *brick);
GwyUnit*        gwy_brick_get_unit_z             (GwyBrick *brick);
GwyUnit*        gwy_brick_get_unit_w             (GwyBrick *brick);
gdouble         gwy_brick_min                    (GwyBrick *brick);
gdouble         gwy_brick_max                    (GwyBrick *brick);
void            gwy_brick_copy_units             (GwyBrick *brick,
                                                  GwyBrick *target);
GwyValueFormat* gwy_brick_get_value_format_x     (GwyBrick *brick,
                                                  GwyUnitFormatStyle style,
                                                  GwyValueFormat *format);
GwyValueFormat* gwy_brick_get_value_format_y     (GwyBrick *brick,
                                                  GwyUnitFormatStyle style,
                                                  GwyValueFormat *format);
GwyValueFormat* gwy_brick_get_value_format_z     (GwyBrick *brick,
                                                  GwyUnitFormatStyle style,
                                                  GwyValueFormat *format);
GwyValueFormat* gwy_brick_get_value_format_w     (GwyBrick *brick,
                                                  GwyUnitFormatStyle style,
                                                  GwyValueFormat *format);
gdouble         gwy_brick_itor                   (GwyBrick *brick,
                                                  gdouble pixpos);
gdouble         gwy_brick_rtoi                   (GwyBrick *brick,
                                                  gdouble realpos);
gdouble         gwy_brick_jtor                   (GwyBrick *brick,
                                                  gdouble pixpos);
gdouble         gwy_brick_rtoj                   (GwyBrick *brick,
                                                  gdouble realpos);
gdouble         gwy_brick_ktor                   (GwyBrick *brick,
                                                  gdouble pixpos);
gdouble         gwy_brick_rtok                   (GwyBrick *brick,
                                                  gdouble realpos);
gdouble         gwy_brick_ktor_cal               (GwyBrick *brick,
                                                  gdouble pixpos);
gdouble         gwy_brick_rtok_cal               (GwyBrick *brick,
                                                  gdouble realpos);
gdouble         gwy_brick_get_val                (GwyBrick *brick,
                                                  gint col,
                                                  gint row,
                                                  gint lev);
void            gwy_brick_set_val                (GwyBrick *brick,
                                                  gint col,
                                                  gint row,
                                                  gint lev,
                                                  gdouble value);
gdouble         gwy_brick_get_val_real           (GwyBrick *brick,
                                                  gdouble x,
                                                  gdouble y,
                                                  gdouble z);
void            gwy_brick_set_val_real           (GwyBrick *brick,
                                                  gdouble x,
                                                  gdouble y,
                                                  gdouble z,
                                                  gdouble value);
gdouble         gwy_brick_get_dval               (GwyBrick *brick,
                                                  gdouble x,
                                                  gdouble y,
                                                  gdouble z,
                                                  GwyInterpolationType interpolation);
gdouble         gwy_brick_get_dval_real          (GwyBrick *brick,
                                                  gdouble x,
                                                  gdouble y,
                                                  gdouble z,
                                                  GwyInterpolationType interpolation);
void            gwy_brick_clear                  (GwyBrick *brick);
void            gwy_brick_fill                   (GwyBrick *brick,
                                                  gdouble value);
void            gwy_brick_multiply               (GwyBrick *brick,
                                                  gdouble value);
void            gwy_brick_add                    (GwyBrick *brick,
                                                  gdouble value);
GwyField*       gwy_brick_new_field_like_xy_plane(GwyBrick *brick,
                                                  gboolean nullme);
void            gwy_brick_extract_plane          (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_extract_xy_plane       (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint lev);
void            gwy_brick_sum_plane              (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_sum_xy_plane           (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_min_plane              (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_min_xy_plane           (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_max_plane              (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_max_xy_plane           (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_minpos_plane           (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_minpos_xy_plane        (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_maxpos_plane           (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_maxpos_xy_plane        (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_mean_plane             (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_mean_xy_plane          (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_rms_plane              (GwyBrick *brick,
                                                  GwyField *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth,
                                                  gboolean keep_offsets);
void            gwy_brick_rms_xy_plane           (GwyBrick *brick,
                                                  GwyField *target);
void            gwy_brick_extract_line           (GwyBrick *brick,
                                                  GwyLine *target,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint iend,
                                                  gint jend,
                                                  gint kend,
                                                  gboolean keep_offsets);
void            gwy_brick_extract_z_line         (GwyBrick *brick,
                                                  GwyLine *target,
                                                  gint i,
                                                  gint j);
GwyLine*        gwy_brick_get_zcalibration       (GwyBrick *brick);
void            gwy_brick_set_zcalibration       (GwyBrick *brick,
                                                  GwyLine *calibration);
void            gwy_brick_copy_zcalibration      (GwyBrick *brick,
                                                  GwyBrick *target);
void            gwy_brick_transpose              (GwyBrick *brick,
                                                  GwyBrick *target,
                                                  GwyBrickTransposeType type,
                                                  gboolean xflipped,
                                                  gboolean yflipped,
                                                  gboolean zflipped);
void            gwy_brick_flip                   (GwyBrick *brick,
                                                  gboolean xflipped,
                                                  gboolean yflipped,
                                                  gboolean zflipped);
void            gwy_brick_invert_value           (GwyBrick *brick);
void            gwy_brick_set_plane              (GwyBrick *brick,
                                                  GwyField *plane,
                                                  gint istart,
                                                  gint jstart,
                                                  gint kstart,
                                                  gint width,
                                                  gint height,
                                                  gint depth);
void            gwy_brick_set_xy_plane           (GwyBrick *brick,
                                                  GwyField *plane,
                                                  gint lev);
void            gwy_brick_add_to_xy_planes       (GwyBrick *brick,
                                                  GwyField *plane);
void            gwy_brick_multiply_xy_planes     (GwyBrick *brick,
                                                  GwyField *plane);
void            gwy_brick_add_to_z_lines         (GwyBrick *brick,
                                                  GwyLine *line);
gint            gwy_brick_threshold              (GwyBrick *brick,
                                                  gdouble threshold,
                                                  gdouble below,
                                                  gdouble above);

G_END_DECLS

#endif

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