/*
 * Windows Kermit
 * 
 * Written by William S. Hall
 *	      3665 Benton Street, #66
 *	      Santa Clara, CA 95051
 *
 * protocol dialog box support
 */

#define NOKANJI
#define NOATOM
#define NOMINMAX
#include <windows.h>
#include <string.h>
#include <stdlib.h>

#include "winasc.h"
#include "winkpr.h"
#include "winkpf.h"

#define MAXPATHLEN	128

static char *defstring = "*.*";

/* local functions */
static void NEAR PathSelect(HWND hDlg, LONG lParam);
static void NEAR ListBoxInit(HWND hDlg);
static int NEAR CheckSelect(HWND hDlg);
static void NEAR ListBoxOK(HWND hDlg, LONG lParam);
static char* NEAR getnamestr(char *str, int len);
static void NEAR GetSendFileList(HWND hDlg, LONG lParam);
static void NEAR SaveMiscParams(HWND hDlg);
static void NEAR krmRemoteCommandInit(HWND hDlg, WORD idd_string1, 
		WORD idd_string2, WORD idd_limit1, WORD idd_limit2, BOOL enable);
static void NEAR krmActivateOK(HWND hDlg, WORD id, LONG lParam);
static BOOL NEAR krmOneParamRemoteCmd(HWND hDlg, WORD id, char cmd);

