/*
 * Generated by the ICS builderXcessory (BX).
 *
 *
 * Builder Xcessory 1.0.1.
 *
 */
#include <Xm/Xm.h>
#include <Text.h>
#include <stdio.h>
#include <strings.h>

#include "widgets.h"  /* list of globally defined widgets */
#include "errors.h"  /* error messages */

#include "params.h"  /* lucy-specific constants */

#include "hes.h"    /* help editing system */

static Arg args[64];  /* make these global vars local to this file */
static int argcnt;

static text_status = 0; /* 0 means no text entered.
			   1 means text has been entered.
			   2 means that text has been saved.
			   */


extern void Get_Subjects(void);
extern void Get_Transaction(int, char *, int);

extern struct {
  char subject[LINE_SIZE];
  int tnum; /* transaction number */
} browser[BROWSER_MAX];


extern struct {
  char name[HELPNAMSIZE];
  char buffer[HELPBUFSIZE];
  } hw[MAXWIND]; /* hw[MAXWIND]; */ /* allow up to MAXWIND help screens */


extern int num_browser; /* keeps track of how many subjects are in browser */  
  
static Boolean help_on = False; /* true means that help screen is onscreen */

static char text[QUESTION_SIZE]; /* text of question */

/* browser--up to BROWSER_MAX topics can be displayed at a time.
   each topic can be up to 128 characters long. */

static XmString browser_xm[BROWSER_MAX]; 

void free_strings(strarray, index)
     XmString strarray[];
     int index;

{
  int i;
  /* call XmFree for each string in the array */

  for (i=0; i < index; i++) {
    XmStringFree(strarray[i]);
  }
}

void lucyCallback(w, client, call)
     Widget w;
     caddr_t client;
     caddr_t call;

{

  static char mess[] = "\n\nLucy \n\
User Interface Created by \n\
UChin Kim, May 1991.\n\
\n\
\n\
With help from:\n\
the Builder Xcessory (Integrated Computer Solutions, Inc.) &&\n\
Bruce R. Lewis.\n\n";



    
  /* display a message containing information about lucy program */
  Widget info;
  XmString xm_mess; /* compound string */
  Widget bad_child; /* use to get rid of help and cancel buttons */
  void ErrorOKed();  /* callback procedure */

  argcnt = 0;
  xm_mess = XmStringCreateLtoR(mess, XmSTRING_DEFAULT_CHARSET);
  XtSetArg(args[argcnt], XmNmessageString, xm_mess); argcnt++;
  XtSetArg(args[argcnt], XmNmessageAlignment, XmALIGNMENT_CENTER); argcnt++;
  info = (Widget) XmCreateInformationDialog(w, "error", args, argcnt);

  /* get rid of help and cancel buttons because we don't need them. */
  bad_child = (Widget) XmMessageBoxGetChild(info, XmDIALOG_CANCEL_BUTTON);
  XtUnmanageChild(bad_child);
  bad_child = (Widget) XmMessageBoxGetChild(info, XmDIALOG_HELP_BUTTON);
  XtUnmanageChild(bad_child);  


  XtAddCallback(info, XmNokCallback, ErrorOKed, NULL);  /* free up mem */  
  XtManageChild(info);  
  XmStringFree(xm_mess); /* free the compound string space we have allocated */

}


void
DialogCancelCallback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
#ifdef DEBUG_LUCY
  fprintf(stderr, "Dialog Cancelled.\n");
#endif
  
  XtUnmanageChild(DialogbulletinBoard);   

}

void ErrorOKed(w, client, call)
     Widget w;
     caddr_t client;
     caddr_t call;
{

  XtDestroyWidget(w);  /* free up the memory associated with the widget */
}

void ExplainError(w, mess)
     Widget w;  /* parent widget */
     char *mess; /* error message */

{
  Widget mess_box;
  XmString xm_mess; /* compound string */

  Widget bad_child; /* use to get rid of help and cancel buttons */

#ifdef DEBUG_LUCY

  fprintf(stderr, mess);
#endif

  /* create an error dialog box */

  argcnt = 0;
  xm_mess = XmStringCreateLtoR(mess, XmSTRING_DEFAULT_CHARSET);
  XtSetArg(args[argcnt], XmNmessageString, xm_mess); argcnt++; 
  mess_box = (Widget) XmCreateErrorDialog(w, "error", args, argcnt);


  XtAddCallback(mess_box, XmNokCallback, ErrorOKed, NULL);   
  XtManageChild(mess_box);

  /* get rid of help and cancel buttons because we don't need them. */  
  bad_child = (Widget) XmMessageBoxGetChild(mess_box, XmDIALOG_CANCEL_BUTTON);
  XtUnmanageChild(bad_child);
  bad_child = (Widget) XmMessageBoxGetChild(mess_box, XmDIALOG_HELP_BUTTON);
  XtUnmanageChild(bad_child); 


  XmStringFree(xm_mess); /* free the compound string space we have allocated*/
  
#ifdef DEBUG_LUCY  
  fprintf(stderr, "Just managed the error box. \n");
#endif
  
}

     


