/*
 * $Id: wvcncm.c 1.49 1996/08/31 06:57:53 dumoulin Exp $
 */

/*-- This is the first line of WVCNCM.C -------------------------------*/

#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include <stdlib.h>
#include <limits.h>
#include <io.h>					// for _access
#include "wvtb\wvtb.h"			// for toolbar

void enableDemandLogonCtl (HWND hDlg, int forceType);
void SetupEncodingOptions (HWND hDlg, char *startEncoding, BOOL includeCustom, BOOL showNone);

BOOL ProcessEncodingOptions (HWND hDlg, char *newEncodingType);

/*-- function WinVnCommDlg ---------------------------------------------
 *
 *   Dialog function to process the Configure Communications
 *   dialog box.
 */

BOOL FAR PASCAL
WinVnCommDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
#define MAXSTR  32
  static int SaveDemand, saveMailForceType;
  static unsigned int saveNewsForceType;
  static char pszMyNNTPService[MAXSTR];
  int mail_force_radio, news_force_radio;
  char NNTPPassword[MAXNNTPSIZE];
  char TimeZoneBuf[MAXTZONESIZE+5];

  switch (iMessage) {

  case WM_INITDIALOG:
	SetDlgItemText (hDlg, ID_CONFIG_NNTP_SERVER, NNTPHost);
	CheckDlgButton (hDlg, ID_CONFIG_CONNECT_AT_START, ConnectAtStartup);

	SetDlgItemText (hDlg, ID_CONFIG_SMTP_SERVER, SMTPHost);
	SetDlgItemText (hDlg, ID_CONFIG_NNTP_PORT, NNTPService);
	SetDlgItemText (hDlg, ID_CONFIG_AUTH_USERNAME, NNTPUserName);
	MRRDecrypt (NNTPPasswordEncrypted, (unsigned char *) NNTPPassword, MAXNNTPSIZE);
	SetDlgItemText (hDlg, ID_CONFIG_AUTH_PASSWORD, NNTPPassword);
	SetDlgItemText (hDlg, ID_CONFIG_TIMEZONE, TimeZone); 
	SetDlgItemText (hDlg, ID_CONFIG_MAPI_PREFIX, MAPIPrefix);

#if 0 // win32s no longer supported
	if (GetVersion () & 0x80000000)		/* win32s */
	  EnableWindow (GetDlgItem (hDlg, IDD_MAIL_SELECT_MAPI), DISABLE);
#endif
	saveMailForceType = MailForceType;
	if (MailForceType == -1)
	  mail_force_radio = IDD_MAIL_SELECT_AUTO;
	else
	  mail_force_radio = MailForceType + IDD_MAIL_SELECT_NONE;

	CheckRadioButton (hDlg, IDD_MAIL_SELECT_NONE,
					  IDD_MAIL_SELECT_AUTO, mail_force_radio);

	saveNewsForceType = force_xhdr;
	if (force_xhdr == HDR_AUTO)
		news_force_radio = IDD_NEWS_SELECT_AUTO;
    else if (force_xhdr == HDR_XOVER)
        news_force_radio = IDD_NEWS_SELECT_XOVER;   
	else if (force_xhdr == HDR_XHDR)
		news_force_radio = IDD_NEWS_SELECT_XHDR;
	else
        news_force_radio = IDD_NEWS_SELECT_AUTO;

	CheckRadioButton (hDlg, IDD_NEWS_SELECT_BASE,
		              IDD_NEWS_SELECT_AUTO, news_force_radio);

	// PCT, 10/05/94
	CheckDlgButton (hDlg, IDD_SAVEPASSWORD, NNTPSavePassword);

	SaveDemand = MailDemandLogon;
	CheckDlgButton (hDlg, IDD_DEMANDLOGON, SaveDemand);
	enableDemandLogonCtl (hDlg, saveMailForceType);
	EnableWindow (GetDlgItem (hDlg, ID_CONFIG_SMTP_SERVER), (mail_force_radio == IDD_MAIL_SELECT_SMTP || mail_force_radio == IDD_MAIL_SELECT_AUTO));
    EnableWindow (GetDlgItem (hDlg, ID_CONFIG_MAPI_PREFIX), (mail_force_radio == IDD_MAIL_SELECT_MAPI || mail_force_radio == IDD_MAIL_SELECT_AUTO));
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  UsingSocket = 1;
	  ConnectAtStartup = (IsDlgButtonChecked (hDlg, ID_CONFIG_CONNECT_AT_START) != 0);
	  GetDlgItemText (hDlg, ID_CONFIG_NNTP_SERVER, NNTPHost, MAXNNTPSIZE);
	  if (*NNTPHost == '\0') {
		MessageBox (hDlg, "Please enter an NNTP (News) server.", "Invalid NNTP Server", MB_OK | MB_ICONSTOP);
		break;
	  }
	  GetDlgItemText (hDlg, ID_CONFIG_NNTP_PORT, NNTPService, MAXNNTPSIZE);
	  if (*NNTPService == '\0') {
		MessageBox (hDlg, "Please enter an NNTP TCP port.  The most common NNTP port is 119.", "Invalid NNTP Port", MB_OK | MB_ICONSTOP);
		break;
	  }
	  GetDlgItemText (hDlg, ID_CONFIG_SMTP_SERVER, SMTPHost, MAXNNTPSIZE);
	  if (*SMTPHost == '\0' && saveMailForceType == MT_SMTP) {
		MessageBox (hDlg, "Invalid mail server address.  Disabling mail.", "Invalid SMTP Server", MB_OK | MB_ICONSTOP);
		saveMailForceType = MT_NONE;
	  } 
	  GetDlgItemText (hDlg, ID_CONFIG_TIMEZONE, TimeZone, MAXTZONESIZE);
	  if (TimeZone[0] != 0){
	     strcpy(TimeZoneBuf,"TZ=");
		 strcat(TimeZoneBuf,TimeZone);
	     _putenv(TimeZoneBuf);
	  } 
      
      GetDlgItemText (hDlg, ID_CONFIG_MAPI_PREFIX, MAPIPrefix, MAXPREFIXSIZE);
      
	  // PCT, 10/05/94
	  NNTPSavePassword = IsDlgButtonChecked (hDlg, IDD_SAVEPASSWORD);
	  GetDlgItemText (hDlg, ID_CONFIG_AUTH_USERNAME, NNTPUserName, MAXNNTPSIZE);
	  GetDlgItemText (hDlg, ID_CONFIG_AUTH_PASSWORD, NNTPPassword, MAXNNTPSIZE);
	  MRREncrypt ((unsigned char *) NNTPPassword, strlen (NNTPPassword) + 1,
				  NNTPPasswordEncrypted);
	  MailDemandLogon = SaveDemand;

	  if ((saveMailForceType != MailForceType) || 	
		  (saveNewsForceType != force_xhdr)) {	   /* change of mail transport medium
													   Not entirely correct as may change from
													   explicit selection to auto detect which
													   in this case will (but in reality may not)
													   affect a relogin to mail)  */
		MailForceType = saveMailForceType;
		force_xhdr = saveNewsForceType;
		if (force_xhdr == HDR_AUTO ||
			force_xhdr == HDR_XOVER) {
		 xoverp = 1;
		}
		MailCrashExit (hDlg);
		MailInit (hDlg);
		UpdateAllMailMenus ();
	  }
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case IDD_MAIL_SELECT_NONE:
	case IDD_MAIL_SELECT_MAPI:	  
	case IDD_MAIL_SELECT_SMTP:
	  saveMailForceType = wParam - IDD_MAIL_SELECT_NONE;
	  enableDemandLogonCtl (hDlg, saveMailForceType);
	  EnableWindow (GetDlgItem (hDlg, ID_CONFIG_MAPI_PREFIX), (saveMailForceType == MT_MAPI));
	  EnableWindow (GetDlgItem (hDlg, ID_CONFIG_SMTP_SERVER), (saveMailForceType == MT_SMTP));
	  break;

	case IDD_MAIL_SELECT_AUTO:
	  saveMailForceType = -1;
	  enableDemandLogonCtl (hDlg, saveMailForceType);
	  EnableWindow (GetDlgItem (hDlg, ID_CONFIG_SMTP_SERVER), ENABLE);
	  EnableWindow (GetDlgItem (hDlg, ID_CONFIG_MAPI_PREFIX), ENABLE);
	  break;

	case IDD_NEWS_SELECT_XOVER:
	  saveNewsForceType = HDR_XOVER;
	  break;

	case IDD_NEWS_SELECT_AUTO:
	  saveNewsForceType = HDR_AUTO;
	  break;

	case IDD_NEWS_SELECT_XHDR:
	  saveNewsForceType = HDR_XHDR;
	  break;

	case IDD_DEMANDLOGON:
	  SaveDemand = !SaveDemand;
	  CheckDlgButton (hDlg, IDD_DEMANDLOGON, SaveDemand);
	  break; 

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}
/*
 *  enable/disable the check box for the DemandLogon variable
 *  as requested
 *
 *  some mail transports do not require authentification (logon)
 *  so demand (deferred ) logon is not an option 
 *
 */
void 
enableDemandLogonCtl (HWND hDlg, int forceType)
{
  EnableWindow (GetDlgItem (hDlg, IDD_DEMANDLOGON),
				(forceType == -1) || (forceType == MT_MAPI));
}

/*-- function WinVnSaveArtDlg ---------------------------------------
 *
 *  Dialog function to handle Save Article dialog box.
 */

