#pragma once
/*
 *  $Id: file.h 29826 2026-04-16 18:08:14Z yeti-dn $
 *  Copyright (C) 2025-2026 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.
 */

#ifndef __GWYAPP_FILE_H__
#define __GWYAPP_FILE_H__

#include <libgwyddion/dict.h>
#include <libgwyddion/field.h>
#include <libgwyddion/brick.h>
#include <libgwyddion/spectra.h>
#include <libgwyddion/scatter.h>
#include <libgwyddion/lawn.h>
#include <libgwyui/graph-model.h>
#include <libgwyui/data-view.h>

G_BEGIN_DECLS

#define GWY_FILE_PREFIX_IMAGE   "/image"
#define GWY_FILE_PREFIX_GRAPH   "/graph"
#define GWY_FILE_PREFIX_SPECTRA "/sps"
#define GWY_FILE_PREFIX_VOLUME  "/volume"
#define GWY_FILE_PREFIX_XYZ     "/xyz"
#define GWY_FILE_PREFIX_CMAP    "/cmap"

#define GWY_FILE_ID_NONE (-1)

#define GWY_FILE_ERROR gwy_file_error_quark()

typedef enum {
    GWY_FILE_ERROR_KEY = 1,
    GWY_FILE_ERROR_TYPE,
    GWY_FILE_ERROR_ORPHAN,
    GWY_FILE_ERROR_SIZE_MISMATCH,
    GWY_FILE_ERROR_HUGE_ID,
} GwyFileError;

typedef enum {
    GWY_FILE_NONE    = -1,
    GWY_FILE_IMAGE   = 0,
    GWY_FILE_GRAPH   = 1,
    GWY_FILE_SPECTRA = 2,
    GWY_FILE_VOLUME  = 3,
    GWY_FILE_XYZ     = 4,
    GWY_FILE_CMAP    = 5,
} GwyDataKind;

typedef enum {
    GWY_FILE_PIECE_PALETTE,
    GWY_FILE_PIECE_RANGE,
    GWY_FILE_PIECE_COLOR_MAPPING,
    GWY_FILE_PIECE_REAL_SQUARE,
    GWY_FILE_PIECE_MASK,
    GWY_FILE_PIECE_MASK_COLOR,
    GWY_FILE_PIECE_SELECTION,
    GWY_FILE_PIECE_META,
    GWY_FILE_PIECE_PICTURE,
    GWY_FILE_PIECE_VIEW,
    GWY_FILE_PIECE_TITLE,
    /* Start pieces we do not simply synchronise beyond any usable bit index. */
    GWY_FILE_PIECE_LOG = 64,
    GWY_FILE_PIECE_VISIBLE,
    GWY_FILE_PIECE_FILENAME,
    GWY_FILE_PIECE_REF,
    GWY_FILE_PIECE_NONE = 65535,
    /* TODO: Other stuff: OpenGL view setup */
} GwyFilePiece;

// It would be nice to have an enum. We can have a 64bit enum in C, but it does not play nicely with GEnum and
// introspection anyway.
#define GWY_FILE_ITEM_PALETTE       (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_PALETTE)
#define GWY_FILE_ITEM_RANGE         (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_RANGE)
#define GWY_FILE_ITEM_COLOR_MAPPING (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_COLOR_MAPPING)
#define GWY_FILE_ITEM_REAL_SQUARE   (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_REAL_SQUARE)
#define GWY_FILE_ITEM_MASK          (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_MASK)
#define GWY_FILE_ITEM_MASK_COLOR    (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_MASK_COLOR)
#define GWY_FILE_ITEM_SELECTIONS    (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_SELECTION)
#define GWY_FILE_ITEM_META          (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_META)
#define GWY_FILE_ITEM_PICTURE       (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_PICTURE)
#define GWY_FILE_ITEM_VIEW          (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_VIEW)
#define GWY_FILE_ITEM_TITLE         (G_GUINT64_CONSTANT(1) << GWY_FILE_PIECE_TITLE)

typedef struct {
    gint id;
    GwyDataKind data_kind;
    GwyFilePiece piece;
    const gchar *suffix;
} GwyFileKeyParsed;