void
DialogOKCallback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  /* data from dialog window */
  Boolean pubYes, pubNo, replyYes, replyNo;
  char *edit; /* temp var. */

  char subject[LINE_SIZE], username[LINE_SIZE]; 
  char reply[LINE_SIZE], publish[LINE_SIZE];
  
  Boolean errored;

    errored = False;  
#ifdef DEBUG_LUCY
  fprintf(stderr, "Dialog OKed.\n");
#endif
  
  
  /* get information from dialog box */
  /* need to get: subject text, publish toggles, reply toggles, send reply to
     text */
  /* then, check the data for errors, inconsistencies, --- error handling. */
  /* then, send it by mail, using Bruce's code */

  edit = XmTextGetString(subjecttext); /* get contents of subjecttext widget */
  strncpy(subject, edit, LINE_SIZE);
  XtFree(edit);

  edit = XmTextGetString(persReplytext);
  strncpy(username, edit, LINE_SIZE);
  XtFree(edit);

  pubYes = XmToggleButtonGetState(publishYestoggle);
  pubNo  = XmToggleButtonGetState(publishNotoggle);
  replyYes = XmToggleButtonGetState(replyYestoggle);
  replyNo = XmToggleButtonGetState(replyNotoggle);
  
/*
  if (pubYes == True) fprintf(stderr, "PublishYes on.\n");
  if (pubNo == True) fprintf(stderr, "PublishNo on. \n");
  if (replyYes == True) fprintf(stderr, "ReplyYes on.\n");
  if (replyNo == True) fprintf(stderr, "ReplyNo on.\n");
*/
  /* possible errors:
     1. pubNo and replyNo are both True.
     2. replyYes is True but username is empty.
     3. pubYes and pubNo are both False.
     4. replyYes and replyNo are both False.
     5. No subject is provided.  --- delete this one, not necessary.
     */

    /* handle case 1 */
    if ( (pubNo == True) && (replyNo == True) ) {
      errored = True;
      ExplainError(DialogbulletinBoard, Error1);
    }

    /* handle case 2 */
    if ( (replyYes == True) && (strlen(username) == 0) ) {
      errored = True;
      ExplainError(DialogbulletinBoard, Error2);
    }

    /* handle case 3 */
    if ( (pubYes == False) && (pubNo == False) ) {
      errored = True;
      ExplainError(DialogbulletinBoard, Error3);
    }

    /* handle case 4 */
    if ( (replyYes == False) && (replyNo == False) ) {
      errored = True;
      ExplainError(DialogbulletinBoard, Error4);
    }


    
  if (errored == False) {  /* concatenate all the information */
    XtUnmanageChild(DialogbulletinBoard);

    /* collate everything before sending it */
    if (replyYes == True) {
      strcpy(reply, username);
    } else {
      strcpy(reply, "ANONYMOUS (NO REPLY)");
    }
    
    if (pubYes == True) {
      strcpy(publish, "Yes.");
    } else {
      strcpy(publish, "No.");
    }
#ifdef DEBUG_LUCY

    fprintf(stderr, "Subject: %s\n\n", subject);
    fprintf(stderr, "%s\n", text);
    fprintf(stderr, "SEND PERSONAL REPLY TO: %s\n", reply);
    fprintf(stderr, "PUBLISH QUESTION/ANSWER IN BROWSER: %s\n", publish);
    fprintf(stderr, "---END OF FILE---\n");
#endif


    luc_ask(subject, text, reply, publish); 

    text_status = 0;  /* Question is gone, has been sent via mail */
#ifdef DEBUG_LUCY

    fprintf(stderr, "empty buffer \n");
#endif
    
    
  } /* end of if (errored == False) */
#ifdef DEBUG_LUCY
  fprintf(stderr, "at end of DialogOKed routine \n");
#endif
}


