///////////////////////////////////////////////////////////////////////
//
// File: linkops.cc
//
// Description:
//
// This file contains all BDE code responsible for controlling link operations.
// The code has been taken from the BDE 1.0 buttondown.cc, buttonup.cc
// and buttonmoved.cc files.
//
// History:
//
// 94/7/18: RJL added sample code (comments) to the stub for link_delete
// 05/02/93 rboccuzz created.
//
// $Log: linkops.cc,v $
// Revision 1.3 1995/05/13 02:32:59 hcpatel
// Implemented corrected state models for link create and link delete operations.
//
// Revision 1.2 1995/04/04 04:41:29 cgopal
// File bde20 and others were fixed so that multiple definitions
// of variables were eliminated. All enumarated types were capitializes and give
// n a prefix.
//
// Arguments to XtAddcallback was casted to the right type. Handler.cc
// was also fixed to use right variables.
//
// Revision 1.10 1994/08/23 01:48:26 lechner
// added sample code (comments) to the stub for link_delete
//
// Revision 1.9 1994/05/07 23:42:23 dgrant
// In routine link_create changed calls from infomessage to
// displayMessage.
//
// Revision 1.8 1994/04/16 17:19:31 tseeley
// Changed global Filename to current_filename.
//
// Revision 1.7 1994/04/01 00:06:57 mtorpey
// fixed problem with genv8 changes.
//
// Revision 1.6 1994/03/31 19:21:37 namin
// version 8 changes
//
// Revision 1.5 1994/03/12 16:44:31 lking
// Added the include file "prototype.h" which contains all the function
// declarations. Removed all external function declarations from this file.
//
// Revision 1.4 1994/03/11 22:18:55 lking
// Removed debug printf statements from the file.
//
// Revision 1.3 1994/03/11 20:58:51 lking
// Reformatted the header comment to make it more readable. Move rcsid
// below the header comment.
//
// Revision 1.2 1994/03/09 18:27:44 jrichard
// Added a rcs log replacement statement to all .cc files as part of the
// header comment. THis places all checkin comments directly into the
// header comment.
//
///////////////////////////////////////////////////////////////////////

#ifndef lint
static char rcsid[] =
"$Id: linkops.cc,v 1.3 1995/05/13 02:32:59 hcpatel Exp $";
#endif

/********************** System include files *******************************/
#include <strings.h>
#include <stdio.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
/********************** Program include files ******************************/
#include "tags.h"
#include "bde.h"
#include "graph.h"
#include "state.h"
#include "prototype.h"

/********************** Macro defines **************************************/
/********************** Global and external variables **********************/

extern char *current_filename;

extern Widget canvas;
extern float selectedx, selectedy;
extern Select selected;
extern Cursor arrow, dot, addcross, pirate;
extern graphobject *currentselection;


/***************************************************************************
* Name:
* void link_create(XButtonEvent*, int, link_attributes*, int)
* Added by:
* ???
* Modified by:
* hcpatel & mmaliset - bdesrc 95s523
* A generic selection routine, select_HN(), is used to select a Node for
* source and destination objects. This implements improved state model
* suggested by Prof. Lechner.
* Description:
* Link Create performs the creation of the links. It does this
* based on the button event and state information passed to it.
* All code within this function was lifted from the button*.cc files.
* button_op is one of : BUTTON_UP, BUTTON_DOWN, BUTTON_MOVED
* Uses:
* DCtoWC(), Ggroup method select_HN(widget, int, int), changeCanvasCursor()
* Ggroup->addlink(), displayMessage(), unselect()
* Side effects:
* NONE.
* Error Handling:
* NONE
***************************************************************************/

