/****************************************************************************
    Copyright (C) 1987-2005 by Jeffery P. Hansen

    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., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************/
#ifndef __wires_h
#define __wires_h

#define NUMPOS 39

/* Split node directions */
#define IN_DIR 42
#define OUT_DIR 7

/* wire_makestrait conditions */
#define OK 42
#define IMMOBILE 0

/* Wire selction modes (These are bit masks) */
#define UNSELECTED	0x0
#define HORIZONTAL	0x1
#define VERTICAL	0x2
#define FULL		0x3
#define NOSTRAITEN	0x4

#define DRIVER 42
#define DRIVEE 0
#define UNKNOWN 8

/* Hit Operations */
#define F_GATE 0x01
#define F_WIRE 0x02
#define F_WIREEND 0x12
#define F_WIRENOEND 0x22

struct locate {
	int x1,y1,x2,y2,dir;
	};

#define D_RIGHT 0
#define D_UP 1
#define D_LEFT 2
#define D_DOWN 3

void wire_free(GWire*);
void wirenode_free(GWireNode*);

GWire *wire_unattach();

GWire *wirenode_driver(GWireNode*);
GWire *wirenode_drivee(GWireNode*);

GWire *wire_driver(GWire*);
GWire *wire_drivee(GWire*);
GWire *wire_other(GWire *w);

GWire *wire_append(GWire *wl,GWire *w);

GWireNode *wire_newnode();

void wire_gateadd(GCElement *g,GModuleDef *mdef,GWire *e1,GWire *e2,int p,int dir,int invertp);
int wire_addToGate(GCElement *g,int p,char *n,GModuleDef *mdef,int invertp);
int wire_new(GModuleDef *mdef,GWire **e,GWire **e2);
int wire_newNetSegment(GModuleDef *mdef,GNet*,GWire **e,GWire **e2);

GWireList *wire_unlink(GWireList *wl,GWire *w);
GWireList *wire_link(GWireList *wl,GWire *w);

char *wire_removeName(GWire*);
void wire_setName(GWire*,char*);
GWire *wire_sigroot(GWire*);

GWire *wire_newend(GModuleDef *M,GNet*,int doNode);
void wire_setNet(GWire *w,GNet *net);

void wire_move(GWireNode *n,int dx,int dy,int type);

GWireNode *wire_iohit(int,int,GWireList*);
GWireNode *wire_hitanynode(int,int,GWireList*);
GWireNode *wire_hitall(int,int,GWireList*);
GWireNode *wire_hit(int,int,GWireList*);
GWire *wire_endhit(GWire*,GWireList*);
GWireNode *wire_hit_other(GWire*,GWireList*);

void wire_snapgate(GCElement *g,int doRedraw);
void wire_snap(GWireNode *n);


GWire *wire_connect(GModuleDef *env,GWire *w1,GWire *w2);
GWireNode *wire_makecorner(GWireNode *n,int tx,int ty);


int wire_shorten(GWire*,GModuleDef*,int drawp);
int wire_nuke(GWire*,int,GModuleDef*);
int wire_trash(GWireNode*,GModuleDef*,int drawp);
int wire_trashin(GWireNode*,GModuleDef*,int drawp);
int wire_trashout(GWireNode*,GModuleDef*,int drawp);
void wire_drawnet(GWire *w);
void wire_draw(GWireNode *);
void wire_deletezeronodes(GWireNode *n);
void wire_finalizeNet(GWire *w);
void wire_cut(int x,int y,GWireNode *n,GModuleDef *env);
void wire_makestraitaux(GWireNode *n,int wt,int ox,int oy,int nx,int ny);
void wire_setPadSpacing(GCElement *g,int p);
void wire_deletenode(GWireNode *n);
int wire_force(GWire *w,int d,int retry);
void wire_drawlist(GWire *w,GCElement *g);
GWire *wire_findClosest(GWire*,int,int);
void wire_addstub(EditState *es,int x,int y);

GWireNode *wirenode_cutsegment(int,int,GWireNode *,GModuleDef *);
GWireNode *wirenode_cutcorner(GWireNode *,GModuleDef *);

void joint_connect(GCElement *g,GWireNode *n);
void joint_make(int x,int y,GWire *w1,GWire *w2,GWire *w3,GWire *w4,EditState *es);
void joint_fixwires(GCElement *j,GWire *w,int retry);
int joint_dejoint(GWireNode *n,GModuleDef *env,int drawp);
void joint_addstub(GCElement *g,EditState *es);

GCElement *join_wires(GWire *w,GWireNode *n,EditState *es);
void join_wirereverse(GWire *w);
void join_treereverse(GWire *w);
void join_treereverse_aux(GWire *w);

void tap_transmute(GWire *branch,EditState *es);

GNet *net_new(const char*,GModuleDef*);
GNet *net_newCompatable(const char*,GNet*,GModuleDef*);
void net_delete(GNet*);
GNet *net_pickOne(GNet*,GNet*,int);
void net_decref(GNet*);
void net_incref(GNet*);
void net_update(GNet *n);
int net_connectOK(GNet *n1,GNet *n2,int isMidWire);
void net_setSize(GNet *net,int nbits);
void net_rename(GNet *net,const char *s,int showName);
void net_draw(GNet*);
void net_select(GNet *n,int drawp);
void net_unselect(int drawp);

int listNets(GModuleDef *mdef);

void setwiresize(EditState *es);
void SignalNamePos(GWire *w,int *x,int *y,int *p,int *q);

int wireorient(GWireNode *n,int d);
void freenodelist(GWireNode *n);
void createwire(GModuleDef *e,GCElement *g,int p,int invertp);

void wire_dump(EditState *es);
int wire_numOnPad(GWire *w);

#endif