void
EnterQuestionCB(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  static char prompt[] = "Question:  ";
  int plength = strlen(prompt);
  
  
  XmTextSetString(lucytext, prompt); /* display prompt */

  /* set the cursor position, make it visible, and make it editable */
  argcnt = 0;
  XtSetArg(args[argcnt], XmNcursorPosition, plength); argcnt++;
  XtSetArg(args[argcnt], XmNcursorPositionVisible, True); argcnt++;
  XtSetArg(args[argcnt], XmNmaxLength, QUESTION_SIZE); argcnt++;

  XtSetArg(args[argcnt], XmNautoShowCursorPosition, True); argcnt++;
/*  XtSetArg(args[argcnt], XmNblinkRate, 0); argcnt++; */
  XtSetValues(lucytext, args, argcnt);
  XmTextSetEditable(lucytext, True);
#ifdef DEBUG_LUCY

  fprintf(stderr, "Enter text to edit.\n");
#endif

  
  /* now let user edit text */
  text_status = 1; /* text is being entered */
#ifdef DEBUG_LUCY
  fprintf(stderr, "text is being entered \n");
#endif

}

void
Exit_Callback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  /* unmanage the help window */
  
  if (help_on == True) {
    help_on = False;
    XtPopdown(Shell001);
  }

}

void
GetHelpCallback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  static Boolean initialize_help = True; /* only load help windows once */
  void HelpItemSelectCallback();
  static XmString help_topics[MAX_HELP];
  static int num_topics = 0;  /* number of topics available in help */
  int i;  
#ifdef DEBUG_LUCY

  fprintf(stderr, "Invoked GetHelp routine.\n");
#endif
  
  
  /* check to see if Shell001 is displayed.  If not, then Pop it up.
     */
  if (help_on == False) {
    help_on = True;

    if (initialize_help == True) {
      initialize_help = False;
#ifdef DEBUG_LUCY

      fprintf(stderr, "Initializing helplist widget.\n");
#endif

      
      load_windows(HELPFILE);
      /* hw[] now contains help window names and buffers. */
      /* convert help window names to an array of XmStrings */
      /* store pointer to array of XmStrings in helplist widget */
      /* store number of elements in the array in helplist widget also */

      for (i = 0; i < num_windows; i++) {
	help_topics[i] = XmStringCreateLtoR(hw[i].name, XmSTRING_DEFAULT_CHARSET);
	num_topics++;
	/* allow only up to MAX_HELP topics */
	if (i >= MAX_HELP) num_windows = MAX_HELP;  
      }

      /* add the following stuff to helplist widget */
      /*******/
      argcnt = 0;
      XtSetArg(args[argcnt], XmNitemCount, num_topics); argcnt++;  
      XtSetArg(args[argcnt], XmNitems, help_topics); argcnt++;   
      XtSetArg(args[argcnt], XmNvisibleItemCount, 5); argcnt++;
      
      XtSetValues(helplist, args, argcnt);

      free_strings(help_topics, num_topics); /* free the XmString space */

      /* also set the helptext widget to noneditable */
      XmTextSetEditable(helptext, False);
    } /* end of one shot initialization routine for helplist */
    
    XtPopup(Shell001, XtGrabNone); 
  } /* end of handler to put help screen on */
  else {
    ExplainError(w, HelpAlreadyOn);
  }
}

void HelpItemSelectCallback(w, client, call)
Widget w;
caddr_t client;
XmListCallbackStruct *call;

{  /* routine to handle when user selects a help item. */
  int n;
  char name[LINE_SIZE];
  char buffer[HELPBUFSIZE];  /* in hes.h */

  n = call->item_position - 1;
  strncpy(name, hw[n].name, LINE_SIZE);
  strncpy(buffer, hw[n].buffer, HELPBUFSIZE);
#ifdef DEBUG_LUCY

  fprintf(stderr, "Help item selected.\n");
  fprintf(stderr, "You selected item: %s with position number %d \n",
	name, n);
  fprintf(stderr, "Contents of window: \n%s\n--End of Window--\n", buffer);
#endif
  
  

  XmTextSetString(helptext, buffer);  /* display text in window */
}

	     
void
QuitCallback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{

  /* works */
  
	XtCloseDisplay(XtDisplay(w));  /* exit lucy program */
	exit(0); 
}