#define GWY_TYPE_FILE            (gwy_file_get_type())
#define GWY_FILE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GWY_TYPE_FILE, GwyFile))
#define GWY_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), GWY_TYPE_FILE, GwyFileClass))
#define GWY_IS_FILE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GWY_TYPE_FILE))
#define GWY_IS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GWY_TYPE_FILE))
#define GWY_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GWY_TYPE_FILE, GwyFileClass))

typedef struct _GwyFile             GwyFile;
typedef struct _GwyFileClass        GwyFileClass;
typedef struct _GwyFilePrivate      GwyFilePrivate;

struct _GwyFile {
    GwyDict parent_instance;
    GwyFilePrivate *priv;
};

struct _GwyFileClass {
    GwyDictClass parent_class;

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

typedef void (*GwyFileTransferFunc)(GwyFile *source,
                                    GwyFile *destination,
                                    GwyDataKind data_kind,
                                    gint source_id,
                                    gint destination_id,
                                    gpointer user_data);

GType               gwy_file_get_type           (void)                         G_GNUC_CONST;
GwyFile*            gwy_file_new                (void);
GwyFile*            gwy_file_new_in_construction(void);
GwyFile*            gwy_file_copy               (GwyFile *file);
gint                gwy_file_add_image          (GwyFile *file,
                                                 GwyField *field);
gint                gwy_file_add_graph          (GwyFile *file,
                                                 GwyGraphModel *graph);
gint                gwy_file_add_spectra        (GwyFile *file,
                                                 GwySpectra *spectra);
gint                gwy_file_add_volume         (GwyFile *file,
                                                 GwyBrick *brick,
                                                 GwyField *preview);
gint                gwy_file_add_xyz            (GwyFile *file,
                                                 GwyScatter *scatter);
gint                gwy_file_add_cmap           (GwyFile *file,
                                                 GwyLawn *lawn,
                                                 GwyField *preview);
void                gwy_file_remove             (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
guint               gwy_file_get_n_data         (GwyFile *file,
                                                 GwyDataKind data_kind);
gint*               gwy_file_get_ids            (GwyFile *file,
                                                 GwyDataKind data_kind);
gint*               gwy_file_get_idsv           (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 guint *n);
void                gwy_file_sync_items         (GwyFile *source,
                                                 GwyDataKind src_data_kind,
                                                 gint from_id,
                                                 GwyFile *destination,
                                                 GwyDataKind dest_data_kind,
                                                 gint to_id,
                                                 guint64 items,
                                                 gboolean delete_too);
gint                gwy_file_copy_data          (GwyFile *source,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 GwyFile *destination);
void                gwy_file_merge              (GwyFile *file,
                                                 GwyFile *otherfile,
                                                 GwyFileTransferFunc merged,
                                                 gpointer user_data,
                                                 GDestroyNotify destroy);
void                gwy_file_set_link_quark     (GwyFile *file,
                                                 GQuark key,
                                                 GQuark value);
void                gwy_file_set_link           (GwyFile *file,
                                                 const gchar *key,
                                                 const gchar *value);
gboolean            gwy_file_value_is_link      (GwyFile *file,
                                                 const gchar *key);
GObject*            gwy_file_get_data           (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_set_image          (GwyFile *file,
                                                 gint id,
                                                 GwyField *field);
void                gwy_file_pass_image         (GwyFile *file,
                                                 gint id,
                                                 GwyField *field);
GwyField*           gwy_file_get_image          (GwyFile *file,
                                                 gint id);
void                gwy_file_set_image_mask     (GwyFile *file,
                                                 gint id,
                                                 GwyNield *mask);
void                gwy_file_pass_image_mask    (GwyFile *file,
                                                 gint id,
                                                 GwyNield *mask);
GwyNield*           gwy_file_get_image_mask     (GwyFile *file,
                                                 gint id);
void                gwy_file_set_graph          (GwyFile *file,
                                                 gint id,
                                                 GwyGraphModel *gmodel);
void                gwy_file_pass_graph         (GwyFile *file,
                                                 gint id,
                                                 GwyGraphModel *gmodel);
GwyGraphModel*      gwy_file_get_graph          (GwyFile *file,
                                                 gint id);
void                gwy_file_set_volume         (GwyFile *file,
                                                 gint id,
                                                 GwyBrick *brick);
void                gwy_file_pass_volume        (GwyFile *file,
                                                 gint id,
                                                 GwyBrick *brick);
GwyBrick*           gwy_file_get_volume         (GwyFile *file,
                                                 gint id);
void                gwy_file_set_spectra        (GwyFile *file,
                                                 gint id,
                                                 GwySpectra *spectra);
void                gwy_file_pass_spectra       (GwyFile *file,
                                                 gint id,
                                                 GwySpectra *spectra);
GwySpectra*         gwy_file_get_spectra        (GwyFile *file,
                                                 gint id);
void                gwy_file_set_xyz            (GwyFile *file,
                                                 gint id,
                                                 GwyScatter *scatter);
void                gwy_file_pass_xyz           (GwyFile *file,
                                                 gint id,
                                                 GwyScatter *scatter);
GwyScatter*         gwy_file_get_xyz            (GwyFile *file,
                                                 gint id);
void                gwy_file_set_cmap           (GwyFile *file,
                                                 gint id,
                                                 GwyLawn *lawn);
void                gwy_file_pass_cmap          (GwyFile *file,
                                                 gint id,
                                                 GwyLawn *lawn);
GwyLawn*            gwy_file_get_cmap           (GwyFile *file,
                                                 gint id);
void                gwy_file_set_title          (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 const gchar *name,
                                                 gboolean numbered);
void                gwy_file_pass_title         (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 gchar *name);
gchar*              gwy_file_get_display_title  (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
const gchar*        gwy_file_get_title          (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
gint*               gwy_file_find_by_title      (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 const gchar *titleglob);
void                gwy_file_set_visible        (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 gboolean visible);
gboolean            gwy_file_get_visible        (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_pass_meta          (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 GwyDict *meta);
GwyDict*            gwy_file_get_meta           (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_set_palette        (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 const gchar *name);
const gchar*        gwy_file_get_palette        (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_set_color_mapping  (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 GwyColorMappingType mapping);
GwyColorMappingType gwy_file_get_color_mapping  (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_set_fixed_range    (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 gdouble min,
                                                 gdouble max);
gboolean            gwy_file_get_fixed_range    (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id,
                                                 gdouble *min,
                                                 gdouble *max);
void                gwy_file_remove_selections  (GwyFile *file,
                                                 GwyDataKind data_kind,
                                                 gint id);
void                gwy_file_remove_logs        (GwyFile *file);
const gchar*        gwy_file_get_format_name    (GwyFile *file);
const gchar*        gwy_file_get_filename_sys   (GwyFile *file);
gint                gwy_file_get_id             (GwyFile *file)                G_GNUC_PURE;

GQuark       gwy_file_key_filename           (void)                            G_GNUC_CONST;
GQuark       gwy_file_key_data               (GwyDataKind data_kind,
                                              gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image              (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_mask         (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_picture      (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_graph              (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_spectra            (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume             (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_mask        (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_xyz                (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap               (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_title        (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_color_mapping(gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_range_min    (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_range_max    (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_palette      (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_meta         (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_real_square  (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_image_selection    (gint id,
                                              const gchar *name)               G_GNUC_CONST;
GQuark       gwy_file_key_image_mask_color   (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_mask_color  (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_title       (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_picture     (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_palette     (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_volume_meta        (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_xyz_title          (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_xyz_palette        (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_xyz_meta           (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_xyz_picture        (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap_title         (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap_palette       (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap_meta          (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap_picture       (gint id)                         G_GNUC_CONST;
GQuark       gwy_file_key_cmap_real_square   (gint id)                         G_GNUC_CONST;
gboolean     gwy_parse_file_key              (const gchar *strkey,
                                              GwyFileKeyParsed *parsed);
GQuark       gwy_form_file_key               (const GwyFileKeyParsed *parsed);
const gchar* gwy_form_string_file_key        (const GwyFileKeyParsed *parsed);
GQuark       gwy_file_error_quark            (void)                            G_GNUC_CONST;

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