BOOL FAR PASCAL
WinVnSaveArtDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  static int MyAppend;
  char fileName[MAXFILENAME];

  switch (iMessage) {

  case WM_INITDIALOG:
	MyAppend = SaveArtAppend;

	CheckDlgButton (hDlg, IDD_APPEND, MyAppend);
	SetDlgItemText (hDlg, IDD_FILENAME, SaveArtFileName);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_FILENAME, SaveArtFileName, MAXFILENAME - 1);
	  if (*SaveArtFileName == '\0') {
		MessageBox (hDlg, "Please enter a file name before continuing", "Filename Error", MB_OK | MB_ICONSTOP);
		break;
	  }

	  SaveArtAppend = MyAppend;
	  if (!MRRWriteDocument (ActiveArticleDoc, sizeof (TypText), SaveArtFileName, SaveArtAppend)) {
		MessageBox (NetDoc.hDocWnd, "Could not write to file", "Problems saving file", MB_OK | MB_ICONEXCLAMATION);
		*SaveArtFileName = '\0';
	  }
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_BROWSE:
	  fileName[0] = '\0';
	  if (AskForNewFileName (hDlg, fileName, "", MyAppend) == SUCCESS)
		SetDlgItemText (hDlg, IDD_FILENAME, fileName);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case IDD_APPEND:
	  MyAppend = !MyAppend;
	  CheckDlgButton (hDlg, IDD_APPEND, MyAppend);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*-- function WinVnSaveArtsDlg ---------------------------------------
 *
 *  Dialog function to handle Save Articles dialog box.
 *  Same as Save Article dialog, except actual save is deferred until
 *  later (When IDM_RETRIEVE_COMPLETE Message gets sent to Group win)
 *  (JSC)
 */

BOOL FAR PASCAL
WinVnSaveArtsDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  static int MyAppend;
  char fileName[MAXFILENAME];
  OFSTRUCT ofs;
  HFILE hFile;
  UINT mode;

  switch (iMessage) {

  case WM_INITDIALOG:
	MyAppend = SaveArtAppend;

	CheckDlgButton (hDlg, IDD_APPEND, MyAppend);
	CheckDlgButton (hDlg, IDD_KEEP_HEADER_VISIBLE, KeepArticleHeaderVisible);
	SetDlgItemText (hDlg, IDD_FILENAME, SaveArtFileName);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_FILENAME, fileName, MAXFILENAME - 1);
	  if (*fileName == '\0') {
		MessageBox (hDlg, "Please enter a file name before continuing", "Filename Error", MB_OK | MB_ICONSTOP);
		break;
	  }
	  mode = (OpenFile (fileName, &ofs, OF_EXIST) == HFILE_ERROR) ? OF_CREATE : OF_WRITE;
	  if ((hFile = OpenFile (fileName, &ofs, mode)) == HFILE_ERROR) {
		_snprintf (str, MAXINTERNALLINE, "Could not write to file %s", fileName);
		MessageBox (hDlg, str, "Invalid File", MB_OK | MB_ICONSTOP);
		break;
	  }
	  _lclose (hFile);
	  strcpy (SaveArtFileName, fileName);

	  KeepArticleHeaderVisible = IsDlgButtonChecked (hDlg, IDD_KEEP_HEADER_VISIBLE);
	  SaveArtAppend = MyAppend;
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_BROWSE:
	  fileName[0] = '\0';
	  if (AskForNewFileName (hDlg, fileName, "", MyAppend) == SUCCESS)
		SetDlgItemText (hDlg, IDD_FILENAME, fileName);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case IDD_APPEND:
	  MyAppend = !MyAppend;
	  CheckDlgButton (hDlg, IDD_APPEND, MyAppend);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*-- function WinVnDecodeArtsDlg ---------------------------------------
 *
 *  Dialog function to handle Decode Articles dialog box.
 *  (JSC)
 */

BOOL FAR PASCAL
WinVnDecodeArtsDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  int len;

  switch (iMessage) {

  case WM_INITDIALOG:
	SetDlgItemText (hDlg, IDD_DECODE_PATH, DecodePathName);
	CheckDlgButton (hDlg, IDD_EXECUTE_DECODED, ExecuteDecodedFiles);
	CheckDlgButton (hDlg, IDD_KEEP_HEADER_VISIBLE, KeepArticleHeaderVisible);
	CheckDlgButton (hDlg, IDD_VERBOSE_STATUS, CodingStatusVerbose);
	CheckDlgButton (hDlg, IDD_MINIMIZE_CODING_STATUS, MinimizeStatusWindows);
	CheckDlgButton (hDlg, IDD_DUMB_DECODE, DumbDecode);
	CheckDlgButton (hDlg, IDD_INCLUDE_OPEN_ARTS, AlsoDecodeOpenArticles);

	EnableWindow (GetDlgItem (hDlg, IDD_INCLUDE_OPEN_ARTS), (BOOL) (NumArticleWnds > 0));
	EnableWindow (GetDlgItem (hDlg, IDD_KEEP_HEADER_VISIBLE), (BOOL) lParam);
	if (lParam)
	  SetWindowText (hDlg, "Decode Articles");
	else
	  SetWindowText (hDlg, "Decode");
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  AlsoDecodeOpenArticles = (IsDlgButtonChecked (hDlg, IDD_INCLUDE_OPEN_ARTS) != 0);
	  GetDlgItemText (hDlg, IDD_DECODE_PATH, DecodePathName, MAXFILENAME - 1);
	  RemoveTrailingWhiteSpace (DecodePathName);
	  len = strlen (DecodePathName);
	  if (len == 0) {
		MessageBox (hDlg, "Please enter a path name before continuing", "Decode Path", MB_OK);
		break;
	  }

	  /* allow path like c:\ -- but otherwise trim off trailing slashes */
	  if ((len != 3 || DecodePathName[1] != ':' || DecodePathName[2] != '\\') &&
		  DecodePathName[len - 1] == '\\') {
		DecodePathName[len - 1] = '\0';
	  }

	  if (_access (DecodePathName, 0) < 0) {
		sprintf (str, "The path %s does not exist", DecodePathName);
		MessageBox (hDlg, str, "Decode Path", MB_OK | MB_ICONSTOP);
		break;
	  }

	  ExecuteDecodedFiles = (IsDlgButtonChecked (hDlg, IDD_EXECUTE_DECODED) != 0);
	  KeepArticleHeaderVisible = IsDlgButtonChecked (hDlg, IDD_KEEP_HEADER_VISIBLE);
	  CodingStatusVerbose = IsDlgButtonChecked (hDlg, IDD_VERBOSE_STATUS);
	  MinimizeStatusWindows = IsDlgButtonChecked (hDlg, IDD_MINIMIZE_CODING_STATUS);
	  DumbDecode = IsDlgButtonChecked (hDlg, IDD_DUMB_DECODE);
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_BROWSE:
	  if (AskForFilePath (hDlg, DecodePathName, "Select Decode Path") == SUCCESS)
		SetDlgItemText (hDlg, IDD_DECODE_PATH, DecodePathName);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case IDD_SMART_FILER:
	  DialogBox (hInst, "WinvnSmartFiler", hDlg, lpfnWinVnSmartFilerDlg);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}


void
SelectTypeByExtension (HWND hListBox, char *fileName)
{
  char temp[MAXFILENAME];

  GetFileExtension (temp, fileName);
  if (!_stricmp (temp, "gif"))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Image/GIF");
  else if (!_stricmp (temp, "jpg") || !_strnicmp (temp, "jpe", 3))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Image/JPEG");
  else if (!_stricmp (temp, "zip"))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Application/Zip");
  else if (!_stricmp (temp, "mpg") || !_strnicmp (temp, "mpe", 3))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Video/MPEG");
  else if (!_stricmp (temp, "avi"))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Video/AVI");
  else if (!_stricmp (temp, "ps"))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Application/PostScript");
  else if (!_stricmp (temp, "txt") || !_stricmp (temp, "bat") || !_stricmp (temp, "c") || !_stricmp (temp, "cpp") || !_stricmp (temp, "h"))
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Text/Plain");
  else
	SendMessage (hListBox, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) DefaultContentType);
}

/*-- function WinVnAttachDlg ---------------------------------------
 *
 *  Dialog function to handle attachments to postings
 *  pointer to attachment struct should be passed in lParam
 *  jsc 9/24/94
 */

