/* doc.h
 * This file is part of Amsam photo cropping program
 * Copyright 2021, 2023, 2024, 2025, 2026 Nandakumar Edamana
 * Distributed under GNU General Public License, version 3
 */ 

#ifndef N96_DRAW_doc_h
#define N96_DRAW_doc_h

typedef struct intvector intvector;
typedef struct LayerOwningVector LayerOwningVector;
typedef struct _ngg_vtab_t_HistoryPoint _ngg_vtab_t_HistoryPoint;
typedef struct HistoryPoint HistoryPoint;
typedef struct ImageHistoryPoint ImageHistoryPoint;
typedef struct LayerStackHistoryPoint LayerStackHistoryPoint;
typedef struct HistoryPointStack HistoryPointStack;
typedef struct _ngg_tuple_ImageDocument__update_composite _ngg_tuple_ImageDocument__update_composite;
typedef struct ImageDocument ImageDocument;
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "floodfill.h"
#include "floodfill.h"
#include "layer.h"
#include "layer.h"
#include "image-cairo.h"
#include "image-cairo.h"
struct intvector {
	int *arr;
	int alloccount;
	int count;
};
void intvector__resize(intvector *this, int newcount);
void intvector_append(intvector *this, int newitem);
void intvector_clear(intvector *this);
int intvector_get_item(intvector *this, int index);
int intvector_pop(intvector *this);
void intvector_set_item(intvector *this, int index, int itm);
int intvector_get_count(intvector *this);
_Bool intvector_is_empty(intvector *this);
void intvector_destruct(intvector *this);
void intvector_construct(intvector *this);
#include <stdio.h>
#include <stdlib.h>
#define STACKLIMIT (5)
#define DEBUG_COMPOSITE_DIRTYRECT (false)
#define RECOMPOSITE_DIRTY_ONLY (true)
#define REPREVIEW_DIRTY_ONLY (true)
#define SCRATCHBORDER (10)
extern Pixel PIXEL_CHECKER_DARK;
extern Pixel PIXEL_CHECKER_LIGHT;
extern Pixel PIXEL_SCRATCH_DARK;
extern Pixel PIXEL_SCRATCH_LIGHT;
struct LayerOwningVector {
	Layer * *arr;
	int alloccount;
	int count;
};
void layer_owning_vector_destruct(LayerOwningVector *this);
void layer_owning_vector__resize(LayerOwningVector *this, int newcount);
void layer_owning_vector_append(LayerOwningVector *this, Layer *newitem);
void layer_owning_vector_clear(LayerOwningVector *this);
void layer_owning_vector_delete_all(LayerOwningVector *this);
Layer * layer_owning_vector_get_item(LayerOwningVector *this, int index);
Layer * layer_owning_vector_pop(LayerOwningVector *this);
void layer_owning_vector_set_item(LayerOwningVector *this, int index, Layer *itm);
int layer_owning_vector_get_count(LayerOwningVector *this);
_Bool layer_owning_vector_is_empty(LayerOwningVector *this);
void layer_owning_vector_construct(LayerOwningVector *this);
extern int _ngg_clsid_HistoryPoint;
typedef struct HistoryPoint HistoryPoint;
struct _ngg_vtab_t_HistoryPoint {
	void (*destruct)(HistoryPoint *this);
};
struct HistoryPoint {
	int *_ngg_clsid_final;
	_ngg_vtab_t_HistoryPoint _ngg_vtab_history_point;
};
void history_point__nggnonvirt_destruct(HistoryPoint *this);
void history_point_destruct(HistoryPoint *this);
void history_point_construct(HistoryPoint *this);
extern int _ngg_clsid_ImageHistoryPoint;
struct ImageHistoryPoint {
	int *_ngg_clsid_final;
	_ngg_vtab_t_HistoryPoint _ngg_vtab_history_point;
	Image *img;
	int layeridx;
};
void image_history_point_construct(ImageHistoryPoint *this, int layeridx, Image *img);
Image * image_history_point_detach_img(ImageHistoryPoint *this);
void image_history_point__nggnonvirt_destruct(ImageHistoryPoint *this);
extern int _ngg_clsid_LayerStackHistoryPoint;
struct LayerStackHistoryPoint {
	int *_ngg_clsid_final;
	_ngg_vtab_t_HistoryPoint _ngg_vtab_history_point;
	intvector *layerstack;
	int curlayeridxidx;
};
void layer_stack_history_point_construct(LayerStackHistoryPoint *this, intvector *layerstack, int curlayeridxidx);
intvector * layer_stack_history_point_detach_layerstack(LayerStackHistoryPoint *this);
void layer_stack_history_point__nggnonvirt_destruct(LayerStackHistoryPoint *this);
struct HistoryPointStack {
	HistoryPoint * *arr;
	int count;
	int alloccount;
};
int history_point_stack_get_count(HistoryPointStack *this);
_Bool history_point_stack_is_empty(HistoryPointStack *this);
void history_point_stack_push(HistoryPointStack *this, HistoryPoint *newitem);
void history_point_stack_push_multiple(HistoryPointStack *this, int n, HistoryPoint * *newitems);
HistoryPoint * history_point_stack_peek(HistoryPointStack *this);
HistoryPoint * history_point_stack_pop(HistoryPointStack *this);
HistoryPoint * history_point_stack_pop_bottom(HistoryPointStack *this);
void history_point_stack_replace_top(HistoryPointStack *this, HistoryPoint *newitem);
void history_point_stack__resize(HistoryPointStack *this, int newcount);
void history_point_stack_destruct(HistoryPointStack *this);
void history_point_stack_construct(HistoryPointStack *this);
struct _ngg_tuple_ImageDocument__update_composite {
	_Bool m0;
	VaraRect m1;
};
struct ImageDocument {
	int width;
	int height;
	LinearPixel bgcolor;
	Image *checkpattern;
	LayerOwningVector *layers;
	intvector *layerstack;
	int curlayeridxidx;
	int layerstack_version;
	VaraRect dirtyrect;
	Image *composite;
	Image *preview;
	Image *scratchborder;
	_Bool preview_is_all_dirty;
	_Bool pen_is_down;
	double oldx;
	double oldy;
	double stroke_smoothness;
	_Bool subpixel_when_zoomed;
	DrawingParams drawparams;
	_Bool scratchmode;
	int vpx;
	int vpy;
	double vpzoom;
	int oldpreviewx;
	int oldpreviewy;
	int oldprevieww;
	int oldpreviewh;
	double oldpreviewzoom;
	_Bool autocenter;
	HistoryPointStack *undostack;
	HistoryPointStack *redostack;
	HistoryPoint *prescratchbak;
	void (*history_changed_cbk)(void *userdata);
	void *history_changed_userdata;
	_Bool in_bg_fg_mode;
};
void image_document_construct(ImageDocument *this, int width, int height, DrawingParams drawparams, _Bool create_init_layers);
void image_document_destruct(ImageDocument *this);
void image_document_apply_snapshot(ImageDocument *this, HistoryPoint *hp);
void image_document_append_layer(ImageDocument *this, Layer *layer);
_Bool image_document_can_create_layer(ImageDocument *this);
_Bool image_document_can_delete_layer(ImageDocument *this);
_Bool image_document_can_move_layer_down(ImageDocument *this);
_Bool image_document_can_move_layer_up(ImageDocument *this);
_Bool image_document_can_redo(ImageDocument *this);
_Bool image_document_can_rename_layer(ImageDocument *this);
_Bool image_document_can_switch_layer(ImageDocument *this);
_Bool image_document_can_undo(ImageDocument *this);
void image_document_clear_layer(ImageDocument *this);
void image_document_clear_redostack(ImageDocument *this);
void image_document_clear_undostack(ImageDocument *this);
void image_document_composite_layerstack(ImageDocument *this, Image *target, _Bool all_dirty, VaraRect dirtyrect);
Image * image_document_create_export_composite(ImageDocument *this, _Bool fillbg);
HistoryPoint * image_document_create_image_history_point(ImageDocument *this);
void image_document_create_layer(ImageDocument *this, const char *name, LinearPixel bgcolor);
void image_document_create_layer_and_switch(ImageDocument *this, const char *name, LinearPixel bgcolor);
HistoryPoint * image_document_create_layerstack_history_point(ImageDocument *this);
void image_document_create_undo_snapshot(ImageDocument *this, HistoryPoint *hp);
void image_document_create_image_undo_snapshot(ImageDocument *this);
void image_document_create_layerstack_undo_snapshot(ImageDocument *this);
void image_document_delete_layer(ImageDocument *this);
Layer * image_document_get_curlayer(ImageDocument *this);
int image_document_get_curlayeridx(ImageDocument *this);
int image_document_get_curlayeridxidx(ImageDocument *this);
Layer * image_document_get_bglayer_must(ImageDocument *this);
Layer * image_document_get_fglayer_must(ImageDocument *this);
Layer * image_document_get_layer(ImageDocument *this, int idx);
Layer * image_document_get_layer_must(ImageDocument *this, int layeridx);
_Bool image_document_has_bglayer(ImageDocument *this);
_Bool image_document_has_fglayer(ImageDocument *this);
void image_document_dip_eyedropper(ImageDocument *this, int x, int y);
VaraFileIOError image_document_export_document(ImageDocument *this, const char *filename, _Bool fillbg);
VaraFileIOError image_document_export_layer(ImageDocument *this, const char *filename, _Bool fillbg);
void image_document_fill_layer(ImageDocument *this, LinearPixel color);
void image_document_fill_layer_with_bgcolor(ImageDocument *this);
void image_document_fill_layer_with_fgcolor(ImageDocument *this);
void image_document_floodfill(ImageDocument *this, int x, int y);
LinearPixel image_document_get_color_at(ImageDocument *this, int x, int y);
int image_document_get_height(ImageDocument *this);
int image_document_get_width(ImageDocument *this);
_Bool image_document_is_curlayer_bg(ImageDocument *this);
_Bool image_document_is_curlayer_fg(ImageDocument *this);
void image_document_add_dirty_region(ImageDocument *this, VaraRect rect);
_Bool image_document_is_all_dirty(ImageDocument *this);
_Bool image_document_is_dirty(ImageDocument *this);
void image_document_mark_all_dirty(ImageDocument *this);
void image_document_mark_not_dirty(ImageDocument *this);
void image_document_move_layer_down(ImageDocument *this);
void image_document_move_layer_up(ImageDocument *this);
void image_document_pen_down(ImageDocument *this, int x, int y, double pressure);
void image_document_pen_up(ImageDocument *this, int x, int y, double pressure);
void image_document_pen_stroke(ImageDocument *this, int ix, int iy, double pressure);
void image_document_rename_layer(ImageDocument *this, const char *newnam);
void image_document_replace_layerstack(ImageDocument *this, intvector *newls);
void image_document_switch_layer(ImageDocument *this, int stackidx);
void image_document_switch_layer_bg(ImageDocument *this);
void image_document_switch_layer_fg(ImageDocument *this);
double image_document_translate_x(ImageDocument *this, double x);
double image_document_translate_y(ImageDocument *this, double y);
void image_document_update_pressure(ImageDocument *this, double pressure);
void image_document_undo(ImageDocument *this);
void image_document_viewport_align_center(ImageDocument *this);
void image_document_viewport_set_offsetx(ImageDocument *this, int x);
void image_document_viewport_set_offsety(ImageDocument *this, int y);
void image_document_viewport_set_size(ImageDocument *this, int w, int h);
void image_document_viewport_zoom_at(ImageDocument *this, int x, int y, double zoom);
void image_document_viewport_zoom_at_internal(ImageDocument *this, int x, int y, double zoom);
void image_document_viewport_zoom_at_center(ImageDocument *this, double zoom);
void image_document_viewport_zoom_to_fit(ImageDocument *this);
_ngg_tuple_ImageDocument__update_composite image_document_update_composite(ImageDocument *this);
VaraRect image_document_update_preview(ImageDocument *this);
void image_document_redo(ImageDocument *this);
void image_document_set_bgvisible(ImageDocument *this, _Bool visible);
void image_document_set_curlayer_alpha(ImageDocument *this, double alpha);
void image_document_set_fgvisible(ImageDocument *this, _Bool visible);
void image_document_set_history_changed_callback(ImageDocument *this, void (*cbk)(void *userdata), void *userdata);
void image_document_toggle_scratch_mode(ImageDocument *this);
void image_fill_checkpattern(Image *img);
void image_fill_scratchpattern(Image *img);
void intvector_delete_item(intvector *iv, int idx);
void intvector_swap_items(intvector *iv, int idx1, int idx2);
VaraFileIOError write_image_to_file(Image *img, const char *fname);
void vara_log_error(const char *msg);
_ngg_tuple_ImageDocument__update_composite _ngg_tuple_ImageDocument__update_composite_default();

#endif /* N96_DRAW_doc_h */
