/**********************************************************************
 * Provider Menu module for xtechinfo
 *
 * $Author: brlewis $
 * $Source: /mit/techinfodev/src/xtechinfo/RCS/xtiprov.c,v $
 * $Header: /mit/techinfodev/src/xtechinfo/RCS/xtiprov.c,v 4.3 1995/03/28 19:15:55 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_provider_c[] = "$Header: /mit/techinfodev/src/xtechinfo/RCS/xtiprov.c,v 4.3 1995/03/28 19:15:55 brlewis Exp $";

#include <Xm/Xm.h>
#include <Xm/MessageB.h>
#include <Xm/Text.h>
#include <Xm/ToggleBG.h>
#include <X11/Wc/WcCreate.h>
#include <ti/ti.h>
#include <ti/node.h>
#include <string.h>
#include <errno.h>
#include <com_err.h>
#include "xtechinfo.h"
#include "xti.h"

#define ABORT { com_err("xtechinfo", code, "\n%s", ti_context); return; }
#define TString(s,t) XmStringGetLtoR((s),XmSTRING_DEFAULT_CHARSET,(t))
static Widget defTitle, defKeywords, defSource, defFolder;
static Widget Title, Keywords, Source; 


/*ARGSUSED*/
void DefinePrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  char *string;
  char label[512];

  /* initialize global widget variables */
  if (!glow.defTitle)
    {
      glow.defTitle = WcFullNameToWidget(w, "*defineDialog*titleText");
      glow.defKeywords = WcFullNameToWidget(w, "*defineDialog*keywordsText");
      glow.defSource = WcFullNameToWidget(w, "*defineDialog*sourceText");
      glow.defLocker = WcFullNameToWidget(w, "*defineDialog*lockerText");
      glow.defFile = WcFullNameToWidget(w, "*defineDialog*fileText");
      glow.defFolder = WcFullNameToWidget(w, "*defineDialog*Folder");
      glow.defLabel = WcFullNameToWidget(w, "*defineDialog*parentLabel");
    }

  /* initialize source */
  XtVaGetValues(glow.defSource,
		XmNvalue, &string,
		NULL);
  if (!string || !(*string))
    XtVaSetValues(glow.defSource,
		  XmNvalue, ti_source1(global.menus[global.current]->tp),
		  NULL);

  /* New item will be added to ... "folder name" */
  sprintf(label, "%s %s", GlobalResources.str21,
	  ti_title(global.nodes[0]));
  XtVaSetValues(glow.defLabel,
		XmNlabelString, XmStringCreateSimple(label),
		NULL);
  global.parent = ti_id(global.nodes[0]);

  /* set keyboard input on title widget */
  XmProcessTraversal(glow.defTitle, XmTRAVERSE_CURRENT);

  return;
}

/**********************************************************************
 * DefineItem module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void DefineItem(button_w, client_data, cbs)
     Widget button_w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  char *title, *keywords, *source, *locker, *file;
  ti_node *nd;

  if (code=ti_newnode(&nd)) ABORT;

  /* set string values */
  XtVaGetValues(glow.defTitle, XmNvalue, &title, NULL);
  ti_settitle(nd, title);
  XtVaGetValues(glow.defKeywords, XmNvalue, &keywords, NULL);
  ti_settopic(nd, keywords);
  XtVaGetValues(glow.defSource, XmNvalue, &source, NULL);
  ti_setsource(nd, source);

  if (XmToggleButtonGadgetGetState(glow.defFolder))
    {
      ti_settype(nd, TI_NMENU);
    }
  else
    {
      XtVaGetValues(glow.defLocker, XmNvalue, &locker, NULL);
      ti_setlocker(nd, locker);
      XtVaGetValues(glow.defFile, XmNvalue, &file, NULL);
      ti_setfile(nd, file);

      /* set type according to filename extension */
      ti_fixtype(nd, NT_ASCII);
    }

  /* check validity of node */
  if (code=ti_nodechk(nd))
    {
      ti_freenode(nd);
      ABORT;
    }

  /* create node */
  if (code=ti_add(global.tp, nd))
    {
      ti_freenode(nd);
      ABORT;
    }

  /* link to parent menu */
  if (code=ti_link(global.tp, global.parent, ti_id(nd)))
    {
      ti_remove(global.tp, ti_id(nd));
      ti_freenode(nd);
      ABORT;
    }

  /* Providers shouldn't use the same keywords for many nodes
   * in a folder.  They should just set the keyword on the top level.
   * To encourage this, we clear the keyword field after successfully
   * creating a node.
   */
  XtVaSetValues(glow.defKeywords, XmNvalue, "", NULL);

  /* rebuild list widget */
  if (code=BuildListWidget(&global)) ABORT;

  return;
}