BOOL FAR PASCAL
WinVnAttachDlg (HWND hDlg, unsigned iMessage, WPARAM wParam, LPARAM lParam)
{
  static TypAttachment *thisAttach;
  int i, select;
  extern char *ContentTypes[NUM_CONTENT_TYPES];
  extern char *EncodingTypes[NUM_ENCODING_TYPES];

  switch (iMessage) {
  case WM_INITDIALOG:
	thisAttach = (TypAttachment *) lParam;

	for (i = 0; i < NUM_CONTENT_TYPES; i++)
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE,
						  CB_ADDSTRING, 0, (LPARAM) (LPSTR) ContentTypes[i]);

	// if DefaultContentType is not "other", add the type to the list
	if (*DefaultContentType && _stricmp (DefaultContentType, "Other")) {
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE,
					  CB_ADDSTRING, 0, (LPARAM) (LPSTR) DefaultContentType);
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) DefaultContentType);
	}
	else {
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) "Other");
	}
	CheckDlgButton (hDlg, IDD_MAKE_DEFAULT_CONTENT, 0);
	CheckDlgButton (hDlg, IDD_MAKE_DEFAULT_ENCODING, 0);

	if (*(thisAttach->encodingType))
	  SetupEncodingOptions (hDlg, thisAttach->encodingType, FALSE, TRUE);
	else
	  SetupEncodingOptions (hDlg, DefaultEncodingType, FALSE, TRUE);

	if (*(thisAttach->fileName))
	  SetDlgItemText (hDlg, IDD_FILENAME, thisAttach->fileName);

	if (*(thisAttach->contentType))
	  SetDlgItemText (hDlg, IDD_CONTENT_TYPE, (LPCSTR) thisAttach->contentType);
	else if (*(thisAttach->fileName))
	  SelectTypeByExtension (GetDlgItem (hDlg, IDD_CONTENT_TYPE), thisAttach->fileName);

	CheckDlgButton (hDlg, IDD_ATTACH_NEXT, thisAttach->attachInNewArt);
	break;

  case WM_COMMAND:
	switch (LOWORD (wParam)) {
	case IDD_FILENAME:
	  if (GET_WM_COMMAND_CMD (wParam, lParam) == EN_KILLFOCUS) {
		GetDlgItemText (hDlg, IDD_CONTENT_TYPE, (LPSTR) str, MAXINTERNALLINE);
		if (*str == '\0') {
		  GetDlgItemText (hDlg, IDD_FILENAME, str, MAXINTERNALLINE);
		  SelectTypeByExtension (GetDlgItem (hDlg, IDD_CONTENT_TYPE), str);
		}
	  }
	  break;

	case IDOK:
	  GetDlgItemText (hDlg, IDD_FILENAME, thisAttach->fileName, MAXINTERNALLINE);
	  if (*(thisAttach->fileName) == '\0') {
		MessageBox (hDlg, "Please enter a filename to attach", "Filename error", MB_OK);
		break;
	  }
//              if (_access(thisAttach->fileName, 0) < 0) {
	  if ((thisAttach->numBytes = GetFileLength (thisAttach->fileName)) == 0) {
		sprintf (str, "The file %s does not exist or is empty", thisAttach->fileName);
		MessageBox (hDlg, str, "Attach File", MB_OK | MB_ICONSTOP);
		break;
	  }

	  GetDlgItemText (hDlg, IDD_CONTENT_TYPE, (LPSTR) thisAttach->contentType, MAXINTERNALLINE);
	  if (IsDlgButtonChecked (hDlg, IDD_MAKE_DEFAULT_CONTENT))
		strcpy (DefaultContentType, thisAttach->contentType);

	  select = (int) SendDlgItemMessage (hDlg, IDD_CODING_TYPE, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
	  if (select != CB_ERR)
		SendDlgItemMessage (hDlg, IDD_CODING_TYPE,
							CB_GETLBTEXT, (WPARAM) select, (LPARAM) (LPSTR) thisAttach->encodingType);
	  if (IsDlgButtonChecked (hDlg, IDD_MAKE_DEFAULT_ENCODING))
		strcpy (DefaultEncodingType, thisAttach->encodingType);

	  thisAttach->attachInNewArt = IsDlgButtonChecked (hDlg, IDD_ATTACH_NEXT);
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_CANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case ID_BROWSE:
	  if (AskForExistingFileName (hDlg, thisAttach->fileName, "Open File To Attach") == SUCCESS) {
		SetDlgItemText (hDlg, IDD_FILENAME, thisAttach->fileName);
		SelectTypeByExtension (GetDlgItem (hDlg, IDD_CONTENT_TYPE), thisAttach->fileName);
	  }
	  break;

	default:
	  return FALSE;
	}

  default:
	return FALSE;
  }
  return TRUE;
}

/*-- function WinVnAttachPrefsDlg ---------------------------------------
 *
 *  Dialog function to handle attachment preferences
 *  jsc 9/24/94
 */

BOOL FAR PASCAL
WinVnAttachPrefsDlg (HWND hDlg, unsigned iMessage, WPARAM wParam, LPARAM lParam)
{
  char temp[MAXINTERNALLINE];
  extern char *GetFileExtension ();
  extern BOOL isnumber (char *str);
  register int i;
  int genMIME, result, num;
  extern char *ContentTypes[NUM_CONTENT_TYPES];
  long newLength;

  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, IDD_ATTACH_NEXT, DefaultAttachInNewArt);

	SendDlgItemMessage (hDlg, IDD_ARTICLE_SPLIT_LENGTH,
						CB_ADDSTRING, 0, (LPARAM) (LPSTR) "32000");
	SendDlgItemMessage (hDlg, IDD_ARTICLE_SPLIT_LENGTH,
						CB_ADDSTRING, 0, (LPARAM) (LPSTR) "60000");
	SendDlgItemMessage (hDlg, IDD_ARTICLE_SPLIT_LENGTH,
						CB_ADDSTRING, 0, (LPARAM) (LPSTR) "100000");
	SendDlgItemMessage (hDlg, IDD_ARTICLE_SPLIT_LENGTH,
						CB_ADDSTRING, 0, (LPARAM) (LPSTR) "None");

	if (ArticleSplitLength == 0) {
	  SetDlgItemText (hDlg, IDD_ARTICLE_SPLIT_LENGTH, "None");
	}
	else {
	  SetDlgItemText (hDlg, IDD_ARTICLE_SPLIT_LENGTH, ltoa (ArticleSplitLength, str, 10));
	}

	SetupEncodingOptions (hDlg, DefaultEncodingType, TRUE, TRUE);

	SetDlgItemText (hDlg, IDD_SUBJECT_TEMPLATE, SubjectTemplate);

	CheckDlgButton (hDlg, IDD_GENERATE_MIME, GenerateMIME);
	if (!GenerateMIME) {
//	  EnableWindow (GetDlgItem (hDlg, IDD_MIME_BOUNDARY), FALSE);
	  EnableWindow (GetDlgItem (hDlg, IDD_CONTENT_TYPE), FALSE);
	}
	CheckDlgButton (hDlg, IDD_MIME_USAGE_SUGGESTIONS, MIMEUsageSuggestions);

	for (i = 0; i < NUM_CONTENT_TYPES; i++)
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE,
						  CB_ADDSTRING, 0, (LPARAM) (LPSTR) ContentTypes[i]);

	if (_stricmp (DefaultContentType, "Other"))
	  SendDlgItemMessage (hDlg, IDD_CONTENT_TYPE,
					  CB_ADDSTRING, 0, (LPARAM) (LPSTR) DefaultContentType);

//	SendDlgItemMessage (hDlg, IDD_MIME_BOUNDARY, EM_LIMITTEXT, (WPARAM) MAXBOUNDARYLINE, 0L);
//	SetDlgItemText (hDlg, IDD_MIME_BOUNDARY, MIMEBoundary);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  DefaultAttachInNewArt = IsDlgButtonChecked (hDlg, IDD_ATTACH_NEXT);
	  if (ProcessEncodingOptions (hDlg, DefaultEncodingType) == FAIL)
		break;

	  GetDlgItemText (hDlg, IDD_ARTICLE_SPLIT_LENGTH, temp, MAXINTERNALLINE);
	  if (!_stricmp (temp, "None")) {
		ArticleSplitLength = 0;
	  }
	  else {
		if (isnumber (temp)) {
		  newLength = atol (temp);
		}
		else {
		  MessageBox (hDlg, "The article split length must be a number of bytes or the word 'None'", "Article Split Length Error", MB_OK);
		  break;
		}
		if (newLength > 0L && newLength < 4096L) {	// allow 0

		  MessageBox (hDlg, "Please choose an article split length greater than 4k",
					  "Article Length Error", MB_OK | MB_ICONSTOP);
		  break;
		}
		if (newLength > 60000L &&
			MessageBox (hDlg, "Articles longer than 60,000 bytes may be transferred incorrectly by some news agents.\nContinue?",
		 "Article Length Warning", MB_YESNO | MB_ICONINFORMATION) == IDNO) {
		  break;
		}
		ArticleSplitLength = newLength;
	  }

	  GetDlgItemText (hDlg, IDD_SUBJECT_TEMPLATE, SubjectTemplate, MAXINTERNALLINE);

	  GenerateMIME = IsDlgButtonChecked (hDlg, IDD_GENERATE_MIME);
//	  GetDlgItemText (hDlg, IDD_MIME_BOUNDARY, MIMEBoundary, MAXBOUNDARYLEN);

	  // *** should check here that characters in boundary are all valid
	  GetDlgItemText (hDlg, IDD_CONTENT_TYPE, (LPSTR) DefaultContentType, MAXINTERNALLINE);

	  MIMEUsageSuggestions = IsDlgButtonChecked (hDlg, IDD_MIME_USAGE_SUGGESTIONS);
	  if (MIMEUsageSuggestions) {
		num = EncodingTypeToNum (DefaultEncodingType);
		if (GenerateMIME && num != CODE_NONE && num != CODE_BASE64) {
		  sprintf (str, "When using %s encoding, MIME headers are not recommended.\nWould you like to deactivate MIME header generation?", DefaultEncodingType);
		  result = MessageBox (hDlg, str, "MIME Usage Suggestion", MB_YESNOCANCEL | MB_ICONINFORMATION);
		  if (result == IDYES)
			GenerateMIME = FALSE;
		  else if (result == IDCANCEL)
			break;

		}
		if (!GenerateMIME && num == CODE_BASE64) {
		  result = MessageBox (hDlg, "When using Base-64 encoding, MIME header generation is recommended.\nWould you like to activate MIME header generation?",
			  "MIME Usage Suggestion", MB_YESNOCANCEL | MB_ICONINFORMATION);
		  if (result == IDYES)
			GenerateMIME = TRUE;
		  else if (result == IDCANCEL)
			break;
		}
	  }
	  EndDialog (hDlg, TRUE);
	  break;

	case IDD_GENERATE_MIME:
	  genMIME = (BOOL) IsDlgButtonChecked (hDlg, IDD_GENERATE_MIME);
//	  EnableWindow (GetDlgItem (hDlg, IDD_MIME_BOUNDARY), genMIME);
	  EnableWindow (GetDlgItem (hDlg, IDD_CONTENT_TYPE), genMIME);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}
