/**********************************************************************
 * main C module for xtechinfo
 *
 * $Author: brlewis $
 * $Source: /mit/techinfodev/src/xtechinfo/RCS/xtimain.c,v $
 * $Header: /mit/techinfodev/src/xtechinfo/RCS/xtimain.c,v 4.2 1995/01/11 16:29:52 brlewis Exp $
 *
 * Copyright 1993 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/
#include <mit-copyright.h>

static char rcsid_main_c[] = "$Header: /mit/techinfodev/src/xtechinfo/RCS/xtimain.c,v 4.2 1995/01/11 16:29:52 brlewis Exp $";

#include <stdio.h>
#include <stdarg.h>
#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include <X11/Wc/WcCreate.h>
#include <X11/Xmp/Xmp.h>
#include <X11/StringDefs.h>
#include "xtechinfo.h"
#include "xti.h"
#include <ti/ti.h>
#include <ti/memory.h>
#include <com_err.h>
#include "bitmaps/logo.xbm"

extern void ResponseCB();
extern void FileSaveCB();
extern void SendFile();
extern void SendFilePrep();
extern void ReplaceFile();
extern void ReplaceFilePrep();


#define ABORT { com_err("xtechinfo", code, "(%s)", ti_context); exit(1); }

static XrmOptionDescRec options[] = {
  WCL_XRM_OPTIONS,
  /* cmd-line opt, X resource,  arg?			set to */
  { "-server",	"*server",	XrmoptionSepArg,	NULL},
  { "-port",	"*port",	XrmoptionSepArg,	NULL},
  { "-helpdir",	"*helpdir",	XrmoptionSepArg,	NULL},
  { "-krb",	"*useKerberos",	XrmoptionNoArg,		"False"},
  { "-frommain", "*searchFromMain", XrmoptionNoArg,	"False"},
  { "-showdate", "*showDate",	XrmoptionNoArg,		"True"},
  { "-showsource", "*showSource", XrmoptionNoArg,	"True"},
  { "-ndepth",	"*normalDepth", XrmoptionSepArg,	NULL},
  { "-odepth",	"*outlineDepth", XrmoptionSepArg,	NULL},
};