/**********************************************************************
 * ModifyPrep module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void ModifyPrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  ti_node *chosen;
  Widget correct_box = (Widget) 0;

  /* no item selected? ignore */
  if (!(chosen = SelectedNode())) return;

  /* initialize global widget variables */
  if (!glow.modFile)
    {
      glow.modFolder = WcFullNameToWidget(w, "*modifyDialog*Folder");
      glow.modDocument = WcFullNameToWidget(w, "*modifyDialog*Document");
      glow.modTitle = WcFullNameToWidget(w, "*modifyDialog*titleText");
      glow.modKeywords = WcFullNameToWidget(w, "*modifyDialog*keywordsText");
      glow.modSource = WcFullNameToWidget(w, "*modifyDialog*sourceText");
      glow.modLocker = WcFullNameToWidget(w, "*modifyDialog*lockerText");
      glow.modFile = WcFullNameToWidget(w, "*modifyDialog*fileText");
    }

  /* initialize strings */
  XtVaSetValues(glow.modTitle,
		  XmNvalue, ti_title(chosen),
		  NULL);
  XtVaSetValues(glow.modKeywords,
		  XmNvalue, ti_topic(chosen),
		  NULL);
  XtVaSetValues(glow.modSource,
		  XmNvalue, ti_source(chosen),
		  NULL);
  XtVaSetValues(glow.modLocker,
		  XmNvalue, ti_locker(chosen),
		  NULL);
  XtVaSetValues(glow.modFile,
		  XmNvalue, ti_file(chosen),
		  NULL);

  /* initialize type */
  if (ti_ismenu(chosen)) correct_box = glow.modFolder;
  else correct_box = glow.modDocument;
  XmToggleButtonGadgetSetState(correct_box, True, True);
  XtCallCallbacks(correct_box, XmNarmCallback, "");
  ti_copynode(chosen, global.to_modify);

  /* set keyboard input on title widget */
  XmProcessTraversal(glow.modTitle, XmTRAVERSE_CURRENT);

  return;
}

/**********************************************************************
 * ModifyItem module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void ModifyItem(button_w, client_data, cbs)
     Widget button_w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  char *title, *keywords, *source, *locker, *file;
  int old_wasmenu;

  old_wasmenu=ti_ismenu(global.to_modify);

  /* get string values */
  XtVaGetValues(glow.modTitle, XmNvalue, &title, NULL);
  ti_settitle(global.to_modify, title);
  XtVaGetValues(glow.modKeywords, XmNvalue, &keywords, NULL);
  ti_settopic(global.to_modify, keywords);
  XtVaGetValues(glow.modSource, XmNvalue, &source, NULL);
  ti_setsource(global.to_modify, source);

  if (XmToggleButtonGadgetGetState(glow.modFolder))
    {
      ti_setlocker(global.to_modify, "");
      ti_setfile(global.to_modify, "");
      ti_settype(global.to_modify, TI_NMENU);
    }
  else
    {
      XtVaGetValues(glow.modLocker, XmNvalue, &locker, NULL);
      ti_setlocker(global.to_modify, locker);
      XtVaGetValues(glow.modFile, XmNvalue, &file, NULL);
      ti_setfile(global.to_modify, file);

      /* set type according to filename extension */
      if (old_wasmenu) ti_fixtype(global.to_modify, NT_ASCII);
    }

  /* check validity of node */
  if (code=ti_nodechk(global.to_modify)) ABORT;

  /* modify node */
  if (code=ti_replace(global.tp, global.to_modify)) ABORT;

  /* rebuild list widget */
  if (code=BuildListWidget(&global)) ABORT;

  return;
}

/**********************************************************************
 * RemovePrep module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void RemovePrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  ti_node *chosen;
  char message[512];
  Widget cancel_buttonG;

  /* no item selected? ignore */
  if (!(chosen = SelectedNode())) return;

  /* initialize global widget variables */
  if (!glow.removeBox)
    {
      glow.removeBox = WcFullNameToWidget(w, "*removeDialog");
    }

  /* fill in label */
  sprintf(message, "%s\n", GlobalResources.str22);
  strcat(strcat(message, ti_title(chosen)), 
	 GlobalResources.str23);
  XtVaSetValues(glow.removeBox,
		XmNmessageString, 
		XmStringCreateLtoR(message, GlobalResources.str24),
		NULL);

  /* remember what we're removing */
  global.to_remove = ti_id(chosen);

  /* set keyboard input on Cancel button */
  if (cancel_buttonG =
      XmMessageBoxGetChild(glow.removeBox, XmDIALOG_CANCEL_BUTTON))
    XmProcessTraversal(cancel_buttonG, XmTRAVERSE_CURRENT);

  return;
}

