/****************************************************************************
 * NCSA Mosaic for the X Window System                                      *
 * Software Development Group                                               *
 * National Center for Supercomputing Applications                          *
 * University of Illinois at Urbana-Champaign                               *
 * 605 E. Springfield, Champaign IL 61820                                   *
 * mosaic@ncsa.uiuc.edu                                                     *
 *                                                                          *
 * Copyright (C) 1993, Board of Trustees of the University of Illinois      *
 *                                                                          *
 * NCSA Mosaic software, both binary and source (hereafter, Software) is    *
 * copyrighted by The Board of Trustees of the University of Illinois       *
 * (UI), and ownership remains with the UI.                                 *
 *                                                                          *
 * The UI grants you (hereafter, Licensee) a license to use the Software    *
 * for academic, research and internal business purposes only, without a    *
 * fee.  Licensee may distribute the binary and source code (if released)   *
 * to third parties provided that the copyright notice and this statement   *
 * appears on all copies and that no charge is associated with such         *
 * copies.                                                                  *
 *                                                                          *
 * Licensee may make derivative works.  However, if Licensee distributes    *
 * any derivative work based on or derived from the Software, then          *
 * Licensee will (1) notify NCSA regarding its distribution of the          *
 * derivative work, and (2) clearly notify users that such derivative       *
 * work is a modified version and not the original NCSA Mosaic              *
 * distributed by the UI.                                                   *
 *                                                                          *
 * Any Licensee wishing to make commercial use of the Software should       *
 * contact the UI, c/o NCSA, to negotiate an appropriate license for such   *
 * commercial use.  Commercial use includes (1) integration of all or       *
 * part of the source code into a product for sale or license by or on      *
 * behalf of Licensee to third parties, or (2) distribution of the binary   *
 * code or source code to third parties that need it to utilize a           *
 * commercial product sold or licensed by or on behalf of Licensee.         *
 *                                                                          *
 * UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR   *
 * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED          *
 * WARRANTY.  THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE    *
 * USERS OF THIS SOFTWARE.                                                  *
 *                                                                          *
 * By using or copying this Software, Licensee agrees to abide by the       *
 * copyright law and all other applicable laws of the U.S. including, but   *
 * not limited to, export control laws, and the terms of this license.      *
 * UI shall have the right to terminate this license immediately by         *
 * written notice upon Licensee's breach of, or non-compliance with, any    *
 * of its terms.  Licensee may be held legally responsible for any          *
 * copyright infringement that is caused or encouraged by Licensee's        *
 * failure to abide by the terms of this license.                           *
 *                                                                          *
 * Comments and questions are welcome and can be sent to                    *
 * mosaic-x@ncsa.uiuc.edu.                                                  *
 ****************************************************************************/

/* Interface for mailto: URLs, stolen from whine.c */

#include "mosaic.h"
#include "libhtmlw/HTML.h"
#include <pwd.h>

#define TEXT_PLAIN	"text/plain"
#ifdef L10N
#define CHARSET		"ISO-2022-JP"
#endif /* L10N */

extern mo_window *current_win;
mo_status mo_send_mailto_message (char *text, char *to, char *subj, 
				  char *content_type, char *url);

/* ----------------------- mo_post_mailto_window ------------------------ */

static XmxCallback (include_mailto_fsb_cb)
{
  char *fname;
  FILE *fp;
  char line[MO_LINE_LENGTH], *status;

  mo_window *win = mo_fetch_window_by_id (XmxExtractUniqid ((int)client_data));

  if (!win)
    return;

  XtUnmanageChild (win->mailto_fsb_win);
  fname = (char *)malloc (128 * sizeof (char));
  
  XmStringGetLtoR (((XmFileSelectionBoxCallbackStruct *)call_data)->value,
                   XmSTRING_DEFAULT_CHARSET,
                   &fname);

  fp = fopen (fname, "r");
  if (!fp)
    {
        char *buf, *final, tmpbuf[80];
	int final_len;

        buf=my_strerror(errno);
        if (!buf || !*buf || !strcmp(buf,"Error 0")) {
                sprintf(tmpbuf,"Unknown Error");
                buf=tmpbuf;
	}

        final_len=30+((!fname || !*fname?3:strlen(fname))+13)+15+(strlen(buf)+13);
        final=(char *)calloc(final_len,sizeof(char));

        strcpy(final,"\nUnable to Open File:\n");
        sprintf(final+strlen(final),"   %s\n",(!fname || !*fname?" ":fname));
        sprintf(final+strlen(final),"\nOpen Error:\n");
        sprintf(final+strlen(final),"   %s\n",buf);

	XmxMakeErrorDialog (win->mailto_win, 
                          final, 
                          "Open Error");
	XtManageChild (Xmx_w);

	if (final) {
		free(final);
		final=NULL;
	}
      return;
    }
  
  while (1)
    {
      long pos;
      status = fgets (line, MO_LINE_LENGTH, fp);
      if (!status || !(*line))
        goto done;
#ifdef L10N
      {
        char *p;
	for (p=line;*p;p++) {
	  if (*p & 0x80) {
	    if (!(*(++p) & 0x80)) {
	      p[-1] = '?';
	    }
	  }
        }
      }
#endif /* L10N */
      
      XmTextInsert (win->mailto_text,
                    pos = XmTextGetInsertionPosition (win->mailto_text),
                    line);
      /* move insertion position to past this line to avoid inserting the
         lines in reverse order */
      XmTextSetInsertionPosition (win->mailto_text, pos + strlen(line));
    }

 done:
  return;
}