/*-- function WinVnEncodeDlg ---------------------------------------
 *
 *  Dialog function to handle encoding to a file
 *  (JSC)
 */

BOOL FAR PASCAL
WinVnEncodeDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  static TypAttachment *thisAttach;

  switch (iMessage) {
  case WM_INITDIALOG:
	thisAttach = (TypAttachment *) lParam;
	// include custom, but do not show "none" in the type-list
	SetupEncodingOptions (hDlg, DefaultEncodingType, TRUE, FALSE);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_FILENAME, thisAttach->fileName, MAXFILENAME - 1);
	  if (*(thisAttach->fileName) == '\0') {
		MessageBox (hDlg, "Please enter a filename to encode", "Filename error", MB_OK);
		break;
	  }

	  if (_access (thisAttach->fileName, 0) < 0) {
		sprintf (str, "The file %s does not exist", thisAttach->fileName);
		MessageBox (hDlg, str, "Filename error", MB_OK | MB_ICONSTOP);
		break;
	  }

	  if (ProcessEncodingOptions (hDlg, thisAttach->encodingType) == FAIL)
		break;

	  if (IsDlgButtonChecked (hDlg, IDD_MAKE_DEFAULT_ENCODING))
		strcpy (DefaultEncodingType, thisAttach->encodingType);

	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case ID_BROWSE:
	  if (AskForExistingFileName (hDlg, thisAttach->fileName, "Open File To Be Encoded") == SUCCESS)
		SetDlgItemText (hDlg, IDD_FILENAME, thisAttach->fileName);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*----------------------------------------------------------------------
 * Encoding options functions for use by two dialogs
 * wvattachdlg and wvencodedlg
 * (JSC)
 */
void
SetupEncodingOptions (HWND hDlg, char *startEncoding, BOOL includeCustom, BOOL showNone)
{
  register int i;
  char temp[MAXENCODINGTYPELEN];

  if (*startEncoding == '\0')
	startEncoding = DefaultEncodingType;

  // This combo box is NOSORT, so entries can be indexed in order they 
  // added here. But BE CAREFUL!
  for (i = 0; i < NUM_ENCODING_TYPES; i++) {
	if (showNone || _stricmp (EncodingTypes[i], "None")) {
	  SendDlgItemMessage (hDlg, IDD_CODING_TYPE,
						CB_ADDSTRING, 0, (LPARAM) (LPSTR) EncodingTypes[i]);
	}
  }

  if (EncodingTypeToNum (startEncoding) == CODE_UNKNOWN)
	strcpy (temp, "None");
  else
	strcpy (temp, startEncoding);

  SendDlgItemMessage (hDlg, IDD_CODING_TYPE, CB_SELECTSTRING, (WPARAM) - 1, (LPARAM) (LPSTR) temp);

  if (includeCustom && UserCodingTable[0] != '\0')
	SetDlgItemText (hDlg, IDD_CUSTOM_TABLE, UserCodingTable);
}

BOOL
ProcessEncodingOptions (HWND hDlg, char *newEncodingType)
{
  char temp[MAXINTERNALLINE];
  int select, x;
  char dummyMap[128];

  select = (int) SendDlgItemMessage (hDlg, IDD_CODING_TYPE, CB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
  if (select != CB_ERR)
	SendDlgItemMessage (hDlg, IDD_CODING_TYPE,
					  CB_GETLBTEXT, (WPARAM) select, (LPARAM) (LPSTR) temp);

  if (!_stricmp (temp, "Custom"))
	if (GetDlgItemText (hDlg, IDD_CUSTOM_TABLE, UserCodingTable, CODINGTABLESIZE + 1)) {
	  if (strlen (UserCodingTable) != CODINGTABLESIZE) {
		MessageBox (hDlg, "Invalid encoding table.  The table must contain 64 characters.", "Custom Encoding Error", MB_OK);
		return (FAIL);
	  }
	  if ((x = CreateCodingMap (dummyMap, UserCodingTable)) != -1) {
		sprintf (temp, "Invalid encoding table.  The table must have no duplicate entries (duplicate is %c).", x);
		MessageBox (hDlg, temp, "Custom Encoding Error", MB_OK);
		return (FAIL);
	  }
	}
	else {
	  MessageBox (hDlg, "To use a custom encoding, you must enter an encoding table", "Custom Encoding Error", MB_OK);
	  return (FAIL);
	}

  strcpy (newEncodingType, temp);

  return (OK);
}

/*-- function WinVnExitDlg---------------------------------------
 *
 *  Dialog function to handle exit from WinVn
 *  Sets globals SaveNewsrc and SaveConfig - leaves actual saving up to caller
 *  (JSC 1/8/94)
 */

BOOL FAR PASCAL
WinVnExitDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, IDD_SAVE_NEWSRC, 1);
	CheckDlgButton (hDlg, IDD_SAVE_CONFIG, 1);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  SaveNewsrc = IsDlgButtonChecked (hDlg, IDD_SAVE_NEWSRC);
	  SaveConfig = IsDlgButtonChecked (hDlg, IDD_SAVE_CONFIG);
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*-- function WinVnFindDlg ---------------------------------------
 *
 *  Dialog function to handle Search dialog box.
 */

BOOL FAR PASCAL
WinVnFindDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  static int MyAppend;

  switch (iMessage) {

  case WM_INITDIALOG:
	SetDlgItemText (hDlg, IDD_SEARCH_STRING, FindDoc->SearchStr);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_SEARCH_STRING, FindDoc->SearchStr, MAXFINDSTRING - 1);

	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnPersonalInfoDlg ----------------------------------
 *
 *  Dialog function to obtain personal configuration info
 *  (Name, email address, etc.) from the user.
 */

BOOL FAR PASCAL
WinVnPersonalInfoDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  switch (iMessage) {
  case WM_INITDIALOG:
	SetDlgItemText (hDlg, ID_CONFIG_EMAIL, MailAddress);
	SetDlgItemText (hDlg, ID_CONFIG_NAME, UserName);
	SetDlgItemText (hDlg, IDD_REPLY_TO, ReplyTo);
	SetDlgItemText (hDlg, ID_CONFIG_ORG, Organization);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, ID_CONFIG_EMAIL, MailAddress, MAILLEN - 1);
	  GetDlgItemText (hDlg, ID_CONFIG_NAME, UserName, MAILLEN - 1);
	  GetDlgItemText (hDlg, IDD_REPLY_TO, ReplyTo, MAILLEN - 1);
	  GetDlgItemText (hDlg, ID_CONFIG_ORG, Organization, MAILLEN - 1);

	  if (!strcmp (MailAddress, ReplyTo)) {		/* clear identical reply-to */
	    MessageBox(hDlg, 
	    	"You do not need to set a reply-to address if it is identical to "
	    	"your e-mail address", "Clearing Identical Reply-To", MB_OK);
		*ReplyTo = '\0';
		SetDlgItemText(hDlg, IDD_REPLY_TO, "");
		break;
	  }
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

// Configure Execute Dialog for setting up Universal Resource Locator (URL)
// interface between WinVN and World Wide Web (WWW) or other browsers.
//
//                                                     JD 7/23/95