#define Offset(field) (XtOffset(XTechInfoResources *, field))
static XtResource xtechinfo_resources[] =
{
  {"server", "Server", XtRString, sizeof(char *),
     Offset(server), XtRString, NULL},
  {"port", "Port", XtRString, sizeof(char *),
     Offset(port), XtRString, NULL},
  {"helpdir", "Helpdir", XtRString, sizeof(char *),
     Offset(helpdir), XtRString, NULL},
  {"useKerberos", "UseKerberos", XtRBoolean, sizeof(Boolean),
     Offset(kerberos), XtRImmediate, (caddr_t) TRUE},
  {"searchFromMain", "SearchFromMain", XtRBoolean, sizeof(Boolean),
     Offset(frommain), XtRImmediate, (caddr_t) TRUE},
  {"showDate", "ShowDate", XtRBoolean, sizeof(Boolean),
     Offset(showdate), XtRImmediate, (caddr_t) FALSE},
  {"showSource", "ShowSource", XtRBoolean, sizeof(Boolean),
     Offset(showsource), XtRImmediate, (caddr_t) FALSE},
  {"normalDepth", "NormalDepth", XtRInt, sizeof(int),
     Offset(ndepth), XtRImmediate, (caddr_t) 1 },
  {"outlineDepth", "OutlineDepth", XtRInt, sizeof(int),
     Offset(odepth), XtRImmediate, (caddr_t) 3 }, 

  /* xtiview.c */
#define OffsetStr(field) (XtOffset(XTechInfoResources *, field))

  {"str01", "Str01", XtRString, sizeof(char *), OffsetStr(str01),
     XtRString, "Path(s) to " },
  {"str02", "Str02", XtRString, sizeof(char *), OffsetStr(str02),
     XtRString, "Warning: SetSearch: unknown search type "},
  {"str03", "Str03", XtRString, sizeof(char *), OffsetStr(str03),
     XtRString, "Matches for keyword "},
  {"str04", "Str04", XtRString, sizeof(char *), OffsetStr(str04),
   XtRString, "Documents containing"},
  {"str05", "Str05", XtRString, sizeof(char *), OffsetStr(str05),
     XtRString, "Nodes provided by"},
  {"str06", "Str06", XtRString, sizeof(char *), OffsetStr(str06),
     XtRString, "Nodes changed since"},
  {"str07", "Str07", XtRString, sizeof(char *), OffsetStr(str07),
     XtRString, "item"},
  {"str08", "Str08", XtRString, sizeof(char *), OffsetStr(str08),
     XtRString, "reason"},
  {"str09", "Str09", XtRString, sizeof(char *), OffsetStr(str09),
     XtRString, "type"},
  {"str10", "Str10", XtRString, sizeof(char *), OffsetStr(str10),
     XtRString, "event type"},
  {"str11", "Str11", XtRString, sizeof(char *), OffsetStr(str11),
     XtRString, "Latest change: "},
  {"str12", "Str12", XtRString, sizeof(char *), OffsetStr(str12),
     XtRString, "bold"},
  {"str13", "Str13", XtRString, sizeof(char *), OffsetStr(str13),
     XtRString, "charset"},
  {"str14", "Str14", XtRString, sizeof(char *), OffsetStr(str14),
     XtRString, "button"},
  {"str15", "Str15", XtRString, sizeof(char *), OffsetStr(str15),
     XtRString, "empty"},
  {"str16", "Str16", XtRString, sizeof(char *), OffsetStr(str16),
     XtRString, "one item"},
  {"str17", "Str17", XtRString, sizeof(char *), OffsetStr(str17),
     XtRString, "items"},

  /* xtitext.c */
  {"str18", "Str18", XtRString, sizeof(char *), OffsetStr(str18),
     XtRString, "Pages: "},
  {"str19", "Str19", XtRString, sizeof(char *), OffsetStr(str19),
     XtRString, "pages"},
  {"str20", "Str20", XtRString, sizeof(char *), OffsetStr(str20),
     XtRString, "Modified on "},

  /* xtiprov.c */
    {"str21", "Str21", XtRString, sizeof(char *), OffsetStr(str21),
     XtRString, "New item will be added to "},
  {"str22", "Str22", XtRString, sizeof(char *), OffsetStr(str22),
     XtRString, "Really remove"},
  {"str23", "Str23", XtRString, sizeof(char *), OffsetStr(str23),
     XtRString, "?"},
  {"str24", "Str24", XtRString, sizeof(char *), OffsetStr(str24),
     XtRString, "charset"},

  /* xtifile.c */
 {"str25", "Str25", XtRString, sizeof(char *), OffsetStr(str25),
     XtRString, "Host"},
  {"str26", "Str26", XtRString, sizeof(char *), OffsetStr(str26),
     XtRString, "Port"},
  {"str27", "Str27", XtRString, sizeof(char *), OffsetStr(str27),
     XtRString, "Long source"},
  {"str28", "Str28", XtRString, sizeof(char *), OffsetStr(str28),
     XtRString, "Contact"},
  {"str29", "Str29", XtRString, sizeof(char *), OffsetStr(str29),
     XtRString, "E-mail"},
  {"str30", "Str30", XtRString, sizeof(char *), OffsetStr(str30),
     XtRString, "Phone"},
  {"str31", "Str31", XtRString, sizeof(char *), OffsetStr(str31),
     XtRString, "Source"},
  {"str32", "Str32", XtRString, sizeof(char *), OffsetStr(str32),
     XtRString, "Keywords"},
  {"str33", "Str33", XtRString, sizeof(char *), OffsetStr(str33),
     XtRString, "Node modified"},
  {"str34", "Str34", XtRString, sizeof(char *), OffsetStr(str34),
     XtRString, "Id"},
  {"str35", "Str35", XtRString, sizeof(char *), OffsetStr(str35),
     XtRString, "Locker"},
  {"str36", "Str36", XtRString, sizeof(char *), OffsetStr(str36),
     XtRString, "File"},
  {"str37", "Str37", XtRString, sizeof(char *), OffsetStr(str37),
     XtRString, "Size"},
  {"str38", "Str38", XtRString, sizeof(char *), OffsetStr(str38),
     XtRString, "Connected to "},
  {"str39", "Str39", XtRString, sizeof(char *), OffsetStr(str39),
     XtRString, "port"},
  {"str40", "Str40", XtRString, sizeof(char *), OffsetStr(str40),
     XtRString, "View: "},
  {"str41", "Str41", XtRString, sizeof(char *), OffsetStr(str41),
     XtRString, "Selected: "},
};
#undef Offset
#undef OffsetStr