static XmxCallback (mailto_win_cb)
{
  mo_window *win = mo_fetch_window_by_id (XmxExtractUniqid ((int)client_data));
  char *msg, *subj, *to;
  
  switch (XmxExtractToken ((int)client_data))
    {
    case 0:  /* send */
      XtUnmanageChild (win->mailto_win);
      
      msg = XmxTextGetString (win->mailto_text);
      if (!msg)
        return;
      if (msg[0] == '\0')
        return;

      to = XmxTextGetString (win->mailto_tofield);
      subj = XmxTextGetString (win->mailto_subfield);

      mo_send_mailto_message (msg, to, subj, TEXT_PLAIN,
			      win->current_node->url);
      free (msg);
      free (to);
      free (subj);

      break;
    case 1:   /* dismiss */
      XtUnmanageChild (win->mailto_win); 
      XtDestroyWidget (win->mailto_win);
      win->mailto_win = NULL;
      win->mailto_fsb_win = NULL;
      /* Do nothing. */
      break;
    case 2:   /* help */
      mo_open_another_window
        (win, 
         mo_assemble_help_url ("help-on-mailto.html"),
         NULL, NULL);
      break;
    case 3:   /* Insert File */
      if (!win->mailto_fsb_win)
	{
	  win->mailto_fsb_win =
	    XmxMakeFileSBDialog (win->mailto_win,
				 "NCSA Mosaic: Include File In Mail to",
				 "Name of file to include:",
				 include_mailto_fsb_cb, 0);
	}
      else
	{
	  XmFileSelectionDoSearch (win->mailto_fsb_win, NULL);
	}
      XmxManageRemanage (win->mailto_fsb_win);
      break;
    }

  return;
}

