/*
 *                            COPYRIGHT
 *
 *  camv-rnd - electronics-related CAM viewer
 *  Copyright (C) 2019,2023 Tibor 'Igor2' Palinkas
 *
 *  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., 31 Milk Street, # 960789 Boston, MA 02196 USA.
 *
 *  Contact:
 *    Project page: http://repo.hu/projects/camv-rnd
 *    lead developer: http://repo.hu/projects/camv-rnd/contact.html
 *    mailing list: pcb-rnd (at) list.repo.hu (send "subscribe")
 */

#ifndef CAMV_DATA_H
#define CAMV_DATA_H

#include <librnd/core/global_typedefs.h>
#include "camv_typedefs.h"
#include <librnd/core/hidlib.h>
#include <librnd/core/color.h>
#include <librnd/font/xform_mx.h>
#include <genvector/vtp0.h>
#include "rtree.h"

struct camv_design_s {
	rnd_design_t hidlib; /* shall be the first */

	/* UI states */
	rnd_coord_t crosshair_x, crosshair_y;
	unsigned grp_load:1;  /* if 1, we are loading a group */
	long grp_idx_last;

	/* data */
	vtp0_t layers; /* to camv_layer_t */
	int lysel;     /* layer idx (lid) of the currently selected layer */
	camv_rtree_box_t bbox;

	/* for loaders */
	struct {
		long ly;
	} loader;
};

struct camv_layer_s {
	camv_rtree_t objs;
	rnd_color_t color;
	char *name, *short_name;
	camv_design_t *parent;


	unsigned sub:1;       /* if 1, layer is a sub-layer in compositing; a main layer is the first of a series of composite layers; sub layers are not visible in the layer sel */
	unsigned vis:1;       /* for main layers: UI visibility */
	unsigned clearing:1;  /* if 1, the layer is negative, clearing layer */
	unsigned prefill:1;   /* if 1, fill screen with large positive poly before draw */
	unsigned enable_mx:1; /* if 1, apply mx (as a matrix transformation) when drawing */

	/* cache */
	rnd_xform_mx_t mx;    /* drawin/rendering mx transformation; does not affect bbox */
	double mx_sx, mx_sy, mx_rotdeg;
};

extern camv_design_t camv;

void camv_layer_init(camv_layer_t *layer);
camv_layer_t *camv_layer_new(void);

/* Create layer by unique name, return existing layer on name match, creates
   non-existing layer if alloc is non-zero; appends to design automatically */
camv_layer_t *camv_layer_by_name(camv_design_t *camv, const char *name, int alloc);

/* Returns index of the new layer (useful for camv_sublayer_append_after()) */
long camv_layer_append_to_design(camv_design_t *camv, camv_layer_t *layer);

/* Appends a (typically hidden) sublayer after the last layer of the group
   at idx; returns new idx for appending more sublayers */
long camv_sublayer_append_after(camv_design_t *camv, camv_layer_t *layer, long idx);

/* Invent a layer color for a main layer that has non set explicitly */
void camv_layer_invent_color(camv_design_t *camv, camv_layer_t *layer);

/* If layer is part of a design, remove it. Destroy all layer objects
   and free all memory allocated by the objects or the layer. */
void camv_layer_free_fields(camv_layer_t *ly);

/* Free all fields of layer and layer itself as well */
void camv_layer_destroy(camv_layer_t *layer);

int camv_layer_set_vis(camv_design_t *camv, rnd_cardinal_t lid, int vis, int emit_event);

void camv_design_free_fields(camv_design_t *camv);

int camv_is_empty(camv_design_t *camv);

void camv_data_bbox(camv_design_t *camv);

/* Change layer selection. -1 means none selected */
void camv_layer_select(camv_design_t *camv, int idx);

/* reverse order of layers loaded within a group but place the whole group on
   top (at the end of the vector) */
void camv_group_load_begin(camv_design_t *camv);
void camv_group_load_end(camv_design_t *camv);

void camv_data_reverse_layers(camv_design_t *camv, int inhibit_ev);

#define camv_hid_redraw(camv) rnd_render->invalidate_all(rnd_render)

extern char camv_measurement_layer_name[];

#endif