main(argc, argv)
     int argc;
     char *argv[];
{
  Widget appShell;
  XtAppContext app;
  char title[64];
  Pixmap icon;
  Pixel fg, bg;
  unsigned int depth;

  /* seed random number generator for mutual Kerberos authentication. */
  /* Fake server might guess process start time from connection time, */
  /* but hopefully it won't know our pid. */
  srand((unsigned) time(0) + (unsigned) getpid());

  bzero(&global, sizeof(global));
  bzero(&glow, sizeof(glow));
  initialize_xti_error_table();

  /* Intialize Toolkit creating the application shell */
  appShell = XtInitialize(argv[0], XTECHINFO_CLASS,
			  options, XtNumber(options), &argc, argv);
  glow.appshell = appShell;
  app = XtWidgetToApplicationContext(appShell);

  /* get application resources */
  XtGetApplicationResources(appShell, (caddr_t) &GlobalResources,
			    xtechinfo_resources,
			    XtNumber(xtechinfo_resources), NULL, 0);

  /* save for later */
  if (GlobalResources.server && *(GlobalResources.server))
    {
      strcpy(global.server=newstring(GlobalResources.server),
	      GlobalResources.server);
    }
  else
    {
      global.server = NULL;
    }

  if (GlobalResources.port && *(GlobalResources.port))
    {
      strcpy(global.port=newstring(GlobalResources.port),
	      GlobalResources.port);
    }
  else
    {
      global.port = NULL;
    }

  /* set title */
  sprintf(title, "%s %s", XTECHINFO_TITLE, XTECHINFO_VERSION);
  XtVaSetValues(appShell, XmNtitle, title, NULL);

  /* Register all callbacks and widget classes */
  RegisterApplication ( app );

  /* Create widget tree below toplevel shell using Xrm database */
  if ( WcWidgetCreation ( appShell ) )
    exit(1);

  /* Realize the widget tree */
  XtRealizeWidget ( appShell );

  /* prepare icon pixmap */
  XtVaGetValues(appShell,
		XmNforeground, &fg,
		XmNbackground, &bg,
		NULL);
  fg = BlackPixelOfScreen(XtScreen(appShell));
  bg = WhitePixelOfScreen(XtScreen(appShell));
  depth = DefaultDepth(XtDisplay(appShell),
		       XScreenNumberOfScreen(XtScreen(appShell)));
  icon = XCreatePixmapFromBitmapData(XtDisplay(appShell),
				     XtWindow(appShell),
				     logo_bits,
				     logo_width, logo_height,
				     fg, bg, depth);

  XtVaSetValues(appShell, XmNiconPixmap, icon, NULL);

  /* warp to list widget so arrow keys work from start */
  XmProcessTraversal(glow.mainlist, XmTRAVERSE_CURRENT);

  /* and finally, enter the main application loop */
  XtMainLoop ( );
}

/**********************************************************************
 * RegisterApplication module for xtechinfo
 **********************************************************************/