mo_status mo_post_mailto_win (char *to_address, char *subject)
{
  mo_window *win = current_win;
  struct passwd *pw = getpwuid (getuid ());
  char namestr[1000], *author;
  extern char *machine;
  FILE *fp;
  char tmp[1024];
  int pos;

  if (!win->mailto_win)
    {
      Widget dialog_frame;
      Widget dialog_sep, buttons_form;
      Widget mailto_form;
      Widget tolabel, sublabel, fromlabel;
      
      /* Create it for the first time. */
      XmxSetUniqid (win->id);
      win->mailto_win = XmxMakeFormDialog 
        (win->base, "NCSA Mosaic: Mail To Author");
      dialog_frame = XmxMakeFrame (win->mailto_win, XmxShadowOut);
      
      /* Constraints for base. */
      XmxSetConstraints 
        (dialog_frame, XmATTACH_FORM, XmATTACH_FORM, 
         XmATTACH_FORM, XmATTACH_FORM, NULL, NULL, NULL, NULL);
      
      /* Main form. */
      mailto_form = XmxMakeForm (dialog_frame);
      
      XmxSetArg (XmNscrolledWindowMarginWidth, 10);
      XmxSetArg (XmNscrolledWindowMarginHeight, 10);
      XmxSetArg (XmNcursorPositionVisible, True);
      XmxSetArg (XmNeditable, True);
      XmxSetArg (XmNeditMode, XmMULTI_LINE_EDIT);
      XmxSetArg (XmNrows, 15);
#ifdef L10N
#ifdef MOTIF_I18N
      if (Rdata.half_sized_textfield)
      XmxSetArg (XmNcolumns, 40);
      else
#endif /* MOTIF_I18N */
#endif /* L10N */
      XmxSetArg (XmNcolumns, 80);
      /* XmxSetArg (XmNwordWrap, True); */
      /* XmxSetArg (XmNscrollHorizontal, False); */
#ifdef L10N
#if defined(IXIMOTIF1_2) || !defined(MOTIF_I18N)
      XmxSetArg (XmNfontList, (XtArgVal)win->font_list);
#endif /* IXIMOTIF1_2 || !MOTIF_I18N */
#endif /* L10N */
      win->mailto_text = XmxMakeScrolledText (mailto_form);
      
      dialog_sep = XmxMakeHorizontalSeparator (mailto_form);

      /* create from, to, and subject widgets */
      fromlabel = XmxMakeLabel(mailto_form, "From:");
      XmxSetArg (XmNeditable, False); /* for now, at least */
      win->mailto_fromfield = XmxMakeTextField(mailto_form);

      tolabel = XmxMakeLabel(mailto_form, "To:");
      win->mailto_tofield = XmxMakeTextField(mailto_form);

      sublabel = XmxMakeLabel(mailto_form, "Subject:");
      win->mailto_subfield = XmxMakeTextField(mailto_form);

      /* constraints for FROM */
      XmxSetOffsets(fromlabel, 14, 10, 10, 10);
      XmxSetConstraints
	(fromlabel, XmATTACH_FORM, XmATTACH_NONE, XmATTACH_FORM, 
	 XmATTACH_NONE, NULL, NULL, NULL, NULL);
      XmxSetOffsets(win->mailto_fromfield, 10, 10, 10, 10);
      XmxSetConstraints
	(win->mailto_fromfield, XmATTACH_FORM, XmATTACH_NONE, XmATTACH_WIDGET,
	 XmATTACH_FORM, NULL, NULL, fromlabel, NULL);

      /* constraints for TO */
      XmxSetOffsets(tolabel, 14, 10, 10, 10);
      XmxSetConstraints
	(tolabel, XmATTACH_WIDGET, XmATTACH_NONE, XmATTACH_FORM, XmATTACH_NONE,
	 win->mailto_fromfield, NULL, NULL, NULL);
      XmxSetOffsets(win->mailto_tofield, 10, 10, 10, 10);
      XmxSetConstraints
	(win->mailto_tofield, XmATTACH_WIDGET, XmATTACH_NONE, XmATTACH_WIDGET, 
	 XmATTACH_FORM, win->mailto_fromfield, NULL, tolabel, NULL);

      /* constraints for SUBJECT */
      XmxSetOffsets(sublabel, 14, 10, 10, 10);
      XmxSetConstraints
	(sublabel, XmATTACH_WIDGET, XmATTACH_NONE, XmATTACH_FORM, 
	 XmATTACH_NONE, win->mailto_tofield, NULL, NULL, NULL);
      XmxSetOffsets(win->mailto_subfield, 10, 10, 10, 10);
      XmxSetConstraints
	(win->mailto_subfield, XmATTACH_WIDGET, XmATTACH_NONE, 
	 XmATTACH_WIDGET, XmATTACH_FORM, win->mailto_tofield, NULL, 
	 sublabel, NULL);

      /* create buttons */
      buttons_form = XmxMakeFormAndFourButtons
        (mailto_form, mailto_win_cb, "Send", "Insert File", "Dismiss",
	 "Help...", 0, 3, 1, 2);

      XmxSetOffsets (XtParent (win->mailto_text), 3, 0, 3, 3);
      XmxSetConstraints
        (XtParent (win->mailto_text), XmATTACH_WIDGET, XmATTACH_WIDGET, 
         XmATTACH_FORM, XmATTACH_FORM,
         win->mailto_subfield, dialog_sep, NULL, NULL);

      XmxSetArg (XmNtopOffset, 10);
      XmxSetConstraints 
        (dialog_sep, XmATTACH_NONE, XmATTACH_WIDGET, XmATTACH_FORM, 
         XmATTACH_FORM,
         NULL, buttons_form, NULL, NULL);
      XmxSetConstraints 
        (buttons_form, XmATTACH_NONE, XmATTACH_FORM, XmATTACH_FORM, 
	 XmATTACH_FORM, NULL, NULL, NULL, NULL);
    }

  /* fill in text fields */
  if (Rdata.default_author_name)
    author = Rdata.default_author_name;
  else
    author = pw->pw_gecos;
  sprintf (namestr, "%s <%s@%s>", author, pw->pw_name, machine);
  XmxTextSetString (win->mailto_fromfield, namestr);
  XmxTextSetString (win->mailto_tofield, to_address);
  if (subject != NULL)
  	XmTextFieldSetString(win->mailto_subfield,subject);
  else
  	XmTextFieldSetString(win->mailto_subfield,"");
  /* XmxTextSetString (win->mailto_text, ""); */
  XmxTextSetString (win->mailto_text, "\n\n");
  /* tack signature on the end if it exists - code from Martin Hamilton */
  if (Rdata.signature)
      XmTextSetInsertionPosition (win->mailto_text, 2);
  if ((fp = fopen(Rdata.signature, "r")) != NULL) {
      while(fgets(tmp, sizeof(tmp) - 1, fp)) {
          XmTextInsert(win->mailto_text,
            pos = XmTextGetInsertionPosition (win->mailto_text), tmp);
          XmTextSetInsertionPosition (win->mailto_text, pos + strlen(tmp));
      }
      fclose(fp);
  }
/* taninaka (end of read signature) */

  XmTextSetInsertionPosition (win->mailto_text, 0);

  XmxManageRemanage (win->mailto_win);
  return mo_succeed;
}

