/*
 *                            COPYRIGHT
 *
 *  cschem - modular/flexible schematics editor - libcschem (core library)
 *  Copyright (C) 2018 Tibor 'Igor2' Palinkas
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.*
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA
 *
 *  Contact:
 *    Project page: http://repo.hu/projects/sch-rnd
 *    contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html
 *    mailing list: http://www.repo.hu/projects/sch-rnd/contact.html
 */


#ifndef CSCH_CONCRETE_POLY_H
#define CSCH_CONCRETE_POLY_H
#include "libcschem/concrete.h"
#include "libcschem/vtcoutline.h"

 /* type=CSCH_CTYPE_POLY */

typedef struct csch_cpoly_s {
	csch_chdr_t hdr;
	csch_vtcoutline_t outline; /* since it is made of lines and arcs, each object contains its spec and inst */
	unsigned has_stroke:1;     /* draw outline with pen if 1 */
	unsigned has_fill:1;       /* draw fill with solid color if 1 */

	/*** cached ***/
	double area;               /* for fill order; calculated by the app when needed, the lib sets it to -1 on any poly update */
} csch_cpoly_t;

csch_cpoly_t *csch_cpoly_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid);
csch_cpoly_t *csch_cpoly_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cpoly_t *src, int keep_id);
void csch_cpoly_free(csch_cpoly_t *poly);
csch_cpoly_t *csch_cpoly_get(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_oid_t oid);
void csch_poly_update(csch_sheet_t *sheet, csch_cpoly_t *poly, int do_xform);

/* fill in dst with outline's centerline bounding box */
void csch_cpoly_center_bbox(csch_sheet_t *sheet, const csch_cpoly_t *poly, csch_rtree_box_t *dst);


unsigned csch_cpoly_hash(const csch_cpoly_t *poly, csch_hash_ignore_t ignore);
int csch_cpoly_keyeq(const csch_cpoly_t *p1, const csch_cpoly_t *p2, csch_hash_ignore_t ignore);

int csch_cpoly_has_fill(csch_cpoly_t *poly);


void csch_cpoly_modify(csch_sheet_t *sheet, csch_cpoly_t *poly, int *has_stroke, int *has_fill, int undoable);

/* Call these to change poly outline in an undoable manner:
   - call begin() and save cookie
   - make modifications to the returned outline
   - call end() with the same cookie to finalize the changes
*/
csch_vtcoutline_t *csch_cpoly_modify_geo_begin(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie, int undoable);
void csch_cpoly_modify_geo_end(csch_sheet_t *sheet, csch_cpoly_t *poly, void **cookie);

/* Returns the contour object(s) near x;y with search "radius" r (really a
   query box width). Returns:
     - 0: no object found (x;y is within or outside of the poly)
     - 1: obj_idx[0] loaded (x;y is on the middle of a contour object)
     - 2: obj_idx[0] and obj_idx[1] loaded (x;y is near enough to a corner);
          the corner point is at obj_idx[0] end while obj_idx[1] start point */
int csch_poly_contour_objs_at(csch_cpoly_t *poly, csch_coord_t x, csch_coord_t y, csch_coord_t r, long obj_idx[2]);

/* Returns whether x;y is an endpoint of poly's idxth contour object. If idx
   is invalid, returns 0. */
int csch_poly_contour_obj_ends_at(csch_cpoly_t *poly, long idx, csch_coord_t x, csch_coord_t y);

#endif