/**********************************************************************
 * RemoveItem module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void RemoveItem(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;

  /* remove node */
  if (code=ti_remove(global.tp, global.to_remove)) ABORT;

  /* rebuild list widget */
  if (code=BuildListWidget(&global)) ABORT;

  return;
}

/**********************************************************************
 * SourcePrep module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void SourcePrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  ti_sourceinfo sourceinfo;

  /* initialize global widget variables */
  if (!glow.sourceEmail)
    {
      glow.sourceShort = WcFullNameToWidget(w, "*sourceDialog*sourceText");
      glow.sourceLong = WcFullNameToWidget(w, "*sourceDialog*lsourceText");
      glow.sourceContact = WcFullNameToWidget(w, "*sourceDialog*contactText");
      glow.sourcePhone = WcFullNameToWidget(w, "*sourceDialog*phoneText");
      glow.sourceEmail = WcFullNameToWidget(w, "*sourceDialog*emailText");
    }

  /* get source info */
  code = ti_getsrcbyname(CurrentTI, ti_source1(CurrentTI), &sourceinfo);
  if (code != 0L)
    {
      if (code != TI_ERR_NOSOURCE) ABORT;

      /* only fill in what we know; leave most fields blank */
      sourceinfo.ssource = ti_source1(CurrentTI);
      sourceinfo.lsource = sourceinfo.name = sourceinfo.phone
	= sourceinfo.email = "";
    }

  /* initialize strings */
  XtVaSetValues(glow.sourceShort,
		  XmNvalue, sourceinfo.ssource,
		  NULL);
  XtVaSetValues(glow.sourceLong,
		  XmNvalue, sourceinfo.lsource,
		  NULL);
  XtVaSetValues(glow.sourceContact,
		  XmNvalue, sourceinfo.name,
		  NULL);
  XtVaSetValues(glow.sourcePhone,
		  XmNvalue, sourceinfo.phone,
		  NULL);
  XtVaSetValues(glow.sourceEmail,
		  XmNvalue, sourceinfo.email,
		  NULL);

  /* set keyboard input on correct widget */
  XmProcessTraversal(glow.sourceLong, XmTRAVERSE_CURRENT);

  return;
}
/**********************************************************************
 * ChangeSource module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void ChangeSource(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  ti_sourceinfo sourceinfo;
  char *string;

  /* set string values */
  sourceinfo.ssource = sourceinfo.buf;
  XtVaGetValues(glow.sourceShort, XmNvalue, &string, NULL);
  strcpy(sourceinfo.ssource, string);

  sourceinfo.lsource = sourceinfo.ssource+strlen(sourceinfo.ssource)+1;
  XtVaGetValues(glow.sourceLong, XmNvalue, &string, NULL);
  strcpy(sourceinfo.lsource, string);

  sourceinfo.name = sourceinfo.lsource+strlen(sourceinfo.lsource)+1;
  XtVaGetValues(glow.sourceContact, XmNvalue, &string, NULL);
  strcpy(sourceinfo.name, string);

  sourceinfo.phone = sourceinfo.name+strlen(sourceinfo.name)+1;
  XtVaGetValues(glow.sourcePhone, XmNvalue, &string, NULL);
  strcpy(sourceinfo.phone, string);

  sourceinfo.email = sourceinfo.phone+strlen(sourceinfo.phone)+1;
  XtVaGetValues(glow.sourceEmail, XmNvalue, &string, NULL);
  strcpy(sourceinfo.email, string);

  /* set source info */
  if (code = ti_setsrc(global.menus[global.current]->tp,
		       &sourceinfo)) ABORT;

  return;
}