BOOL FAR PASCAL
WinVnExecuteInfoDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  switch (iMessage) {
  case WM_INITDIALOG:
	SetDlgItemText (hDlg, ID_CONFIG_URL_HTTP,HttpClient);
	SetDlgItemText (hDlg, ID_CONFIG_URL_FTP,FtpClient);
	SetDlgItemText (hDlg, ID_CONFIG_URL_GOPHER,GopherClient);
	SetDlgItemText (hDlg, ID_CONFIG_URL_WAIS, WaisClient);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
		
	  GetDlgItemText (hDlg, ID_CONFIG_URL_HTTP, HttpClient, MAXFILENAME-1);
	  GetDlgItemText (hDlg, ID_CONFIG_URL_FTP, FtpClient, MAXFILENAME-1);
	  GetDlgItemText (hDlg, ID_CONFIG_URL_GOPHER, GopherClient, MAXFILENAME-1);
	  GetDlgItemText (hDlg, ID_CONFIG_URL_WAIS, WaisClient, MAXFILENAME-1);
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnComposePrefsDlg ---------------------------------------------
 *
 * Composition prefs
 *
 * jsc 9/28/94
 */

BOOL FAR PASCAL
WinVnComposePrefsDlg (HWND hDlg, unsigned iMessage, WPARAM wParam, LPARAM lParam)
{
  static int MyShowFrom, MyShowOrg, MyShowReplyTo, MyShowKeywords, MyShowSummary,
    MyShowDist, MyShowFollowupTo;
  char temp[MAXFILENAME];

  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, IDD_WORD_WRAP, WordWrap);
	CheckDlgButton (hDlg, IDD_PREFILL_CC, PrefillCcAddress);
	CheckDlgButton (hDlg, IDD_SHOW_FROM_HDR, ShowFromHdr);
	CheckDlgButton (hDlg, IDD_SHOW_ORG_HDR, ShowOrgHdr);
	CheckDlgButton (hDlg, IDD_SHOW_REPLYTO_HDR, ShowReplyToHdr);
	CheckDlgButton (hDlg, IDD_SHOW_KEYWORDS_HDR, ShowKeywordsHdr);
	CheckDlgButton (hDlg, IDD_SHOW_SUMMARY_HDR, ShowSummaryHdr);
	CheckDlgButton (hDlg, IDD_SHOW_DISTRIBUTION_HDR, ShowDistributionHdr);
	CheckDlgButton (hDlg, IDD_SHOW_FOLLOWUPTO_HDR, ShowFollowupToHdr);
	CheckDlgButton (hDlg, IDD_ENABLE_SIG, EnableSig);
	SetDlgItemText (hDlg, IDD_FILENAME, SigFileName);
	SetDlgItemText (hDlg, IDD_FOLLOWUP_TEMPLATE, FollowupSaysTemplate);
	SetDlgItemText (hDlg, IDD_REPLY_TEMPLATE, ReplySaysTemplate);
	MyShowFrom = ShowFromHdr;
	MyShowOrg = ShowOrgHdr;
	MyShowReplyTo = ShowReplyToHdr;
	MyShowKeywords = ShowKeywordsHdr;
	MyShowSummary = ShowSummaryHdr;
	MyShowDist = ShowDistributionHdr;
	MyShowFollowupTo = ShowFollowupToHdr;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  WordWrap = (IsDlgButtonChecked (hDlg, IDD_WORD_WRAP) != 0);
	  PrefillCcAddress = (IsDlgButtonChecked (hDlg, IDD_PREFILL_CC) != 0);
	  ShowFromHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_FROM_HDR) != 0);
	  ShowOrgHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_ORG_HDR) != 0);
	  ShowReplyToHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_REPLYTO_HDR) != 0);
	  ShowKeywordsHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_KEYWORDS_HDR) != 0);
	  ShowSummaryHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_SUMMARY_HDR) != 0);
	  ShowDistributionHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_DISTRIBUTION_HDR) != 0);
	  ShowFollowupToHdr = (IsDlgButtonChecked (hDlg, IDD_SHOW_FOLLOWUPTO_HDR) != 0);
	  GetDlgItemText (hDlg, IDD_FOLLOWUP_TEMPLATE, FollowupSaysTemplate, MAXINTERNALLINE - 1);
	  GetDlgItemText (hDlg, IDD_REPLY_TEMPLATE, ReplySaysTemplate, MAXINTERNALLINE - 1);

	  if (MyShowFrom != ShowFromHdr ||
		  MyShowOrg != ShowOrgHdr ||
		  MyShowReplyTo != ShowReplyToHdr ||
		  MyShowKeywords != ShowKeywordsHdr ||
		  MyShowSummary != ShowSummaryHdr ||
		  MyShowFollowupTo != ShowFollowupToHdr ||
		  MyShowDist != ShowDistributionHdr) {
		RefreshComposeWnds ();
	  }

	  EnableSig = IsDlgButtonChecked (hDlg, IDD_ENABLE_SIG);
	  GetDlgItemText (hDlg, IDD_FILENAME, temp, MAXFILENAME - 1);
	  if (EnableSig) {
		if (*temp == '\0' || _access (temp, 0) < 0) {
		  MessageBox (hDlg, "Invalid signature file.  Signature disabled.",
					  "Invalid Filename", MB_OK | MB_ICONSTOP);
		  EnableSig = FALSE;
		  break;
		}
		ResetTextBlock (Signature);
		if (ReadFileToTextBlock (hDlg, Signature, temp) == FAIL)
		  break;

		if (Signature->numLines > BIG_SIG_FILE) {
		  sprintf (str, "Do you really want a %lu line signature?", Signature->numLines);
		  if (MessageBox (hDlg, str, "Big Signature!", MB_YESNO | MB_ICONQUESTION) == IDNO) {
			ResetTextBlock (Signature);
			break;
		  }
		}
	  }
	  strcpy (SigFileName, temp);

	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case ID_BROWSE:
	  if (AskForExistingFileName (hDlg, temp, "Select Signature File") == SUCCESS) {
		SetDlgItemText (hDlg, IDD_FILENAME, temp);
	  }
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;

}