void link_create (XButtonEvent *event, int state, /* Canvas State */
link_attributes *attribute, int button_op)
{
float sx, sy;
static graphobject *firstselect;

DCtoWC(event->x, event->y, &sx, &sy);

switch (state) {

case SArrow:
switch (button_op) {

case BUTTON_DOWN_EVENT:
topobject->select_HN(canvas, (int)sx, (int)sy);
firstselect = currentselection;
break;

case BUTTON_UP_EVENT:
topobject->select_HN(canvas, (int)sx, (int)sy);
/* Create link only if firstselection and second selection
both are separate Nodes */
if (currentselection != NULL && firstselect != NULL) {
if ( firstselect != currentselection) {
topobject->addlink(firstselect, currentselection);
} else
displayMessage("Self loop is not implemented yet\n");
} else
displayMessage("Selected source/destination is not a Node\n");
changeCanvasCursor(addcross);
unselect();
break;

case BUTTON_MOVED_EVENT:
if(currentselection != NULL)
changeCanvasCursor(dot);
displayMessage("Choose the destination Node of Link\n");
break;
default: /* illegal value for button_op variable */
//add PostErrorMsg() to handle error message - phsia 12/8/95
PostErrorMsg(SArrow);
break;
}
break;


default: /* illegal value for state variable */
fprintf(stderr, "Out of State in function link_create.\n");
fprintf(stderr, "switch on state\n");
fprintf(stderr, "Report this to Professor Lechner.\n");
break;
}

}
// end void link_create()

/***************************************************************************
* Name:
* void link_delete(XButtorEvent*, int, link_attributes*, int)
* Added by:
* ???
* Modified by:
* hcpatel & mmaliset - bdesrc 95s523
* A generic selection method select_HL is used to select a link from the
* object list. This implements improved state model suggested by
* Prof. Lechner.
* Description:
* Link Delete performs the deletetion of one link and all
* its labels and bendpoints (HI and HP children). It does this
* based on the button event and state information passed to it.
* All code within this function was lifted from the button*.cc files.
* button_op is one of: BUTTON_UP, BUTTON_DOWN, BUTTON_MOVED
* Uses:
* DCtoWC(), select_HL(widget, int, int), changeCanvasCursor(),
* selected.changeAttribState(), docut()
* Error handling:
* NONE.
* Side effects:
* NONE.
***************************************************************************/


void link_delete (XButtonEvent *event, int state, /* Canvas State */
link_attributes *attribute, int button_op)
{
float sx, sy;
static graphobject *selected_link = NULL;

DCtoWC(event->x, event->y, &sx, &sy);

switch (state) {

case SDlink1:
switch (button_op) {

case BUTTON_DOWN_EVENT:
topobject->select_HL(canvas, (int)sx, (int)sy);
selected_link = currentselection;
if(currentselection != NULL) {
selected.changeAttribState(SDlink2);
changeCanvasCursor(pirate);
}
break;

case BUTTON_UP_EVENT:
break;

case BUTTON_MOVED_EVENT:
break;
default:
//add PostErrorMsg() to handle error message - phsia 12/8/95
PostErrorMsg(SDlink1);
break;
}
break;


case SDlink2:
switch (button_op) {

case BUTTON_DOWN_EVENT:
topobject->select_HL(canvas, (int)sx, (int)sy);
if (currentselection != NULL &&
selected_link == currentselection) {
docut((Widget) 0,0,0);
selected.changeAttribState(SDlink1);
changeCanvasCursor(arrow);
} else
selected_link = currentselection;
break;

case BUTTON_UP_EVENT:
break;

case BUTTON_MOVED_EVENT:
break;
default: /* illegal value for button_op variable */
//add PostErrorMsg() to handle error message - phsia 12/8/95
PostErrorMsg(SDlink2);
break;
}
break;

default: /* illegal value for state variable */
fprintf(stderr, "Out of State in function node_delete.\n");
fprintf(stderr, "switch on state\n");
fprintf(stderr, "Report this to Professor Lechner.\n");
break;
}

}
// end void link_delete()