void RegisterApplication ( app )
     XtAppContext app;
{
  extern Widget XmCreateFormDialog(), XmCreateMenuBar(),
    XmCreatePulldownMenu(), XmCreateRadioBox(), XmCreateScrolledList(),
    XmCreateScrolledText(), XmCreateMessageDialog(), XmCreateSimpleCheckBox(),
    XmCreateInformationDialog(), XmCreateQuestionDialog(), XmCreateFrame(),
    XmCreateOptionMenu(), XmCreateCascadeButton(), 
    XmCreateFileSelectionDialog(), XmCreateFileSelectionBox() ;
  extern WidgetClass xmCascadeButtonWidgetClass, xmFormWidgetClass,
    xmLabelWidgetClass, xmPushButtonWidgetClass, xmSeparatorWidgetClass,
    xmTextWidgetClass, xmTextFieldWidgetClass, xmToggleButtonGadgetClass,
    xmpTableWidgetClass, xmScaleWidgetClass, xmRowColumnWidgetClass;
  
    /* -- Useful shorthand for registering things with the Wcl library */
#define RCP( name, class  ) WcRegisterClassPtr   ( app, name, class );
#define RCO( name, constr ) WcRegisterConstructor( app, name, constr );
#define RAC( name, func   ) WcRegisterAction     ( app, name, func );
#define RCB( name, func   ) WcRegisterCallback   ( app, name, func, NULL );

/* -- Register Motif-specific converters */
  XmpAddConverters(app);

    /* -- register widget classes and constructors */
 RCO( "XmCreateFormDialog",		XmCreateFormDialog		);
 RCO( "XmCreateMenuBar",		XmCreateMenuBar			);
 RCO( "XmCreatePulldownMenu",		XmCreatePulldownMenu		);
 RCO( "XmCreateRadioBox",		XmCreateRadioBox		);
 RCO( "XmCreateScrolledList",		XmCreateScrolledList		);
 RCO( "XmCreateScrolledText",		XmCreateScrolledText		);
 RCO( "XmCreateMessageDialog",		XmCreateMessageDialog		);
 RCO( "XmCreateInformationDialog",	XmCreateInformationDialog	);
 RCO( "XmCreateQuestionDialog",		XmCreateQuestionDialog		);
 RCO( "XmCreateFrame",			XmCreateFrame			);
 RCO( "XmCreateSimpleCheckBox",		XmCreateSimpleCheckBox		);
 RCO( "XmCreateOptionMenu",		XmCreateOptionMenu		);
 RCO( "XmCreateCascadeButton",		XmCreateCascadeButton		);
 RCO( "XmCreateFileSelectionDialog",    XmCreateFileSelectionDialog     );
 RCO( "XmCreateFileSelectionBox",       XmCreateFileSelectionBox        );

 RCP("XmCascadeButton",			xmCascadeButtonWidgetClass	);
 RCP("XmForm",				xmFormWidgetClass		);
 RCP("XmLabel",				xmLabelWidgetClass		);
 RCP("XmPushButton",			xmPushButtonWidgetClass		);
 RCP("XmSeparator",			xmSeparatorWidgetClass		);
 RCP("XmText",				xmTextWidgetClass		);
 RCP("XmToggleButtonGadget",		xmToggleButtonGadgetClass	);
 RCP("XmpTable",			xmpTableWidgetClass		);
 RCP("XmScale",				xmScaleWidgetClass		);
 RCP("XmRowColumn",			xmRowColumnWidgetClass		);

    /* -- Register application specific callbacks */
 RCB("Emacs",				SetEmacs			);
 RCB("XTechInfoInit",			InitializeXtechinfoCB		);
 RCB("RemoveExtraMessageBoxButtons",	RemoveExtraMessageBoxButtons	);
 RCB("ViewItem",			ViewItem			);
 RCB("ViewSelected",			ViewSel				);
 RCB("PathSelected",			PathSel				);
 RCB("OutlineSelected",			OtlSel				);
 RCB("PrevMenu",			PrevMenu			);
 RCB("MainMenu",			MainMenu			);
/*
 RCB("KeywordPrep",			KeywordPrep			);
 RCB("KeywordSearch",			KeywordSearch			);
*/
 RCB("ShowInfo",			ShowInfoCB			);
 RCB("StandardCursor",			StandardCursor			);
 RCB("WaitCursor",			WaitCursor			);
 RCB("PrintPrep",			PrintPrep			);
 RCB("Print",				Print				);
 RCB("Find",				Find				);
 RCB("Authenticate",			Authenticate			);
 RCB("KrbAuthenticate",			KrbAuthenticate			);
 RCB("Deauthenticate",			Deauthenticate			);
 RCB("DefinePrep",			DefinePrep			);
 RCB("DefineItem",			DefineItem			);
 RCB("ModifyPrep",			ModifyPrep			);
 RCB("ModifyItem",			ModifyItem			);
 RCB("RemovePrep",			RemovePrep			);
 RCB("RemoveItem",			RemoveItem			);
 RCB("Cut",				Cut				);
 RCB("Copy",				Copy				);
 RCB("Paste",				Paste				);
 RCB("SourcePrep",			SourcePrep			);
 RCB("ChangeSource",			ChangeSource			);
 RCB("ItemSelected",			ItemSelected			);
 RCB("TraverseCurrent",			TraverseCurrent			);
 RCB("TraverseNext",			TraverseNext			);
 RCB("WorldWide",			WorldWide			);
 RCB("ViewHelp",			ViewHelp			);
 RCB("PrefPrep",			PrefPrep			);
 RCB("PrefApply",			PrefApply			);
 RCB("ChooseAuth",			ChooseAuth			);
 RCB("SetSearch",			SetSearch			);
 RCB("DoSearch",			DoSearch			);
 RCB("JumpMenu",			JumpMenu			);
 RCB("CommentPrep",			CommentPrep			);
 RCB("CommentSend",			CommentSend			);
 RCB("NewprovPrep",			NewprovPrep			);
 RCB("NewProvider",			NewProvider			);
 RCB("ResponseCB",                      ResponseCB                      );
 RCB("FileSaveCB",                      FileSaveCB                      );
 RCB("SendFile",                        SendFile                        );
 RCB("SendFilePrep",                    SendFilePrep                    );
 RCB("ReplaceFile",                     ReplaceFile                     );
 RCB("ReplaceFilePrep",                 ReplaceFilePrep                 );
}