/*--- Function WinVnConfigArticleDlg ---------------------------------------------
 *
 * Article prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnConfigArticleDlg (HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  int ok, num;
  static int MyItalicizeQuotes;

  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, ID_WRAP_INCOMING_TEXT, WrapIncomingArticleText);
	SetDlgItemInt (hDlg, ID_WRAP_INCOMING_TEXT_LIMIT, WrapIncomingArticleTextLength, TRUE);
	CheckDlgButton (hDlg, ID_TRIM_HEADERS, TrimHeaders);
	CheckDlgButton (hDlg, ID_CONFIG_NEW_WND_ARTICLE, NewArticleWindow);
	CheckDlgButton (hDlg, ID_SCROLL_PAST_HEADERS, ScrollPastHeaders);
	CheckDlgButton (hDlg, ID_QUOTES_IN_ITALICS, ItalicizeQuotes);
	MyItalicizeQuotes = ItalicizeQuotes;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  WrapIncomingArticleText = (IsDlgButtonChecked (hDlg, ID_WRAP_INCOMING_TEXT) != 0);
	  num = GetDlgItemInt (hDlg, ID_WRAP_INCOMING_TEXT_LIMIT, &ok, TRUE);
	  if (num && (num < 15 || num > 150)) {
		MessageBox (hDlg, "Please choose an article wrap length between 15 and 150 chars.",
					"Invalid Wrap Length", MB_OK | MB_ICONSTOP);
		break;
	  }
	  WrapIncomingArticleTextLength = num;
	  if (!WrapIncomingArticleTextLength) {
		WrapIncomingArticleText = FALSE;
	  }
	  TrimHeaders = (IsDlgButtonChecked (hDlg, ID_TRIM_HEADERS) != 0);
	  NewArticleWindow = (IsDlgButtonChecked (hDlg, ID_CONFIG_NEW_WND_ARTICLE) != 0);
	  ScrollPastHeaders = (IsDlgButtonChecked (hDlg, ID_SCROLL_PAST_HEADERS) != 0);
	  ItalicizeQuotes = (IsDlgButtonChecked (hDlg, ID_QUOTES_IN_ITALICS) != 0);
	  if (ItalicizeQuotes != MyItalicizeQuotes)
		RefreshArticleWnds ();

	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnConfigArticleListDlg ---------------------------------------------
 *
 * Article-list (for a group) prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnConfigArticleListDlg (HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  char numStr[20];
  static int MyFullSubject;
  static char MyDepth;

  switch (iMessage) {
  case WM_INITDIALOG:
	SetDlgItemText (hDlg, IDD_ART_THRESHOLD, ltoa (article_threshold, numStr, 10));
	SetDlgItemText (hDlg, IDD_MIN_TO_READ, ltoa (min_to_retrieve, numStr, 10));
	CheckDlgButton (hDlg, ID_CONFIG_SHOWUNREADONLY, ShowUnreadOnly);
	CheckDlgButton (hDlg, ID_CONFIG_NEW_WND_GROUP, ViewNew);
	CheckDlgButton (hDlg, ID_CONFIG_MULTI_SELECT, ArtListMultiSelect);
	CheckDlgButton (hDlg, ID_CONFIG_SAVE_NEWSRC_ON_CLOSE, SaveNewsrcOnClose);
	CheckDlgButton (hDlg, ID_CONFIG_CROSSPOST, TrackSubscribedCrossposts);
	CheckDlgButton (hDlg, ID_CONFIG_CROSSPOST_UNSUB, TrackUnsubscribedCrossposts);
	CheckDlgButton (hDlg, ID_CONFIG_FULLNAMEFROM, FullNameFrom);
	CheckDlgButton (hDlg, ID_CONFIG_THREADS, threadp);
	CheckDlgButton (hDlg, ID_CONFIG_THREADS_FULL_SUBJECT, ThreadFullSubject);
	CheckDlgButton (hDlg, ID_ENABLE_KILLFILE, bEnableArticleAction);

	SendDlgItemMessage (hDlg, ID_THREAD_DEPTH_INDICATOR, EM_LIMITTEXT, (WPARAM) 1, 0L);
	SetDlgItemText (hDlg, ID_THREAD_DEPTH_INDICATOR, ThreadDepthIndicator);

	MyFullSubject = ThreadFullSubject;
	MyDepth = *ThreadDepthIndicator;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  ShowUnreadOnly = (IsDlgButtonChecked (hDlg, ID_CONFIG_SHOWUNREADONLY) != 0);
	  ViewNew = (IsDlgButtonChecked (hDlg, ID_CONFIG_NEW_WND_GROUP) != 0);
	  ArtListMultiSelect = (IsDlgButtonChecked (hDlg, ID_CONFIG_MULTI_SELECT) != 0);
	  SaveNewsrcOnClose = (IsDlgButtonChecked (hDlg, ID_CONFIG_SAVE_NEWSRC_ON_CLOSE) != 0);
	  TrackSubscribedCrossposts = (IsDlgButtonChecked (hDlg, ID_CONFIG_CROSSPOST) != 0);
	  TrackUnsubscribedCrossposts = (IsDlgButtonChecked (hDlg, ID_CONFIG_CROSSPOST_UNSUB) != 0);
	  FullNameFrom = (IsDlgButtonChecked (hDlg, ID_CONFIG_FULLNAMEFROM) != 0);
	  threadp = (IsDlgButtonChecked (hDlg, ID_CONFIG_THREADS) != 0);
	  bEnableArticleAction = (IsDlgButtonChecked (hDlg, ID_ENABLE_KILLFILE) != 0);
	  ThreadFullSubject = (IsDlgButtonChecked (hDlg, ID_CONFIG_THREADS_FULL_SUBJECT) != 0);
	  GetDlgItemText (hDlg, ID_THREAD_DEPTH_INDICATOR, ThreadDepthIndicator, 2);
	  ThreadDepthIndicator[1] = '\0';
	  if (ThreadFullSubject != MyFullSubject || *ThreadDepthIndicator != MyDepth)
		RefreshGroupWnds ();

	  GetDlgItemText (hDlg, IDD_ART_THRESHOLD, numStr, 20);
	  if (atol(numStr) <= 0){
	     EndDialog(hDlg, FALSE);
	  }
	  else {
	     article_threshold = atol (numStr);
	     GetDlgItemText (hDlg, IDD_MIN_TO_READ, numStr, 20);
	     min_to_retrieve = atol (numStr);

	    /* 0 or a bogus value means they don't want a threshold */
	    if (!article_threshold)
		article_threshold = INT_MAX;
     	EndDialog (hDlg, TRUE);
	  }
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnConfigGroupListDlg ---------------------------------------------
 *
 * Group-list (the usenet window) prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnConfigGroupListDlg (HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  int temp, item;

  switch (iMessage) {
  case WM_INITDIALOG:
	CheckRadioButton (hDlg, ID_DOLIST_BASE, ID_DOLIST_ASK, DoList + ID_DOLIST_BASE);
	CheckDlgButton (hDlg, ID_CONFIG_MULTI_SELECT, GroupListMultiSelect);
	CheckDlgButton (hDlg, ID_CONFIG_SHOWUNSUB, ShowUnsubscribed);
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GroupListMultiSelect = (IsDlgButtonChecked (hDlg, ID_CONFIG_MULTI_SELECT) != 0);

	  for (item = ID_DOLIST_BASE; item <= ID_DOLIST_ASK; item++) {
		if (IsDlgButtonChecked (hDlg, item)) {
		  DoList = item - ID_DOLIST_BASE;
		}
	  }
	  /* If the user has changed the ShowUnsubscribed option, we must
	   * recompute which lines are active and redisplay.  
	   * Reset the window to the top to make sure that everything
	   * will display OK.
	   * There is some question in my mind whether this code will
	   * work OK if the first screen's worth of groups are unsubscribed,
	   * but it *should* work.
	   */
	  temp = (IsDlgButtonChecked (hDlg, ID_CONFIG_SHOWUNSUB) != 0);
	  if (temp != ShowUnsubscribed) {
		ShowUnsubscribed = temp;
		NetDoc.LongestLine = 0;
		SetGroupActiveLines ();
		ScreenToTop (&NetDoc);
		InvalidateRect (NetDoc.hDocWnd, NULL, FALSE);
		SendMessage (NetDoc.hWndTB, TB_CHECKBUTTON, IDB_TOGGLE_VIEW_UNSUB, ShowUnsubscribed);
	  }
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnConfigCodingPrefsDlg ---------------------------------------------
 *
 * Decoding prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnConfigCodingPrefsDlg (HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  static int MyAlwaysOnTop;

  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, ID_STATUSALWAYSONTOP, BlockCodingStatusAlwaysOnTop);
	CheckDlgButton (hDlg, IDD_VERBOSE_STATUS, CodingStatusVerbose);
	CheckDlgButton (hDlg, IDD_MINIMIZE_CODING_STATUS, MinimizeStatusWindows);
	CheckDlgButton (hDlg, IDD_KEEP_HEADER_VISIBLE, KeepArticleHeaderVisible);
	CheckDlgButton (hDlg, IDD_EXECUTE_DECODED, ExecuteDecodedFiles);
	CheckDlgButton (hDlg, IDD_DUMB_DECODE, DumbDecode);
	CheckDlgButton (hDlg, IDD_INCLUDE_OPEN_ARTS, AlsoDecodeOpenArticles);

	MyAlwaysOnTop = BlockCodingStatusAlwaysOnTop;
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  BlockCodingStatusAlwaysOnTop = (IsDlgButtonChecked (hDlg, ID_STATUSALWAYSONTOP) != 0);
	  CodingStatusVerbose = (IsDlgButtonChecked (hDlg, IDD_VERBOSE_STATUS) != 0);
	  MinimizeStatusWindows = (IsDlgButtonChecked (hDlg, IDD_MINIMIZE_CODING_STATUS) != 0);
	  KeepArticleHeaderVisible = (IsDlgButtonChecked (hDlg, IDD_KEEP_HEADER_VISIBLE) != 0);
	  ExecuteDecodedFiles = (IsDlgButtonChecked (hDlg, IDD_EXECUTE_DECODED) != 0);
	  DumbDecode = IsDlgButtonChecked (hDlg, IDD_DUMB_DECODE);
	  AlsoDecodeOpenArticles = (IsDlgButtonChecked (hDlg, IDD_INCLUDE_OPEN_ARTS) != 0);

	  if (BlockCodingStatusAlwaysOnTop != MyAlwaysOnTop)
		RefreshCodedBlockWnd ();

	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*--- Function WinVnConfigConfirmationDlg ---------------------------------------------
 *
 * Confirmations prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnConfigConfirmationDlg (HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  switch (iMessage) {
  case WM_INITDIALOG:
	CheckDlgButton (hDlg, ID_CONFIG_CONFIRM_BATCH, ConfirmBatchOps);
	CheckDlgButton (hDlg, ID_CONFIRM_DISCONNECT, ConfirmDisconnect);
	CheckDlgButton (hDlg, ID_CONFIG_CONFIRM_REPLY_TO, ConfirmReplyTo);
	CheckDlgButton (hDlg, ID_CONFIG_CONFIRM_EXIT, ConfirmSaveOnExit);
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  ConfirmBatchOps = (IsDlgButtonChecked (hDlg, ID_CONFIG_CONFIRM_BATCH) != 0);
	  ConfirmDisconnect = (IsDlgButtonChecked (hDlg, ID_CONFIRM_DISCONNECT) != 0);
	  ConfirmReplyTo = (IsDlgButtonChecked (hDlg, ID_CONFIG_CONFIRM_REPLY_TO) != 0);
	  ConfirmSaveOnExit = (IsDlgButtonChecked (hDlg, ID_CONFIG_CONFIRM_EXIT) != 0);
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*-- function WinVnThresholdDlg ---------------------------------------
 *
 *  Dialog function to ask how many article headers we
 *  want to retrieve.
 */
BOOL FAR PASCAL
WinVnThresholdDlg(HWND hDlg, unsigned iMessage, WORD wParam, LONG lParam)
{
  char numStr[20];

  switch (iMessage) {

  case WM_INITDIALOG:
	sprintf (str, "%lu articles in group, %lu unseen", arts_to_retrieve, est_num_unread);
	SetWindowText (hDlg, (LPCSTR) str);
	break;
  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_ARTS_TO_GRAB, numStr, 20);
	  arts_to_retrieve = atol (numStr);
	  if (arts_to_retrieve > 0)
		EndDialog (hDlg, TRUE);
	  else
	    {
	    arts_to_retrieve = 0;
	    EndDialog (hDlg, FALSE);
		}
	  break;

	case ID_CANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case ID_100_ARTS:
	  arts_to_retrieve = 100L;
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_250_ARTS:
	  arts_to_retrieve = 250L;
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_500_ARTS:
	  arts_to_retrieve = 500L;
	  EndDialog (hDlg, TRUE);
	  break;

	case ID_THRESHOLD_ALL:
	  EndDialog (hDlg, ID_THRESHOLD_ALL);
	  break;

	case ID_THRESHOLD_UNREAD:
	  EndDialog (hDlg, ID_THRESHOLD_UNREAD);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}


/*--- Function WinVnLogOptDlg ---------------------------------------------
 *
 * Logging prefs
 *
 * jsc 9/28/94
 */
BOOL FAR PASCAL
WinVnLogOptDlg (HWND hDlg, unsigned int iMessage, WORD wParam, LONG lParam)
{
  char fileName[MAXFILENAME];
  UINT mode;
  OFSTRUCT ofs;
  HFILE hFile;

  switch (iMessage) {

  case WM_INITDIALOG:
	CheckDlgButton (hDlg, IDD_MAILLOG, MailLog);
	CheckDlgButton (hDlg, IDD_POSTLOG, PostLog);
	SetDlgItemText (hDlg, IDD_MAILNAME, MailLogFile);
	SetDlgItemText (hDlg, IDD_POSTNAME, PostLogFile);

	/* mail logging only works for SMTP-mail at present */
	EnableWindow (GetDlgItem (hDlg, IDD_MAILLOG), (MailCtrl.MailType == MT_SMTP));
	EnableWindow (GetDlgItem (hDlg, IDD_MAILNAME), (MailCtrl.MailType == MT_SMTP));
	EnableWindow (GetDlgItem (hDlg, ID_BROWSEMAIL), (MailCtrl.MailType == MT_SMTP));
	break;

  case WM_COMMAND:
	switch (wParam) {
	case IDOK:
	  GetDlgItemText (hDlg, IDD_MAILNAME, fileName, MAXFILENAME - 1);
	  mode = (OpenFile (fileName, &ofs, OF_EXIST) == HFILE_ERROR) ? OF_CREATE : OF_WRITE;
	  if ((hFile = OpenFile (fileName, &ofs, mode)) == HFILE_ERROR) {
		_snprintf (str, MAXINTERNALLINE, "Could not write to file %s.\nMail log disabled.", fileName);
		MessageBox (hDlg, str, "Invalid File", MB_OK | MB_ICONSTOP);
		CheckDlgButton (hDlg, IDD_MAILLOG, FALSE);
		break;
	  }
	  _lclose (hFile);
	  strcpy (MailLogFile, fileName);

	  GetDlgItemText (hDlg, IDD_POSTNAME, fileName, MAXFILENAME - 1);
	  mode = (OpenFile (fileName, &ofs, OF_EXIST) == HFILE_ERROR) ? OF_CREATE : OF_WRITE;
	  if ((hFile = OpenFile (fileName, &ofs, mode)) == HFILE_ERROR) {
		_snprintf (str, MAXINTERNALLINE, "Invalid filename %s.\nPost log disabled.", fileName);
		MessageBox (hDlg, str, "Invalid File", MB_OK | MB_ICONSTOP);
		CheckDlgButton (hDlg, IDD_POSTLOG, FALSE);
		break;
	  }
	  _lclose (hFile);
	  strcpy (PostLogFile, fileName);

	  MailLog = (IsDlgButtonChecked (hDlg, IDD_MAILLOG) != 0);
	  PostLog = (IsDlgButtonChecked (hDlg, IDD_POSTLOG) != 0);
	  EndDialog (hDlg, TRUE);
	  break;

	case IDCANCEL:
	  EndDialog (hDlg, FALSE);
	  break;

	case ID_BROWSEPOST:
	  fileName[0] = '\0';
	  if (AskForNewFileName (hDlg, fileName, "", TRUE) == SUCCESS)
		SetDlgItemText (hDlg, IDD_POSTNAME, fileName);
	  break;

	case ID_BROWSEMAIL:
	  fileName[0] = '\0';
	  if (AskForNewFileName (hDlg, fileName, "", TRUE) == SUCCESS)
		SetDlgItemText (hDlg, IDD_MAILNAME, fileName);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*-- function WinVnMailDialog ---------------------------------------
 *
 *  Dialog function to query for mail destination, and manage list
 *  of mail addresses
 *
 *  Returns mail address(es) in DialogString
 *  (JSC 2/1/94)
 */

BOOL FAR PASCAL
WinVnMailDlg (HWND hDlg, unsigned int iMessage, WPARAM wParam, LPARAM lParam)
{
  static HWND hMailList;		/* Handle to child list box window. */
  register int j;
  int count, len, startLen, found;
  char *ptr;
  char mybuf[MAXDIALOGSTRING];

  switch (iMessage) {
  case WM_INITDIALOG:
	ptr = (char *) lParam;
	if (ptr && *ptr) {
	  SetDlgItemText (hDlg, IDD_MAIL_DEST, ptr);
	}

	hMailList = GetDlgItem (hDlg, IDD_MAIL_LIST);

	SendMessage (hMailList, WM_SETREDRAW, FALSE, 0L);
	for (j = 0; j < (int) MailList->numLines; j++)
	  SendMessage (hMailList, LB_ADDSTRING, 0, (LPARAM) (LPSTR) TextBlockLine (MailList, j));

	SendMessage (hMailList, WM_SETREDRAW, TRUE, 0L);
	EnableWindow (GetDlgItem (hDlg, IDD_DELETE), FALSE);
	EnableWindow (GetDlgItem (hDlg, IDD_ADD), FALSE);
	return TRUE;
	break;

  case WM_COMMAND:
	switch (LOWORD (wParam)) {
	case IDD_MAIL_LIST:
	  switch (GET_WM_COMMAND_CMD (wParam, lParam)) {
	  case LBN_SELCHANGE:
		EnableWindow (GetDlgItem (hDlg, IDD_DELETE), TRUE);
		break;

	  case LBN_DBLCLK:
		// a double click means they want to add a name to the to-line
		// only add it if it's not already on the to-line

		j = (int) SendMessage (hMailList, LB_GETCARETINDEX, 0, 0L);
		SendMessage (hMailList, LB_GETTEXT, j, (LPARAM) (LPSTR) mybuf);

		GetDlgItemText (hDlg, IDD_MAIL_DEST, DialogString, MAXDIALOGSTRING - 1);
		strcpy (str, DialogString);
		// test if name already on "To:" line
		// can't to a test with strstr() because mybuf may be a substring
		// of another address (i.e. 'jcoop' is a substr of 'jcooper@apl.com')
		for (found = FALSE, ptr = str; *ptr; ptr += len + 1) {
		  // if there's only one token left, then len will = startLen, 
		  // and we'll iterate once only
		  startLen = strlen (ptr);
		  if ((len = strcspn (ptr, " ,\n\t\r")) != startLen) {
			ptr[len] = '\0';	// replace delim with NULL char

			while (strchr (" ,\n\t\r", ptr[len + 1]))	// eat white space

			  ptr[len++] = '\0';
		  }
		  if (!strcmp (ptr, mybuf)) {
			found = TRUE;
			break;
		  }
		  if (len == startLen)	// last token, we're done

			break;
		}
		if (!found) {
		  if (strlen (mybuf) + strlen (DialogString) + 2 > MAXDIALOGSTRING - 1) {
			MessageBox (hDlg, "Cannot add another address", "Address line is too long", MB_OK);
			return FALSE;
		  }
		  if (DialogString[0])	// if this isn't the first one, prepend a comma

			strcat (DialogString, ", ");
		  strcat (DialogString, mybuf);
		  SetDlgItemText (hDlg, IDD_MAIL_DEST, DialogString);
		}
	  }
	  break;

	case IDD_MAIL_DEST:
	  GetDlgItemText (hDlg, IDD_MAIL_DEST, mybuf, MAXDIALOGSTRING - 1);
	  EnableWindow (GetDlgItem (hDlg, IDD_ADD), mybuf[0]);
	  return FALSE;				/* let default handler act on these events */
	  break;

	case IDD_ADD:
	  // check addresses listed on to-line, add each one to list box 
	  // (if not already in the list)
	  GetDlgItemText (hDlg, IDD_MAIL_DEST, DialogString, MAXDIALOGSTRING - 1);
	  for (ptr = DialogString; *ptr; ptr += len + 1) {
		// if there's only one token left, then len will = startLen, 
		// and we'll iterate once only
		startLen = strlen (ptr);
		if ((len = strcspn (ptr, " ,\n\t\r")) != startLen) {
		  ptr[len] = '\0';		// replace delim with NULL char

		  while (strchr (" ,\n\t\r", ptr[len + 1]))		// eat white space

			ptr[len++] = '\0';
		}
		if (*ptr != '\0')		// if not a blank
		 {
		  // check if it's already in the list
		  count = (int) SendMessage (hMailList, LB_GETCOUNT, 0, 0L);
		  for (j = 0; j < count; j++) {
			SendMessage (hMailList, LB_GETTEXT, j, (LPARAM) (LPSTR) mybuf);
			if (!stricmp (ptr, mybuf))
			  break;
		  }
		  if (j == count)		// if not already in list, add it

			SendMessage (hMailList, LB_ADDSTRING, 0, (LPARAM) (LPSTR) ptr);
		}
		if (len == startLen)	// last token, we're done

		  break;
	  }
	  break;

	case IDD_DELETE:
	  // remove all selected addresses from list box
	  count = (int) SendMessage (hMailList, LB_GETCOUNT, 0, 0L);

	  SendMessage (hMailList, WM_SETREDRAW, FALSE, 0L);

	  // working backwards, delete selected items
	  for (j = count - 1; j >= 0; j--)
		if (SendMessage (hMailList, LB_GETSEL, j, 0L))
		  SendMessage (hMailList, LB_DELETESTRING, j, 0L);

	  SendMessage (hMailList, WM_SETREDRAW, TRUE, 0L);
	  EnableWindow (GetDlgItem (hDlg, IDD_DELETE), FALSE);
	  break;

	case IDOK:
	  GetDlgItemText (hDlg, IDD_MAIL_DEST, mybuf, MAXDIALOGSTRING - 1);

	  // make sure the address (if more than one) is comma separated
	  DialogString[0] = '\0';
	  for (ptr = mybuf; *ptr; ptr += len + 1) {
		// if there's only one token left, then len will = startLen, 
		// and we'll iterate once only
		startLen = strlen (ptr);
		if ((len = strcspn (ptr, " ,\n\t\r")) != startLen) {
		  ptr[len] = '\0';		// replace delim with NULL char

		  while (strchr (" ,\n\t\r", ptr[len + 1]))		// eat white space

			ptr[len++] = '\0';
		}

		strcat (DialogString, ptr);

		if (len == startLen)	// last token, we're done

		  break;
		else
		  strcat (DialogString, ", ");
	  }

	  // commit changes in listbox to internal MailList
	  ResetTextBlock (MailList);
	  count = (int) SendMessage (hMailList, LB_GETCOUNT, 0, 0L);
	  for (j = 0; j < count; j++) {
		SendMessage (hMailList, LB_GETTEXT, j, (LPARAM) (LPSTR) mybuf);
		AddLineToTextBlock (MailList, mybuf);
	  }

	  EndDialog (hDlg, TRUE);
	  break;


	case IDCANCEL:
	  // changes to MailList are _not_ committed on Cancel
	  EndDialog (hDlg, FALSE);
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}


/*-- function WinVnSmartFilerDialog ---------------------------------------
 *
 *  Manages smart filer config
 *  jsc 9/10/94 -- and 7500 mile tuneup 9/30/94
 */

BOOL FAR PASCAL
WinVnSmartFilerDlg (HWND hDlg, unsigned int iMessage, WPARAM wParam, LPARAM lParam)
{
  static HWND hMapList;			/* extension mapping combobox */
  static HWND hDupeList, hShortenList;	/* options dropllists */
  static int MyEnableExtensionConversion;
  register int j;
  int count, n, e, tabStop[10];
  char mybuf[MAXDIALOGSTRING];
  RECT rect;
  BOOL ok;

  switch (iMessage) {
  case WM_INITDIALOG:
	hMapList = GetDlgItem (hDlg, IDD_EXT_MAP_LIST);
	hDupeList = GetDlgItem (hDlg, IDD_AVOID_DUPES);
	hShortenList = GetDlgItem (hDlg, IDD_NAME_SHORTEN);

	/* set tab stop at half width (width/2) of listbox.
	 * we need # of dlg units to get half width.
	 * a dlg unit is (baseUnit/4).  so half posn in dlg units is...
	 *      (width/2) / (baseUnit/4) ==> (2*cx)/baseUnit
	 *
	 * then, set a few more evenly spaced after that in case 
	 * of really long source extension in list
	 */
	GetWindowRect (hMapList, &rect);
	tabStop[0] = (2 * (RectWidth (rect)) / LOWORD (GetDialogBaseUnits ()));
	for (j = 1; j < 10; j++) {
	  tabStop[j] = tabStop[j - 1] + 2 * LOWORD (GetDialogBaseUnits ());
	}
	SendMessage (hMapList, LB_SETTABSTOPS, 10, (LPARAM) tabStop);

	SetDlgItemInt (hDlg, IDD_MAX_NAME_LEN, MaxFileNameLen, TRUE);
	SetDlgItemInt (hDlg, IDD_MAX_EXT_LEN, MaxFileExtLen, TRUE);

	CheckDlgButton (hDlg, IDD_ENABLE_CONVERSION, EnableExtensionConversion);
	EnableWindow (hMapList, EnableExtensionConversion);
	EnableWindow (GetDlgItem (hDlg, IDD_SOURCE_EXT), EnableExtensionConversion);
	EnableWindow (GetDlgItem (hDlg, IDD_DOS_EXT), EnableExtensionConversion);

	EnableWindow (GetDlgItem (hDlg, IDD_ADD), FALSE);
	EnableWindow (GetDlgItem (hDlg, IDD_DELETE), FALSE);

	SendMessage (hMapList, WM_SETREDRAW, FALSE, 0L);
	SendMessage (hDupeList, WM_SETREDRAW, FALSE, 0L);
	SendMessage (hShortenList, WM_SETREDRAW, FALSE, 0L);
	for (j = 0; j < (int) ExtMapSourceList->numLines; j++) {
	  _snprintf (mybuf, MAXDIALOGSTRING, "%s\t%s",
	  TextBlockLine (ExtMapSourceList, j), TextBlockLine (ExtMapDosList, j));
	  SendMessage (hMapList, LB_ADDSTRING, 0, (LPARAM) (LPCSTR) mybuf);
	}
	SendMessage (hDupeList, CB_INSERTSTRING, (WPARAM) DUPE_AVOID_NONE, (LPARAM) (LPCSTR) "Prompt for new file name");
	SendMessage (hDupeList, CB_INSERTSTRING, (WPARAM) DUPE_AVOID_NUMBER_EXT, (LPARAM) (LPCSTR) "Replace extension with number");
	SendMessage (hDupeList, CB_INSERTSTRING, (WPARAM) DUPE_AVOID_PREPEND_NUM, (LPARAM) (LPCSTR) "Preserve extension, prepend number to name");
	SendMessage (hDupeList, CB_INSERTSTRING, (WPARAM) DUPE_AVOID_APPEND_NUM, (LPARAM) (LPCSTR) "Preserve extension, append number to name");

	SendMessage (hShortenList, CB_INSERTSTRING, (WPARAM) SHORTEN_NONE, (LPARAM) (LPCSTR) "Prompt for new file name");
	SendMessage (hShortenList, CB_INSERTSTRING, (WPARAM) SHORTEN_TRUNCATE, (LPARAM) (LPCSTR) "Truncate at max name length");
	SendMessage (hShortenList, CB_INSERTSTRING, (WPARAM) SHORTEN_SKIP_VOWELS, (LPARAM) (LPCSTR) "Condense (skip vowels, punctuation)");

	MyEnableExtensionConversion = EnableExtensionConversion;

	SendMessage (hDupeList, CB_SETCURSEL, (WPARAM) OnDupeName, 0L);
	SendMessage (hShortenList, CB_SETCURSEL, (WPARAM) OnNameTooLong, 0L);

	SendMessage (hMapList, WM_SETREDRAW, TRUE, 0L);
	SendMessage (hDupeList, WM_SETREDRAW, TRUE, 0L);
	SendMessage (hShortenList, WM_SETREDRAW, TRUE, 0L);

	return TRUE;
	break;

  case WM_COMMAND:
	switch (LOWORD (wParam)) {
	case IDD_EXT_MAP_LIST:
	  switch (GET_WM_COMMAND_CMD (wParam, lParam)) {
	  case LBN_SELCHANGE:
		EnableWindow (GetDlgItem (hDlg, IDD_DELETE), TRUE);
		return FALSE;			/* let the default handler do it */
		break;
	  }
	  break;

	case IDD_SOURCE_EXT:
	case IDD_DOS_EXT:
	  GetDlgItemText (hDlg, IDD_SOURCE_EXT, mybuf, MAXDIALOGSTRING - 1);
	  GetDlgItemText (hDlg, IDD_DOS_EXT, str, MAXDIALOGSTRING - 1);
	  EnableWindow (GetDlgItem (hDlg, IDD_ADD), (str[0] && mybuf[0]));
	  return FALSE;				/* let default handler act on these events */
	  break;

	case IDD_ADD:
	  GetDlgItemText (hDlg, IDD_SOURCE_EXT, DialogString, MAXDIALOGSTRING - 1);
	  GetDlgItemText (hDlg, IDD_DOS_EXT, str, MAXDIALOGSTRING - 1);
	  _snprintf (mybuf, MAXDIALOGSTRING, "%s\t%s", DialogString, str);

	  /* check if it's already in the list */
	  count = (int) SendMessage (hMapList, LB_GETCOUNT, 0, 0L);
	  for (j = 0; j < count; j++) {
		SendMessage (hMapList, LB_GETTEXT, (WPARAM) j, (LPARAM) (LPSTR) str);
		/* is the source ext already in the list somewhere? */
		if (!strnicmp (mybuf, str, strlen (DialogString) + 1))
		  break;
	  }
	  if (j == count) {			/* if not already in list, add it */
		SendMessage (hMapList, LB_ADDSTRING, 0, (LPARAM) (LPSTR) mybuf);
	  }
	  else {					/* if already in list, modify the dos ex */
		SendMessage (hMapList, LB_DELETESTRING, (WPARAM) j, 0L);
		SendMessage (hMapList, LB_INSERTSTRING, (WPARAM) j, (LPARAM) (LPSTR) mybuf);
	  }
	  break;

	case IDD_DELETE:
	  j = (int) SendMessage (hMapList, LB_GETCURSEL, 0, 0L);
	  SendMessage (hMapList, LB_DELETESTRING, (WPARAM) j, 0L);
	  EnableWindow (GetDlgItem (hDlg, IDD_DELETE), FALSE);
	  break;

	case IDOK:
	  n = GetDlgItemInt (hDlg, IDD_MAX_NAME_LEN, &ok, TRUE);
	  e = GetDlgItemInt (hDlg, IDD_MAX_EXT_LEN, &ok, TRUE);
#ifdef WIN32
	  if (n + e <= 0 || n + e > 255) {
		MessageBox (hDlg, "Names (name + extension) must be between 1 and 255 characters in length", "File Name Length Error", MB_OK);
		break;
	  }
	  if (e == 0 && MyEnableExtensionConversion) {
		if (MessageBox (hDlg, "With max extension length of 0, extension conversion must be disabled.  Continue?", "Warning", MB_YESNO) == IDNO)
		  break;
		else
		  MyEnableExtensionConversion = FALSE;
	  }

#else
	  if (n <= 0 || n > 8) {
		MessageBox (hDlg, "DOS names must be between 0 and 8 characters in length", "File Name Length Error", MB_OK);
		break;
	  }
	  if (e <= 0 || e > 3) {
		MessageBox (hDlg, "DOS extensions must be between 0 and 3 characters in length", "File Extension Length Error", MB_OK);
		break;
	  }
#endif /* WIN32 */
	  MaxFileNameLen = n;
	  MaxFileExtLen = e;
	  OnDupeName = (int) SendMessage (hDupeList, CB_GETCURSEL, 0, 0L);
	  OnNameTooLong = (int) SendMessage (hShortenList, CB_GETCURSEL, 0, 0L);
	  EnableExtensionConversion = MyEnableExtensionConversion;

	  /* commit changes in listbox to internal lists */
	  ResetTextBlock (ExtMapSourceList);
	  ResetTextBlock (ExtMapDosList);
	  count = (int) SendMessage (hMapList, LB_GETCOUNT, 0, 0L);
	  for (j = 0; j < count; j++) {
		SendMessage (hMapList, LB_GETTEXT, j, (LPARAM) (LPSTR) mybuf);
		sscanf (mybuf, "%s\t%s", DialogString, str);
		AddLineToTextBlock (ExtMapSourceList, DialogString);
		AddLineToTextBlock (ExtMapDosList, str);
	  }

	  EndDialog (hDlg, TRUE);
	  break;


	case IDCANCEL:
	  /* changes to lists are _not_ committed on Cancel */
	  EndDialog (hDlg, FALSE);
	  break;

	case IDD_ENABLE_CONVERSION:
	  MyEnableExtensionConversion = !MyEnableExtensionConversion;
	  CheckDlgButton (hDlg, IDD_ENABLE_CONVERSION, MyEnableExtensionConversion);
	  SendMessage (hMapList, LB_SETCURSEL, (WPARAM) - 1, 0L);	/* deselect */
	  EnableWindow (hMapList, MyEnableExtensionConversion);
	  EnableWindow (GetDlgItem (hDlg, IDD_SOURCE_EXT), MyEnableExtensionConversion);
	  EnableWindow (GetDlgItem (hDlg, IDD_DOS_EXT), MyEnableExtensionConversion);
	  if (!MyEnableExtensionConversion) {
		EnableWindow (GetDlgItem (hDlg, IDD_ADD), FALSE);
		EnableWindow (GetDlgItem (hDlg, IDD_DELETE), FALSE);
	  }
	  break;

	default:
	  return FALSE;
	}
	break;

  default:
	return FALSE;
	break;
  }
  return TRUE;
}

/*
 * Local Variables:
 * tab-width: 2
 * end:
 */