/* send file dialog box */
BOOL FAR PASCAL SendFileDlgProc(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{

    switch (message) {
	case WM_INITDIALOG:
	    ListBoxInit(hDlg);
	    break;

	case WM_COMMAND:
	    switch (wParam) {

		case IDOK:
		    ListBoxOK(hDlg, lParam);
		    break;
		
		case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;

		case IDD_SEND:
		    GetSendFileList(hDlg, lParam);
		    break;

		case IDD_PATHSELECT:
		    PathSelect(hDlg, lParam);
		    break;

		default:
		    return FALSE;
	    }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* support modules for send file dlg */
static char* NEAR getnamestr(char *str, int len)
{
    char *tmp;

    tmp = str + len;

    while ((*tmp != ':') && (*tmp != '\\') && (tmp > str))
	tmp--;
    if (*tmp != ':' && *tmp != '\\')
	return(tmp);
    else
	return(tmp + 1);

}

static void NEAR PathSelect(HWND hDlg, LONG lParam)
{

    char buf[MAXPATHLEN];
    char str[MAXPATHLEN];
    int len;

    if (HIWORD(lParam) == LBN_SELCHANGE) {
	len = GetDlgItemText(hDlg, IDD_EDITSELECT,(LPSTR)str,80);
        DlgDirSelect(hDlg, (LPSTR)buf, IDD_PATHSELECT);
	if (strchr(str,'*') || strchr(str,'?'))
	    strcat(buf,getnamestr(str,len));
	else
	    strcat(buf, defstring);
        SetDlgItemText(hDlg, IDD_EDITSELECT, (LPSTR)buf);
    }
    else if (HIWORD(lParam) == LBN_DBLCLK) {
	GetDlgItemText(hDlg, IDD_EDITSELECT,(LPSTR)buf,80);
	DlgDirList(hDlg, (LPSTR)buf, IDD_LISTSELECT,IDD_PATHDISPLAY, 0);
	DlgDirList(hDlg, (LPSTR)buf, IDD_PATHSELECT,IDD_PATHDISPLAY, 0xC010);
	SetDlgItemText(hDlg, IDD_EDITSELECT, (LPSTR)buf);
    }
}

static void NEAR ListBoxInit(HWND hDlg)
{

    char buf[10];
    strcpy(buf, defstring);

    DlgDirList(hDlg, (LPSTR)buf, IDD_LISTSELECT,IDD_PATHDISPLAY, 0);
    DlgDirList(hDlg, (LPSTR)buf, IDD_PATHSELECT,IDD_PATHDISPLAY, 0xC010);
    SetDlgItemText(hDlg, IDD_EDITSELECT, (LPSTR)buf);
    SendDlgItemMessage(hDlg, IDD_EDITSELECT,EM_LIMITTEXT,128,0L);
}

static int NEAR CheckSelect(HWND hDlg)
{

    int num, i;
    int count = 0;

    num = (int)SendDlgItemMessage(hDlg, IDD_LISTSELECT,LB_GETCOUNT,0,0L);

    for (i = 0; i < num; i++)
        if (SendDlgItemMessage(hDlg,IDD_LISTSELECT,LB_GETSEL,(WORD)i,0L))
	    count += 1;

    return count;
}

static void NEAR GetSendFileList(HWND hDlg, LONG lParam)
{

    char buf[MAXPATHLEN];
    int count, i, num;

    count = CheckSelect(hDlg);
    if (count > 0) {
        Kermit.hfilelist = LocalAlloc(LPTR, count * 13);
	if (Kermit.hfilelist != NULL) {
	    Kermit.pfilelist = LocalLock(Kermit.hfilelist);
	    num = (int)SendDlgItemMessage(hDlg, IDD_LISTSELECT,
						LB_GETCOUNT,0,0L);
	    for (i = 0; i < num; i++) {
	        if (SendDlgItemMessage(hDlg,IDD_LISTSELECT,LB_GETSEL,(WORD)i,0L)) {
	       	    SendDlgItemMessage(hDlg, IDD_LISTSELECT,LB_GETTEXT, 
						(WORD)i, (LONG)(LPSTR)buf);
		    strcat(Kermit.pfilelist, buf);
		    strcat(Kermit.pfilelist, " ");
	        }
            }
        }
        else
	    count = 0;
    }
    if (count == 0) {
	/* no files selected or local alloc error */
    }
    EndDialog(hDlg,count);
}

static void NEAR ListBoxOK(HWND hDlg, LONG lParam)
{

    char buf[MAXPATHLEN];
    int validsspec, count;
    OFSTRUCT myoff;
    HANDLE hFile;
    char oldpath[MAXPATHLEN];
    char *ptr;

/* if nothing in the edit box */
    if (GetDlgItemText(hDlg, IDD_EDITSELECT,(LPSTR)buf,sizeof(buf)) == 0)
/* remove highlighting from file list box */
        SendDlgItemMessage(hDlg,IDD_LISTSELECT,LB_SETSEL,FALSE,(LONG)(-1));
    else {
/* otherwise, save the path */
    	GetDlgItemText(hDlg, IDD_PATHDISPLAY,(LPSTR)oldpath,128);
/* see if valid search spec */
	SendDlgItemMessage(hDlg, IDD_LISTSELECT, WM_SETREDRAW, FALSE, 0L);
	SendDlgItemMessage(hDlg, IDD_PATHSELECT, WM_SETREDRAW, FALSE, 0L);
	validsspec = DlgDirList(hDlg,(LPSTR)buf,IDD_LISTSELECT,IDD_PATHDISPLAY,0);
	SendDlgItemMessage(hDlg, IDD_LISTSELECT, WM_SETREDRAW, TRUE, 0L);
	SendDlgItemMessage(hDlg, IDD_PATHSELECT, WM_SETREDRAW, TRUE, 0L);
/* if valid, get the new path */
	if (validsspec) {
/* buf modified, so update it */
	    SetDlgItemText(hDlg, IDD_EDITSELECT, (LPSTR)buf);
	    GetDlgItemText(hDlg, IDD_PATHDISPLAY, (LPSTR)buf,128);
/* if the same as before */
	    if (strcmp(oldpath, buf) == 0)
/* select the whole list box */
                SendDlgItemMessage(hDlg,IDD_LISTSELECT,
				   LB_SETSEL,TRUE,(LONG)(-1));
	    else {
/* update the directory change box */
                SendDlgItemMessage(hDlg,IDD_LISTSELECT,
				   LB_SETSEL,FALSE,(LONG)(-1));
	        DlgDirList(hDlg,(LPSTR)buf,IDD_PATHSELECT,
			   IDD_PATHDISPLAY, 0xC010);
	    }
/* not a valid search spec */
	} else {
/* clear box */
            SendDlgItemMessage(hDlg, IDD_LISTSELECT, LB_RESETCONTENT,0,0L);
/* see if it exists */
	    hFile = OpenFile((LPSTR)buf, (OFSTRUCT FAR *)&myoff, OF_EXIST);
	    if (hFile != -1) {
/* get the file name and add it to list box */
	        ptr = strrchr(myoff.szPathName,'\\') + 1;
	        SendDlgItemMessage(hDlg, IDD_LISTSELECT,LB_ADDSTRING,0,
							(LONG)(LPSTR)ptr);
/* get the pathname */
	        strcpy(buf, myoff.szPathName);
	        count = strlen(buf) - strlen(ptr);
	        buf[count] = NUL;
/* select it */
                SendDlgItemMessage(hDlg,IDD_LISTSELECT,LB_SETSEL,TRUE,-1L);
/* update the path select box */
	        SetDlgItemText(hDlg, IDD_EDITSELECT, (LPSTR)ptr);
	        DlgDirList(hDlg, (LPSTR)buf, IDD_PATHSELECT,IDD_PATHDISPLAY, 0xC010);
	    }
        }
    }
    SendDlgItemMessage(hDlg, IDD_EDITSELECT, EM_SETSEL, 0, MAKELONG(0,32767));
}

/* set protocol parameters */
BOOL FAR PASCAL SetMiscParams(HWND hDlg,
			      unsigned message,WORD wParam,LONG lParam)
{

    int i, *ptr;

    switch (message) {
	case WM_INITDIALOG:
	    ptr = &Kermit.timer;
	    for (i = IDD_TIMER; i <= IDD_KRM_BELL; i++)
	        CheckDlgButton(hDlg,i, *ptr++);
	    CheckDlgButton(hDlg, IDD_KRM_SAVE,FALSE);
	    break;

	case WM_COMMAND:
	    switch(wParam) {
	        case IDOK:
		    ptr = &Kermit.timer;
		    for (i = IDD_TIMER; i <= IDD_KRM_BELL; i++)
			*ptr++ = IsDlgButtonChecked(hDlg,i);
		    if (IsDlgButtonChecked(hDlg,IDD_KRM_SAVE))
			SaveMiscParams(hDlg);
		    EndDialog(hDlg, TRUE);
		    break;
	        case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;
		case IDD_TIMER:
		case IDD_FILEWARN:
		case IDD_FILEDISCARD:
		case IDD_KRM_BELL:
		case IDD_KRM_SAVE:
		    if (IsDlgButtonChecked(hDlg, wParam))
		        CheckDlgButton(hDlg,wParam,FALSE);
		    else
		        CheckDlgButton(hDlg,wParam,TRUE);
		    break;
	        default:
		    return FALSE;
            }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* support for set misc dlg */
static void NEAR SaveMiscParams(HWND hDlg)
{

    int i, *ptr;
    char szAppStr[30];
    char szKeyStr[30];
    char szValStr[20];
    HANDLE hInstance;

    hInstance = (HANDLE)GetWindowWord(hDlg, GWW_HINSTANCE);
 
    LoadString(hInstance,IDS_KRM_KERMIT, (LPSTR)szAppStr, sizeof(szAppStr));
    ptr = &Kermit.timer;

    for (i = 0; i < 4; i++) {
	LoadString(hInstance,IDS_KRM_TIMER+i,(LPSTR)szKeyStr, sizeof(szKeyStr));
        itoa(*ptr++, szValStr, sizeof(szValStr));
	WriteProfileString((LPSTR)szAppStr,(LPSTR)szKeyStr,(LPSTR)szValStr);
    }
    BroadcastWinIniChange();
}

/* generic one-edit box dialog box */
BOOL FAR PASCAL GetFileList(HWND hDlg,unsigned message,WORD wParam,LONG lParam)
{

    int count;

    switch (message) {
	case WM_INITDIALOG:
	    krmRemoteCommandInit(hDlg,Kermit.ids_title,0,IDD_GETNAME,0,
							Kermit.nullstrOK);
	    break;

	case WM_COMMAND:
	    switch(wParam) {
	        case IDOK:
		    count = (int)SendDlgItemMessage(hDlg,IDD_GETNAME,
					WM_GETTEXTLENGTH,0,0L);
		    Kermit.hfilelist = LocalAlloc(LPTR, count+1);
		    if (Kermit.hfilelist != NULL) {
		        Kermit.pfilelist = LocalLock(Kermit.hfilelist);
		        count = GetDlgItemText(hDlg,IDD_GETNAME,
					(LPSTR)Kermit.pfilelist,count + 1);
			if (Kermit.remotecmd == 'R')
		            AnsiUpper((LPSTR)Kermit.pfilelist);
		    }
		    else
		        count = 0;
		    EndDialog(hDlg, count);
		    break;

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

		case IDD_GETNAME:
		    if (!Kermit.nullstrOK)
		        krmActivateOK(hDlg, wParam, lParam);
		    break;

	        default:
		    return FALSE;
            }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* chdir, or two-edit box dialog box */
BOOL FAR PASCAL krmRemoteChdir(HWND hDlg,
			       unsigned message,WORD wParam,LONG lParam)
{

    int count, count1;
    static HBRUSH hbr = 0;

    switch (message) {

	case WM_CTLCOLOR:
            if (LOWORD(lParam) == GetDlgItem(hDlg,IDD_GETTEXT2)) {
		SetBkColor(wParam, GetSysColor(COLOR_WINDOWTEXT));
		SetTextColor(wParam, GetSysColor(COLOR_WINDOWTEXT));
		if (hbr)
	            return (int)hbr;
		else
		    return((int)GetStockObject(WHITE_BRUSH));
	    }
	    return FALSE;

	case WM_INITDIALOG:
	    krmRemoteCommandInit(hDlg,IDS_KRM_CWD,IDS_KRM_PASSWORD,
					IDD_GETTEXT1,IDD_GETTEXT2,TRUE); 
	    hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
	    break;

	case WM_COMMAND:
	    switch(wParam) {
	        case IDOK:
		    count = (int)SendDlgItemMessage(hDlg,IDD_GETTEXT1,
					WM_GETTEXTLENGTH,0,0L);
		    count1 = (int)SendDlgItemMessage(hDlg,IDD_GETTEXT2,
					WM_GETTEXTLENGTH,0,0L);
		    Kermit.hRemoteCommand = LocalAlloc(LPTR,count + count1 + 4);
		    if (Kermit.hRemoteCommand != NULL) {
		        Kermit.pRemoteCommand = LocalLock(Kermit.hRemoteCommand);
		   	*Kermit.pRemoteCommand = 'C';
			*(Kermit.pRemoteCommand+1) = (BYTE)tochar(count);
		 	if (count) {
		            GetDlgItemText(hDlg,IDD_GETTEXT1,
				    (LPSTR)(Kermit.pRemoteCommand+2), count+1);
			    if (count1) {			    
				*(Kermit.pRemoteCommand + count + 2) = 
							(BYTE)tochar(count1);			
		        	GetDlgItemText(hDlg,IDD_GETTEXT2,
					(LPSTR)(Kermit.pRemoteCommand+count+3), 
						count1 + 1);
			    }
			}
			EndDialog(hDlg, TRUE);
		    }
		    else
		        EndDialog(hDlg, FALSE);
		    if (hbr)
  		        DeleteObject(hbr);
		    break;

	        case IDCANCEL:
		    EndDialog(hDlg, FALSE);
  		    if (hbr)
		        DeleteObject(hbr);
		    break;

	        default:
		    return FALSE;
            }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* show transfer data */
BOOL FAR PASCAL krmXferDlgBox(HWND hDlg,
			      unsigned message,WORD wParam,LONG lParam)
{

    char buf[40];
    HANDLE hInst;

    switch (message) {

	case WM_INITDIALOG:
	    if (krmState == IDM_KRM_SEND) {
		hInst = (HANDLE)GetWindowWord(hDlg, GWW_HINSTANCE);
    	        LoadString(hInst,IDS_KRM_SENDING, (LPSTR)buf, sizeof(buf));
		SetDlgItemText(hDlg, IDD_OPERATION, (LPSTR)buf);
	    }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* another 1-edit box dialog box */
BOOL FAR PASCAL krmRemoteCmdDlgBox(HWND hDlg,
				   unsigned message,WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    krmRemoteCommandInit(hDlg,Kermit.ids_title,
				 0,IDD_GETNAME,0,Kermit.nullstrOK); 
	    break;

	case WM_COMMAND:
	    switch(wParam) {
	        case IDOK:
		    EndDialog(hDlg,krmOneParamRemoteCmd(hDlg,
			      IDD_GETNAME,Kermit.remotecmd));
		    break;

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

		case IDD_GETNAME:
		    if (!Kermit.nullstrOK)
		        krmActivateOK(hDlg, wParam, lParam);
		    break;

	        default:
		    return FALSE;
            }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* support functions */
static void NEAR krmRemoteCommandInit(HWND hDlg, WORD idd_string1, 
		WORD idd_string2, WORD idd_limit1, WORD idd_limit2, BOOL enable)
{
    char buf[80];
    HANDLE hInst;

    hInst = (HANDLE)GetWindowWord(hDlg, GWW_HINSTANCE);

    if (idd_string1) {
    	LoadString(hInst,idd_string1, (LPSTR)buf, sizeof(buf));
	SetDlgItemText(hDlg, IDD_STATICTEXT1, (LPSTR)buf);
    }
    if (idd_string2) {
    	LoadString(hInst,idd_string2, (LPSTR)buf, sizeof(buf));
	SetDlgItemText(hDlg, IDD_STATICTEXT2, (LPSTR)buf);
    }

    if (idd_limit1)
        SendDlgItemMessage(hDlg,idd_limit1,EM_LIMITTEXT,KRM_MAXPACKETSIZE,0L);
    if (idd_limit2)
        SendDlgItemMessage(hDlg,idd_limit2,EM_LIMITTEXT,KRM_MAXPACKETSIZE,0L);

    EnableWindow(GetDlgItem(hDlg, IDOK), enable);
}

static void NEAR krmActivateOK(HWND hDlg, WORD id, LONG lParam)
{

    int count;

    if (HIWORD(lParam) == EN_CHANGE) {
        count = (int)SendDlgItemMessage(hDlg,id, WM_GETTEXTLENGTH,0,0L);
	EnableWindow(GetDlgItem(hDlg, IDOK), count);
    }
}

static BOOL NEAR krmOneParamRemoteCmd(HWND hDlg, WORD id, char cmd)
{
    int count;

    count = (int)SendDlgItemMessage(hDlg,id,WM_GETTEXTLENGTH,0,0L);
    Kermit.hRemoteCommand = LocalAlloc(LPTR,count + 3);
    if (Kermit.hRemoteCommand != NULL) {
        Kermit.pRemoteCommand = LocalLock(Kermit.hRemoteCommand);
   	*Kermit.pRemoteCommand = cmd;
	*(Kermit.pRemoteCommand+1) = (BYTE)tochar(count);
 	if (count)
            GetDlgItemText(hDlg,id,(LPSTR)(Kermit.pRemoteCommand+2), count+1);
	return TRUE;
    }
    else
	return FALSE;
}