/**********************************************************************
 * xtechinfo's global variables
 **********************************************************************/

GlobalMenus global;
GlobalWidgets glow;
XTechInfoResources GlobalResources;
char *textbuf = NULL;
int TextSearchPos;

/**********************************************************************
 * initialization module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void InitializeXtechinfoCB(w, unusedstring, unusedptr)
     Widget w;
     char *unusedstring;
     XtPointer unusedptr;
{
  long code;

  /* connect to the techinfo server */
  if (code=ti_open(global.server, global.port,
		   &(global.tp))) ABORT;

  ti_version(global.tp, "XWIN", XTECHINFO_VERSION);

  /* get main menu */
  if (code = ti_main(global.tp, &(global.menus[0]))) ABORT;

  /* current menu is 0; menu count is 1 */
  global.current = 0;
  global.count = 1;

  /* intialize global widget variables */
  glow.mainlist = WcFullNameToWidget(w, "*mainList");
  glow.mainlabel = WcFullNameToWidget(w, "*mainLabel");
  glow.mainform = WcFullNameToWidget(w, "*mainForm");
  glow.buttonPrev = WcFullNameToWidget(w, "*PrevMenu");
  glow.itemPrev = WcFullNameToWidget(w, "*lookMenu.prev");
  glow.itemDefine = WcFullNameToWidget(w, "*providerMenu.def");
  glow.Cut = WcFullNameToWidget(w, "*providerMenu.cut");
  glow.Paste = WcFullNameToWidget(w, "*providerMenu.paste");
  glow.mainDate = WcFullNameToWidget(w, "*mainDate");
  glow.mainCount = WcFullNameToWidget(w, "*mainCount");
  glow.itemOutl = WcFullNameToWidget(w, "*lookMenu.outl");
  glow.itemPath = WcFullNameToWidget(w, "*lookMenu.path");
  glow.itemWwide = WcFullNameToWidget(w, "*lookMenu.wwide");
  glow.historyMenu = WcFullNameToWidget(w, "*historyMenu");
  glow.mainHistory = WcFullNameToWidget(w, "*mainHistory");

  XtVaSetValues(glow.mainHistory,
		XmNlabelString, XmStringCreateSimple(""),
		NULL);

  /* switch to windowed error reporting */
  set_com_err_hook(xti_com_err);

  if (code=BuildListWidget(&global)) ABORT;
  return;
}

/**********************************************************************
 * xti_com_err module for xtechinfo
 **********************************************************************/

/*VARARGS3*/
void xti_com_err(whoami, code, fmt, args)
     char *whoami;
     long code;
     char *fmt;
     va_list args;
{
  char message[512];
  Widget cancel_buttonG, help_buttonG;

  /* initialize widget */
  if (!glow.messageBox)
    {
      if (!(glow.messageBox =
	    WcFullNameToWidget(glow.appshell, "*messageBox")))
	goto ERR_ABORT;
    }

  /* prepare message */
  sprintf(message, "%s ", error_message(code));
  vsprintf(message+strlen(message), fmt, args);

  XtVaSetValues(glow.messageBox,
		XmNdialogType, XmDIALOG_ERROR,
		XmNmessageString, XmStringCreateLtoR(message, "charset"),
		NULL);

  /* unmap unused buttons */
  if (cancel_buttonG = XmMessageBoxGetChild(glow.messageBox,
					    XmDIALOG_CANCEL_BUTTON))
    XtUnmanageChild(cancel_buttonG);
  if (help_buttonG = XmMessageBoxGetChild(glow.messageBox,
					    XmDIALOG_HELP_BUTTON))
    XtUnmanageChild(help_buttonG);

  XtManageChild(glow.messageBox);
  return;

 ERR_ABORT:
  reset_com_err_hook();
  com_err(whoami, code, fmt, args);
  return;
}

/**********************************************************************
 * cursor module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void WaitCursor(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  if (glow.mainform) MuSetWaitCursor(glow.mainform);
  if (glow.textshell) MuSetWaitCursor(glow.textshell);
  return;
}

/*ARGSUSED*/
void StandardCursor(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  if (glow.mainform) MuSetStandardCursor(glow.mainform);
  if (glow.textshell) MuSetStandardCursor(glow.textshell);
  return;
}
