/*
 *                            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_GRP_H
#define CSCH_CONCRETE_GRP_H
#include "libcschem/concrete.h"

/*** standard calls on groups ***/

csch_cgrp_t *csch_cgrp_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid);
void csch_cgrp_uninit(csch_cgrp_t *grp);
void csch_cgrp_free(csch_cgrp_t *grp);
csch_cgrp_t *csch_cgrp_get(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid);
void csch_cgrp_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform);
void csch_cgrp_attrib_update(csch_sheet_t *sheet, csch_cgrp_t *grp, int prio, const char *key, const char *val);
csch_cgrp_t *csch_cgrp_dup(csch_sheet_t *sheet, csch_cgrp_t *parent, const csch_cgrp_t *src, int keep_id);

csch_cgrp_t *csch_cgrp_init(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_cgrp_t *parent, csch_oid_t oid);

void csch_cgrp_render_all(csch_sheet_t *sheet, csch_cgrp_t *grp);
void csch_cgrp_xform_update(csch_sheet_t *sheet, csch_cgrp_t *grp);
void csch_cgrp_role_update(csch_sheet_t *sheet, csch_cgrp_t *grp);

/* Remove and free all child objects */
void csch_cgrp_clear(csch_cgrp_t *grp);

/* Returns the idxth abstract object generated for a grp from sheet's
   project's last compilation. Returns NULL if no such object or not compiled */
csch_ahdr_t *csch_cgrp_get_abstract(csch_sheet_t *sheet, const csch_cgrp_t *grp, long idx);

unsigned csch_cgrp_hash_(csch_cgrp_t *grp, csch_hash_ignore_t ignore);
int csch_cgrp_keyeq_(csch_cgrp_t *g1, csch_cgrp_t *g2, csch_hash_ignore_t ignore);


/*** standard calls on group refs ***/

csch_cgrp_t *csch_cgrp_ref_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid);
void csch_cgrp_ref_free(csch_cgrp_t *grp);
void csch_cgrp_ref_update(csch_sheet_t *sheet, csch_cgrp_t *grpref, int do_xform);

void csch_cgrp_modify(csch_sheet_t *sheet, csch_cgrp_t *grp, csch_coord_t *x, csch_coord_t *y, double *rot, int *mirx, int *miry, int undoable, int relative);
void csch_cgrp_modify_uuid(csch_sheet_t *sheet, csch_cgrp_t *grp, minuid_bin_t *uuid, minuid_bin_t *src_uuid, int undoable);


/*** non-standard calls on group refs ***/

/* remove all objects from the ref; NOTE: this converts some conns from
   object pointers back to object path list. The caller needs to update
   dirty conns. */
void csch_cgrp_ref_clean(csch_sheet_t *sheet, csch_cgrp_t *grpref);

/* copy objects from the referenced group; may call csch_cgrp_ref_clean(),
   thus may need conn dirty recalc, see csch_cgrp_ref_clean() */
void csch_cgrp_ref_render(csch_sheet_t *sheet, csch_cgrp_t *grpref);

/* Return an attribute by key, before the merge, considering both grpref and the referenced group */
csch_attrib_t *csch_cgrp_ref_get_attr(csch_cgrp_t *grpref, const char *key);

/* Convert a group ref into a group in-place */
void csch_grp_ref_embed(csch_cgrp_t *grpref);

/* Calculate cgrp's inverse transformation matrix in dst; useful for
   determining how a sheet coord system oepration translates into a
   group's coord system, e.g. when moving floaters */
void csch_cgrp_inverse_matrix(g2d_xform_t *dst, const csch_cgrp_t *cgrp);


void csch_cgrp_bbox_update(csch_sheet_t *sheet, csch_cgrp_t *grp);


/* Resolve referee from text version (oidpath) to pointer */
int csch_cgrp_ref_text2ptr(csch_sheet_t *sheet, csch_cgrp_t *grpref);

/* Encode pointer reference into textual ref (resets pointer ref to NULL) */
int csch_cgrp_ref_ptr2text(csch_sheet_t *sheet, csch_cgrp_t *grpref);

/* inverse-transform pairs of coords using parent's xform matrix; the v
   variant takes pairs of (csch_coord_t *x, csch_coord_t *y) and then a NULL */
void csch_cgrp_inverse_xform(csch_cgrp_t *parent, csch_coord_t *x, csch_coord_t *y, long num_crds);
void csch_cgrp_vinverse_xform(csch_cgrp_t *parent, ...);

/* Extract discrete transformations from a matrix */
double csch_cgrp_extract_rot(g2d_xform_t mx);
void csch_cgrp_extract_scale(g2d_xform_t mx, double *sx, double *sy);


#endif
