/*
 *  $Id: brick.h 23262 2021-03-15 14:11:31Z yeti-dn $
 *  Copyright (C) 2003-2019 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/gwysiunit.h>
#include <libprocess/gwyprocessenums.h>
#include <libprocess/datafield.h>
#include <libprocess/dataline.h>

G_BEGIN_DECLS

#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;

/* XXX: Unused.  But Petr copied it here so we must keep it in the API. */
typedef struct {
    guint col;
    guint row;
    guint level;
    guint width;
    guint height;
    guint depth;
} GwyBrickPart;

struct _GwyBrick {
    GObject parent_instance;

    gint xres;
    gint yres;
    gint zres;

    gdouble xreal;
    gdouble yreal;
    gdouble zreal;

    gdouble xoff;
    gdouble yoff;
    gdouble zoff;

    gdouble *data;

    GwySIUnit *si_unit_x;
    GwySIUnit *si_unit_y;
    GwySIUnit *si_unit_z;
    GwySIUnit *si_unit_w;

    gpointer priv;
    gint int1;
};

struct _GwyBrickClass {
    GObjectClass parent_class;

    void (*data_changed)(GwyBrick *brick);
    /*< private >*/
    void (*reserved1)(void);
};

#define gwy_brick_duplicate(brick) \
        (GWY_BRICK(gwy_serializable_duplicate(G_OBJECT(brick))))
#define gwy_brick_assign(dest, source) \
        gwy_serializable_clone_with_type(G_OBJECT(source), \
                                         G_OBJECT(dest), \
                                         GWY_TYPE_BRICK)

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);
GwyBrick* gwy_brick_new_alike   (GwyBrick *model,
                                 gboolean nullme);
GwyBrick* gwy_brick_new_part    (const GwyBrick *brick,
                                 gint xpos,
                                 gint ypos,
                                 gint zpos,
                                 gint xres,
                                 gint yres,
                                 gint zres,
                                 gboolean keep_offsets);
void      gwy_brick_data_changed(GwyBrick *brick);

void              gwy_brick_copy              (GwyBrick *src,
                                               GwyBrick *dest,
                                               gboolean nondata_too);

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);
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);
GwySIUnit*        gwy_brick_get_si_unit_x     (GwyBrick *brick);
GwySIUnit*        gwy_brick_get_si_unit_y     (GwyBrick *brick);
GwySIUnit*        gwy_brick_get_si_unit_z     (GwyBrick *brick);
GwySIUnit*        gwy_brick_get_si_unit_w     (GwyBrick *brick);
void              gwy_brick_set_si_unit_x     (GwyBrick *brick,
                                               GwySIUnit *si_unit);
void              gwy_brick_set_si_unit_y     (GwyBrick *brick,
                                               GwySIUnit *si_unit);
void              gwy_brick_set_si_unit_z     (GwyBrick *brick,
                                               GwySIUnit *si_unit);
void              gwy_brick_set_si_unit_w     (GwyBrick *brick,
                                               GwySIUnit *si_unit);
gdouble           gwy_brick_get_min           (GwyBrick *brick);
gdouble           gwy_brick_get_max           (GwyBrick *brick);
void              gwy_brick_copy_units        (const GwyBrick *brick,
                                               GwyBrick *target);
GwySIValueFormat* gwy_brick_get_value_format_x(GwyBrick *brick,
                                               GwySIUnitFormatStyle style,
                                               GwySIValueFormat *format);
GwySIValueFormat* gwy_brick_get_value_format_y(GwyBrick *brick,
                                               GwySIUnitFormatStyle style,
                                               GwySIValueFormat *format);
GwySIValueFormat* gwy_brick_get_value_format_z(GwyBrick *brick,
                                               GwySIUnitFormatStyle style,
                                               GwySIValueFormat *format);
GwySIValueFormat* gwy_brick_get_value_format_w(GwyBrick *brick,
                                               GwySIUnitFormatStyle style,
                                               GwySIValueFormat *format);
gdouble*          gwy_brick_get_data          (GwyBrick *brick);
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,
                                               gint interpolation);
gdouble           gwy_brick_get_dval_real     (GwyBrick *brick,
                                               gdouble x,
                                               gdouble y,
                                               gdouble z,
                                               gint 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);
void              gwy_brick_extract_plane     (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_extract_xy_plane  (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint lev);
void              gwy_brick_sum_plane         (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_sum_xy_plane      (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_min_plane         (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_min_xy_plane      (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_max_plane         (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_max_xy_plane      (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_minpos_plane      (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_minpos_xy_plane   (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_maxpos_plane      (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_maxpos_xy_plane   (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_mean_plane        (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_mean_xy_plane     (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_rms_plane         (const GwyBrick *brick,
                                               GwyDataField *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth,
                                               gboolean keep_offsets);
void              gwy_brick_rms_xy_plane      (const GwyBrick *brick,
                                               GwyDataField *target);
void              gwy_brick_extract_line      (const GwyBrick *brick,
                                               GwyDataLine *target,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint iend,
                                               gint jend,
                                               gint kend,
                                               gboolean keep_offsets);
void              gwy_brick_extract_z_line    (const GwyBrick *brick,
                                               GwyDataLine *target,
                                               gint i,
                                               gint j);
GwyDataLine*      gwy_brick_get_zcalibration  (const GwyBrick *brick);
void              gwy_brick_set_zcalibration  (GwyBrick *brick,
                                               GwyDataLine *calibration);
void              gwy_brick_copy_zcalibration (const GwyBrick *brick,
                                               GwyBrick *target);
void              gwy_brick_transpose         (GwyBrick *brick,
                                               GwyBrick *target,
                                               GwyBrickTransposeType type,
                                               gboolean xflipped,
                                               gboolean yflipped,
                                               gboolean zflipped);
void              gwy_brick_invert            (GwyBrick *brick,
                                               gboolean xflipped,
                                               gboolean yflipped,
                                               gboolean zflipped,
                                               gboolean wflipped);
void              gwy_brick_set_plane         (GwyBrick *brick,
                                               GwyDataField *plane,
                                               gint istart,
                                               gint jstart,
                                               gint kstart,
                                               gint width,
                                               gint height,
                                               gint depth);
void              gwy_brick_set_xy_plane      (GwyBrick *brick,
                                               GwyDataField *plane,
                                               gint lev);
void              gwy_brick_add_to_xy_planes  (GwyBrick *brick,
                                               GwyDataField *plane);
void              gwy_brick_add_to_z_lines    (GwyBrick *brick,
                                               GwyDataLine *line);

G_END_DECLS

#endif /* __GWY_BRICK_H__ */

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