/* ------------------------------------------------------------------------ */
/* these are not currently used.  We just use the functions in whine.c */
/* ------------------------------------------------------------------------ */

static FILE *_fp = NULL;

#ifdef L10N
FILE *mo_start_sending_mailto_message (char *to, char *subj, 
                                     char *content_type, char *charset, char *url)
#else /* L10N */
FILE *mo_start_sending_mailto_message (char *to, char *subj, 
                                     char *content_type, char *url)
#endif /* L10N */
{
  char cmd[2048];
#ifdef L10N
  char jis[4096];
#ifdef MIME_HEAD
  char mime[4096];
#endif /* MIME_HEAD */
#endif /* L10N */
/*  char *tmp;*/

  if (!to)
    return NULL;
  
  if (Rdata.mail_filter_command)
    {
      sprintf (cmd, "%s | %s -t", Rdata.mail_filter_command, 
               Rdata.sendmail_command);
    }
  else
    {
      sprintf (cmd, "%s -t", Rdata.sendmail_command);
    }
  if ((_fp = popen (cmd, "w")) == NULL)
    return NULL;

  fprintf (_fp, "To: %s\n", to);
  fprintf (_fp, "Mime-Version: 1.0\n");
#ifdef L10N
  if (strcmp (charset, CHARSET)) {
#endif /* L10N */
  fprintf (_fp, "Subject: %s\n", subj);
#ifdef L10N
  } else {
  mo_codeconv(subj, jis);
#ifdef MIME_HEAD
  MIME_strHeaderEncode(jis, mime, 4096);
  fprintf (_fp, "Subject: %s\n", mime);
#else /* MIME_HEAD */
  fprintf (_fp, "Subject: %s\n", jis);
#endif /* MIME_HEAD */
  }
  fprintf (_fp, "Content-Type: %s; charset=%s\n", content_type, charset);
  fprintf (_fp, "X-Mailer: NCSA Mosaic %s L10N+ on %s\n", 
           MO_VERSION_STRING, MO_MACHINE_TYPE);
#else /* L10N */
  fprintf (_fp, "Content-Type: %s; charset=US-ASCII\n", content_type);
  fprintf (_fp, "X-Mailer: NCSA Mosaic %s on %s\n", 
           MO_VERSION_STRING, MO_MACHINE_TYPE);
#endif /* L10N */
  if (url)
    fprintf (_fp, "X-URL: %s\n", url);

  fprintf (_fp, "\n");
  
  /* Stick in BASE tag as appropriate. */
  if (url && content_type && 
      strcmp (content_type, "text/x-html") == 0)
    fprintf (_fp, "<base href=\"%s\">\n", url);

  return _fp;
}

mo_status mo_finish_sending_mailto_message (void)
{
  if (_fp)
    pclose (_fp);

  _fp = NULL;

  return mo_succeed;
}

/* ------------------------------------------------------------------------ */

mo_status mo_send_mailto_message (char *text, char *to, char *subj, 
                                char *content_type, char *url)
{
  FILE *fp;
#ifdef L10N
  char *jis;
#endif /* L10N */

#ifdef L10N
  jis = malloc(strlen(text) * 4);
  if (mo_codeconv (text, jis))
  fp = mo_start_sending_mailto_message (to, subj, content_type, CHARSET, url);
  else
  fp = mo_start_sending_mailto_message (to, subj, content_type, "us-ascii", url);
#else /* L10N */
  fp = mo_start_sending_mailto_message (to, subj, content_type, url);
#endif /* L10N */
  if (!fp)
    return mo_fail;

#ifdef L10N
  fputs (jis, fp);
  free (jis);
#else /* L10N */  
  fputs (text, fp);
#endif /* L10N */

  mo_finish_sending_mailto_message ();

  return mo_succeed;
}