/**********************************************************************
 * New Provider module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void NewprovPrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;

  /* initialize global widget variables */
  if (!glow.provPasswd)
    {
      glow.provSource = WcFullNameToWidget(w, "*newprovDialog*sourceText");
      glow.provUser = WcFullNameToWidget(w, "*newprovDialog*userText");
      glow.provPasswd = WcFullNameToWidget(w, "*newprovDialog*passwdText");
    }

  /* set initial text */
  XmTextSetString(glow.provSource, ti_source1(CurrentTI));
  XmTextSetString(glow.provUser, "");
  XmTextSetString(glow.provPasswd, "");

  return;
}

/*ARGSUSED*/
void NewProvider(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  char *source, *uname, *password;

  source = XmTextGetString(glow.provSource);
  uname = XmTextGetString(glow.provUser);
  password = XmTextGetString(glow.provPasswd);

  if (!*password)
    {
#ifdef USE_KERBEROS
      code = ti_newprov(CurrentTI, source, uname, TI_KERBEROS);
#else
      *ti_context = '\0';
      code = XTI_ERR_NEEDPASS;
#endif /* USE_KERBEROS */
    }
  else code = ti_newprov(CurrentTI, source, uname, password);
  
  XtFree(source);
  XtFree(uname);
  XtFree(password);

  if (code) ABORT;
  return;
}

/**********************************************************************
 * Cut module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void
Cut(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  ti_node *parent, *child;

  /* nothing to cut?  ignore. */
  if (!(child = SelectedNode())) return;

  /* no parent to cut from?  ignore. */
  if (!(parent = SelectedParent())) return;

  /* unlink item from folder */
  if (code = ti_unlink(global.tp, ti_id(parent), ti_id(child))) ABORT;

  /* remember what to paste */
  global.to_paste = ti_id(child);

  /* set sensitivity on paste button */
  XtSetSensitive(glow.Paste, True);

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

  return;
}

/**********************************************************************
 * Copy module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void Copy(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  ti_node *chosen;

  /* no item selected? ignore */
  if (!(chosen = SelectedNode())) return;

  /* remember what we're copying */
  global.to_paste = ti_id(chosen);

  /* set sensitivity on paste button */
  XtSetSensitive(glow.Paste, True);

  return;
}

/**********************************************************************
 * Paste module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void
Paste(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;
  ti_node *parent, *child;

  /* no parent to paste into?  ignore. */
  if (!(parent = SelectedParent())) return;

  /* add item to folder */
  if (code = ti_link(global.tp, ti_id(parent), global.to_paste)) ABORT;

  /* Reorder if necessary */
  if (child = SelectedNode())
    {
      if (code = ti_reorder(global.tp, ti_id(parent),
			    ti_id(child), global.to_paste))
	com_err("xtechinfo", code, "\n%s", ti_context);
    }

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

  return;
}

/**********************************************************************
 * Provider Deauthentication module for xtechinfo
 **********************************************************************/

/*ARGSUSED*/
void Deauthenticate(button_w, client_data, cbs)
     Widget button_w;
     XtPointer client_data;
     XmAnyCallbackStruct *cbs;
{
  long code;

  /* Try to deauthenticate */
  if (code = ti_deauth(global.tp)) ABORT;

  /* free node to modify */
  ti_freenode(global.to_modify);

  /* Unmap provider menu */
  XtUnmanageChild(WcFullNameToWidget(button_w, "*provider"));
  global.am_provider = False;

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

  return;
}


/*****************************************************************************
 * Provider Send File Module
 *****************************************************************************/

void SendFilePrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmFileSelectionBoxCallbackStruct  *cbs;
{
  char *string;
  char label[512];

  if (!defTitle)
    {
      defTitle = WcFullNameToWidget(w, "*sendFileDialog*titleText");
      defKeywords = WcFullNameToWidget(w, "*sendFileDialog*keywordsText");
      defSource = WcFullNameToWidget(w, "*sendFileDialog*sourceText");
      defFolder = WcFullNameToWidget(w, "*sendFileDialog*Folder");
    }

  /* initialize source */
  XtVaSetValues(defSource,
		XmNvalue, ti_source(global.nodes[0]),
		NULL);
  
  /* New item will be added to ... "folder name" */
  sprintf(label, "%s %s", GlobalResources.str21,
          ti_title(global.nodes[0]));
  global.parent = ti_id(global.nodes[0]);

  /* set keyboard input on title widget */
  XmProcessTraversal(defTitle, XmTRAVERSE_CURRENT);
}