void
SendQuestionCB(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  char *edit;

  if (text_status == 0) { /* no text has been entered */
#ifdef DEBUG_LUCY

    fprintf(stderr, "empty buffer \n");
#endif
    
    
    /* pop up an error dialog */
    ExplainError(w, ErrorNoQuestionText);
#ifdef DEBUG_LUCY

    fprintf(stderr, "error popup: No Text has been entered. \n");
#endif
    return; /* don't continue with SendQuestion */
  }
  if (text_status == 1) { /* text entered, but not saved. */
#ifdef DEBUG_LUCY

    fprintf(stderr, "text has been entered. \n");
#endif
    
    
      XmTextSetEditable(lucytext, False); /* prevent further editing */
    edit = (char *) XmTextGetString(lucytext);
    /* remember to handle empty string error here */
  strncpy(text, edit, 10000);
  XtFree(edit);
}
  /* if text_status == 2, then text has previously been saved,
     and we need not save it again . */
  if (text_status == 2) {
#ifdef DEBUG_LUCY

    fprintf(stderr, "text has been saved to text[] \n");
#endif
    
    
  }
#ifdef DEBUG_LUCY

  fprintf(stderr, "You entered <%s> \n", text);
#endif
  

  
  /* and now pop up some dialog window to get additional info */
  XtManageChild(DialogbulletinBoard);

}


void get_topics_list()
{
  /* get_topics_list gets a list of topics from the meetings server
     and places them in browser[]..  also sets num_browser to the
     number of topics in the browser array.  */

  /* currently, this is a stub routine */

/*  some old stub code.
  int i;

  for (i=0; i < ; i++) {
    strncpy(browser[i].subject, hw[i].name, LINE_SIZE);

#ifdef DEBUG_LUCY

    fprintf(stderr, "browser[%d] = %s \n", i, browser[i].subject);
    fprintf(stderr, "hw[%d].name = %s \n", i, hw[i].name);

#endif    
    num_browser++;
  }
*/

  Get_Subjects();  
}



void
ViewBrowserCallback(w, client, call)
Widget w;
caddr_t client;
caddr_t call;
{
  static one_shot = True;
  int i;
  /* display CB's for transaction select.  add scroll CBs or enable them.
     add CBs for transaction select.  set a flag to indicate that
     we are in browser mode */
#ifdef DEBUG_LUCY

  fprintf(stderr, "In View Browser.\n");
#endif
  
  

  if (one_shot == True) {
    one_shot = False;
    get_topics_list();  /* get the list of topics from the meetings server */
    /* list of topics is now stored in browser[]...
       and num_browser tells us how many topics are in browser */

    for (i = 0; i < num_browser; i++) {
      browser_xm[i] = XmStringCreateLtoR(browser[i].subject,
					 XmSTRING_DEFAULT_CHARSET);
    }
    argcnt = 0;
    XtSetArg(args[argcnt], XmNitemCount, num_browser); argcnt++;  
    XtSetArg(args[argcnt], XmNitems, browser_xm); argcnt++;   
    XtSetArg(args[argcnt], XmNvisibleItemCount, 10); argcnt++;
    XtSetValues(lucylist, args, argcnt);
    free_strings(browser_xm, num_browser);
    XmTextSetEditable(lucytext, False);
  } /* end of one_shot deal */

}



void BrowserSelectCallback(w, client, call)
     Widget w;
     caddr_t client;
     XmListCallbackStruct *call;     

{
  int n;  /* selection number */
  int tnum;  /* transaction number */
  char name[LINE_SIZE];
  static char buffer[QUESTION_SIZE];
  char * edit;

  if (text_status == 1) {  /* question has been previously entered, but
			      not saved. */
#ifdef DEBUG_LUCY

    fprintf(stderr, "text has been entered but not saved. \n");
#endif
    

    edit = (char *) XmTextGetString(lucytext);    
    strncpy(text, edit, HELPBUFSIZE);
    text_status = 2; /* question has been saved */
    XtFree(edit);    
  }

  /* code to handle a browser selection */
#ifdef DEBUG_LUCY

  fprintf(stderr, "You selected something in the browser \n");
#endif
  
  

  n = call->item_position - 1;

  tnum = browser[n].tnum; /* get the transaction number for this item */
  bzero(buffer, QUESTION_SIZE);  /* clear buffer */
  Get_Transaction(tnum, buffer, QUESTION_SIZE);
/*  old code...
  strncpy(name, hw[n].name, LINE_SIZE);
  strncpy(buffer, hw[n].buffer);
*/
#ifdef DEBUG_LUCY

  fprintf(stderr, "You selected item %d \n", n);

#endif

  /* we want to clear any previous text, to reset the window to
     beginning of text */
  XmTextSetString(lucytext, ""); /* clear the previous text */
  XmTextSetString(lucytext, buffer);  /* display text in window */

}



