/*
 *                            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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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_CONN_H
#define CSCH_CONCRETE_CONN_H
#include "libcschem/concrete.h"
#include "libcschem/vtoidpath.h"

/* type=CSCH_CTYPE_CONN */

typedef struct csch_conn_s {
	csch_chdr_t hdr;
	vtp0_t conn;                /* (csch_chdr_t *); xorcache: if not empty, ->conn_path is empty */
	csch_oid_t gfx;
	unsigned dirty:1;           /* mark connections that need to be updated */

	/* cache: file I/O version */
	csch_vtoidpath_t conn_path; /* xorcache: if not empty, ->conn is empty */

	/* cache/debug: coordinates of connection points in x1;y1;x2;y2 lines form */
	vtl0_t coords;
} csch_conn_t;

csch_conn_t *csch_conn_alloc(csch_sheet_t *sheet, csch_cgrp_t *parent, csch_oid_t oid);
void csch_conn_free(csch_conn_t *conn);
csch_conn_t *csch_conn_get(csch_sheet_t *sheet, csch_oid_t oid);
void csch_conn_update(csch_sheet_t *sheet, csch_conn_t *conn, int do_xform);

/* Add drawing obj in a connection; returns -1 if it is already in */
int csch_conn_add_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable);

/* Del obj from a connection; returns -1 if it is not in */
int csch_conn_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj, int undoable);

/* Undoable connection creation between obj1 and obj2; automatically reuses
   existing shared conn or creates a new conn object; addi returns the index of
   conn in obj1 (or -1 on error) */
csch_conn_t *csch_conn_auto_add(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2);
long csch_conn_auto_addi(csch_sheet_t *sheet, csch_chdr_t *obj1, csch_chdr_t *obj2);

/* Undoable conn obj remove; if conn becomes empty or single-object, the
   conn is removed too. */
int csch_conn_auto_del_obj(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *obj);

/* Remove all connections of an object using auto_del */
int csch_conn_auto_del_obj_all(csch_sheet_t *sheet, csch_chdr_t *obj);

/* Automatically recalculate connections of an object (e.g. wire or
   terminal). Recursive for groups. Always undoable. */
void csch_conn_auto_recalc(csch_sheet_t *sheet, csch_chdr_t *obj);

/* Recursive recalc the geometry of connection objects; does not add or remove
   connections. Since conn geo is not saved, there is nothing to be undone */
void csch_conn_auto_recalc_geo(csch_sheet_t *sheet, csch_chdr_t *obj);


/* Convert conn's oid-path field into object pointers */
void csch_conn_text2ptr(csch_sheet_t *sheet, csch_conn_t *conn);

/* Convert conn's object pointers into the oid-path field; useful if some an
   object is recreated (changing pointer), which would make the object's
   old dangling pointer remain in the pointer vector */
void csch_conn_ptr2text(csch_sheet_t *sheet, csch_conn_t *conn);


/* Return an existing connection if owner's (maybe currently removed) conn
   could be merged into it. Useful when owner is moved from one group to
   another: its connections need to be moved but if there are existing conn
   in the target group overlapping, that is returned here and should be
   reused/extended. */
csch_conn_t *csch_conn_find_mergable(csch_sheet_t *sheet, csch_conn_t *conn, csch_chdr_t *owner);

/* Update all connections that are marked dirty, recursively */
void csch_conn_update_dirties(csch_sheet_t *sheet, csch_cgrp_t *grp, int do_xform);

#endif