void SendFile(button_w, client_data, cbs)
     Widget button_w;
     XtPointer client_data;
     XmFileSelectionBoxCallbackStruct *cbs;
{
  long code;
  char *title, *keywords, *source, *filename;
  ti_node *nd;
  FILE *fp;

  if (code=ti_newnode(&nd)) ABORT;

  /* set string values */
  XtVaGetValues(defTitle, XmNvalue, &title, NULL);
  ti_settitle(nd, title);
  XtVaGetValues(defKeywords, XmNvalue, &keywords, NULL);
  ti_settopic(nd, keywords);
  XtVaGetValues(defSource, XmNvalue, &source, NULL);
  ti_setsource(nd, source);

  if(!TString(cbs->value, &filename)){
    return;
  }

  /* set file type according to filename extension */
  ti_clrflag(nd, TI_ALLTYPEBITS);
  ti_setflag(nd, ti_filenodetypeof(ti_filetypeof(filename, NT_ASCII)));

  printf("filename=%s\n", filename);

  if((fp = fopen(filename,"r")) == NULL)
    return;
  ti_setflag(nd, TI_NSYSGEN_FN);
  
  /* check validity of node */
  if (code=ti_nodechk(nd))
    {
      ti_freenode(nd);
      ABORT;
    }
  
  /* create node */
  if (code=ti_add(global.tp, nd))
    {
      ti_freenode(nd);
      ABORT;
    }
  
  /* link to parent menu */
  if (code=ti_link(global.tp, global.parent, ti_id(nd)))
    {
      ti_remove(global.tp, ti_id(nd));
      ti_freenode(nd);
      ABORT;
    }
  
  /* Providers shouldn't use the same keywords for many nodes
   * in a folder.  They should just set the keyword on the top level.
   * To encourage this, we clear the keyword field after successfully
   * creating a node.
   */
  XtVaSetValues(defKeywords, XmNvalue, "", NULL);
  XtVaSetValues(defTitle, XmNvalue, "", NULL);
  
  /* rebuild list widget */
  if (code=BuildListWidget(&global)) ABORT;

  ti_sendfile(CurrentTI, nd, fp);
}

/*****************************************************************************
* Provider Replace Item with File
*************************************************************************** */
void ReplaceFilePrep(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmFileSelectionBoxCallbackStruct  *cbs;
{
  ti_node *chosen;
  Widget correct_box = (Widget) 0;

  /* no item selected? ignore */
  if (!(chosen = SelectedNode())) return;
  
  /* initialize global widget variables */
  if (!Title)
    {
      Title = WcFullNameToWidget(w, "*replFileDialog*titleText");
      Keywords = WcFullNameToWidget(w, "*replFileDialog*keywordsText");
      Source = WcFullNameToWidget(w, "*replFileDialog*sourceText");
    }

  /* initialize strings */
  XtVaSetValues(Title,
		XmNvalue, ti_title(chosen),
		NULL);
  XtVaSetValues(Keywords,
		XmNvalue, ti_topic(chosen),
		NULL);
  XtVaSetValues(Source,
		XmNvalue, ti_source(chosen),
		NULL);

  ti_copynode(chosen, global.to_modify);

  XmProcessTraversal(glow.modTitle, XmTRAVERSE_CURRENT);
}

void ReplaceFile(w, client_data, cbs)
     Widget w;
     XtPointer client_data;
     XmFileSelectionBoxCallbackStruct  *cbs;
{
  long code;
  char *title, *keywords, *source, *filename;
  FILE *fp;

  if(!TString(cbs->value, &filename)){
    return;
  }

  if((fp = fopen(filename,"r")) == NULL)
    return;

  /* get string values */
  XtVaGetValues(Title, XmNvalue, &title, NULL);
  ti_settitle(global.to_modify, title);
  XtVaGetValues(Keywords, XmNvalue, &keywords, NULL);
  ti_settopic(global.to_modify, keywords);
  XtVaGetValues(Source, XmNvalue, &source, NULL);
  ti_setsource(global.to_modify, source);

  ti_setflag(global.to_modify, TI_NSYSGEN_FN);

  /* set file type according to filename extension */
  ti_clrflag(global.to_modify, TI_ALLTYPEBITS);
  ti_setflag(global.to_modify,
	     ti_filenodetypeof(ti_filetypeof(filename, NT_ASCII)));

  /* check validity of node */
  if (code=ti_nodechk(global.to_modify)) ABORT;

  /* modify node */
  if (code=ti_replace(global.tp, global.to_modify)) ABORT;
 
  /* rebuild list widget */
  if (code=BuildListWidget(&global)) ABORT;

  ti_sendfile(CurrentTI, global.to_modify, fp);
}