/***************************************************************************
* Description:
* Link Move performs the moving of the links. It does this
* based on the button event and state information passed to it.
* All code within thei function was lifted from the button*.cc files.
*
* Error handling:
* NONE.
* Side effects:
* NONE.
***************************************************************************/

void link_move (XButtonEvent *event, int state, link_attributes *attribute,
int button_op) /* BUTTON_UP, BUTTON_DOWN, BUTTON_MOVED */
{
/* Stub function, not written yet */
}


/***************************************************************************
* Description:
* Reverse Arrow performs the reversing of the direction of link arrow
* It does this based on the button event and state information passed
* to it. All code within their function was lifted from the
* buttonevent.cc files.
*
* Error handeling:
* NONE.
* Side effects:
* NONE.
**************************************************************************/

extern float savedx, savedy;


void reverse_arrow (XButtonEvent *event, int state, /* Canvas State */
link_attributes *attribute, int button_op)
{
float sx, sy;
#ifdef GENV6
char *id;
#else
hcg_key id;
#endif
int chen_pcount, chen_num;

DCtoWC(event->x, event->y, &sx, &sy);

switch (state) {
/* Reverse the direction of the link */

case SReverse:
switch (button_op) {

case BUTTON_DOWN_EVENT:
unselect();
unselect();
selection(canvas,(int)sx,(int)sy);
break;

case BUTTON_MOVED_EVENT:
break;

case BUTTON_UP_EVENT:
if(currentselection != 0) {
#ifdef GENV6
id = currentselection->getid();
#else
id = (hcg_key)currentselection->getid();
#endif
pr_find(HN, HNid, id);
if (HNcurr != NULL){
unselect();
currentselection = 0;
} else {

pr_find(HL, HLid, id);
if (HLcurr != NULL)
selected.changeAttribState(SReverse_Arrow);
}
}
break;

default: /* illegal value for button_op variable */
//add PostErrorMsg() to handle error messsage - phsia 12/8/95
PostErrorMsg(SReverse);
break;
}
break;

/* Reverse the link arrow */

case SReverse_Arrow:
switch (button_op) {

case BUTTON_DOWN_EVENT:
unselect();
selection(canvas,(int)sx,(int)sy);
chen_num=0;

if(currentselection != 0) {
#ifdef GENV6
id = currentselection->getid();
#else
id = (hcg_key)currentselection->getid();
#endif
pr_find(HL,HLid,id);

if (HLcurr != NULL){
chen_pcount = HLcurr->HPcount - 1;
child_loop(HL,HP,HPid,HLid) {
if (HPcurr != NULL){
if (chen_num == chen_pcount) {
switch(HPcurr->hsegpattern[0]){
case '0':
case 'P':
HPcurr->hsegpattern[0] = '1';
break;
case '1':
HPcurr->hsegpattern[0] = '2';
break;
case '2':
HPcurr->hsegpattern[0] = '0';
break;
default:
break;
}
} else {
switch(HPcurr->hsegpattern[0]){
case 'P':
HPcurr->hsegpattern[0] = '0';
break;
default:
break;
}
}
}
chen_num++;
}
} else {
unselect();
currentselection = 0;
}
}
break;

case BUTTON_MOVED_EVENT:
break;

case BUTTON_UP_EVENT:
if(currentselection != 0){
ReDraw();
}
break;

default: /* illegal value for button_op variable */
//add PostErrorMsg() to handle error messsage - phsia 12/8/95
PostErrorMsg(SReverse_Arrow);
break;
}
break;


default: /* illegal value for state variable */
fprintf(stderr, "Out of State in function reverse_arrow().\n");
fprintf(stderr, "switch on state\n");
fprintf(stderr, "Report this to Professor Lechner.\n");
break;
}

}



/*------------------ ReDirection -------------------------
void dirdo()
{
FILE *dir_file;
void loadobjects(char*);
void clearObjects();

if((dir_file = fopen("wchen","r")) == NULL){
return;
}

clearObjects();
pr_free();
loadobjects("wchen");

}
*/