/*
  Windows Sockets FTP Application

  Written by: John A. Junod            Internet: <junodj@gordon-emh2.army.mil>
              267 Hillwood Street                <zj8549@trotter.usma.edu>
              Martinez, GA 30907     Compuserve: 72321,366 

  This program executable and all source code is released into the public
  domain.

  MODULE: WS_DLG.C  (controls main dialog box)
*/

#include "ws_glob.h"
#include "WS_ftp.H"
//----------------------
#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <ctype.h>

/*
  GetLocalDirForDlg
  Fills in the local portion of the transfer dialog box
*/
int GetLocalDirForDlg(HWND hDlg)
{
  char tmp[184];
  // get the local directory name
  // DLG_LDIRECTORY (directory name)
  getcwd(tmp,180);
  SetDlgItemText(hDlg,DLG_LDIRECTORY,tmp);
  // DLG_LDIRS      (directory list box)
  SendDlgItemMessage(hDlg,DLG_LDIRS,LB_RESETCONTENT,0,0);
  {
   struct ffblk ffblk;
   int done;
   done = findfirst("*.*",&ffblk,FA_DIREC);
   while (!done) 
   {
      if(ffblk.ff_attrib & 0x10 && strcmp(ffblk.ff_name,".")!=0)
        SendDlgItemMessage(hDlg,DLG_LDIRS,LB_ADDSTRING,0,(LONG)ffblk.ff_name);
      done = findnext(&ffblk);
   }
  }
  // DLG_LFILES     (file list box)
  SendDlgItemMessage(hDlg,DLG_LFILES,LB_RESETCONTENT,0,0);
  {
   struct ffblk ffblk;
   int done;
   int i;
   done = findfirst("*.*",&ffblk,0);
   while (!done) 
   {
      if(!(ffblk.ff_attrib & 0x10)) {
        strcpy(tmp,ffblk.ff_name);
        for(i=0;i<strlen(tmp);i++)
          tmp[i]=tolower(tmp[i]);
        SendDlgItemMessage(hDlg,DLG_LFILES,LB_ADDSTRING,0,(LONG)tmp);
      }
      done = findnext(&ffblk);
   }
  }
  return 0;
}

/*
  GetRemoteDirForDlg
  Fills in the remote portion of the transfer dialog box
*/
GetRemoteDirForDlg(HWND hDlg)
{
  char tmp[184];
  char *s;
  FILE *fd;
  int rc;

  // clean out the old contents of the list boxes
  SendDlgItemMessage(hDlg,DLG_RDIRS,LB_RESETCONTENT,0,0);
  SendDlgItemMessage(hDlg,DLG_RFILES,LB_RESETCONTENT,0,0);
  // can't do much if we aren't connected
  if(!bConnected) {
    SetDlgItemText(hDlg,DLG_HOSTNAME,"not connected");
    SetDlgItemText(hDlg,DLG_RDIRECTORY,"no remote directory");
    SetDlgItemText(hDlg,DLG_STATUS,"not connected to remote host");
  }
  else {
    // set the hostname
    SetDlgItemText(hDlg,DLG_HOSTNAME,pinghost);
    // get the remote directory name
    strcpy(tmp,"undecipherable");
    rc=DoPWD(ctrl_socket);
    SetDlgItemText(hDlg,DLG_STATUS,szMsgBuf);
    if(rc==FTP_COMPLETE) {
      if((s=strchr(szMsgBuf,'"'))!=NULL)
        strncpy(tmp,++s,180);
      if((s=strchr(tmp,'"'))!=NULL)
        *s=0;
      else tmp[180]=0;
    }
    // DLG_RDIRECTORY (directory name)
    SetDlgItemText(hDlg,DLG_RDIRECTORY,tmp);
    // go get the current remote directory listing in tmpfile.tmp
    rc=RetrieveFile(ctrl_socket,"NLST",szTmpFile,TYPE_A);
    SetDlgItemText(hDlg,DLG_STATUS,szMsgBuf);
    if(rc==FTP_COMPLETE)
    {
      if((fd=fopen(szTmpFile,"r"))!=NULL)
      {
        while(fgets(tmp,180,fd)!=NULL)
        {
          if((s=strchr(tmp,'\n'))!=NULL) *s=0;
          if(tmp[strlen(tmp)-1]=='/' || tmp[strlen(tmp)-1]=='\\')
          {
            tmp[strlen(tmp)-1]=0;
            // DLG_RDIRS      (directory list box)
            if(strcmp(tmp,".")!=0)
              SendDlgItemMessage(hDlg,DLG_RDIRS,LB_ADDSTRING,0,(LONG)tmp);
          } else
            // DLG_RFILES     (file list box)
            SendDlgItemMessage(hDlg,DLG_RFILES,LB_ADDSTRING,0,(LONG)tmp);
        }
        fclose(fd);
      } else
        DoAddLine("couldn't open tmpfile for read.");
    } else
      DoPrintf("DoDirList returned %u",rc);
  } // if we were connected
  return 0;
}

BOOL FAR PASCAL WS_MainMsgProc(HWND hWndDlg, WORD Message, 
                               WORD wParam, LONG lParam)
{
  int nIndex;
  int nRC;
   
 switch(Message)
 {
   case WM_INITDIALOG:
     GetLocalDirForDlg(hWndDlg);
     GetRemoteDirForDlg(hWndDlg);
     if(!bConnected)
       PostMessage(hWndDlg,WM_COMMAND,BTN_CONNECT,0L);
     break;

   case WM_CLOSE:
     PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
     break;

   case WM_SETCURSOR:
     if(bCmdInProgress)
       SetCursor(hWaitCursor);
     else
       return FALSE;
     break;

   case WM_COMMAND:
     if(wParam==IDM_CLOSE) {
          SendMessage(hWndMain,WM_COMMAND,IDM_CLOSE,0L);
          GetRemoteDirForDlg(hWndDlg);
          break;
     } else if(bCmdInProgress) return(FALSE);
     switch(wParam)
     {
       case BTN_CONNECT:
         if(!(bConnected))
         {
           FARPROC lpfnMsgProc;
           lpfnMsgProc = MakeProcInstance((FARPROC)WS_HostMsgProc, hInst);
            DialogBox(hInst, (LPSTR)"DLG_HOST", hWndDlg, lpfnMsgProc);
            FreeProcInstance(lpfnMsgProc);
            ctrl_socket=(SOCKET)DoConnect(pinghost);
            GetRemoteDirForDlg(hWndDlg);
          }
          break;

// local buttons
        case BTN_LMKDIR:
          { FARPROC lpfnMsgProc;
            lstrcpy(dlg_prompt,"Enter new local directory name:");
            dlg_edit[0]=0;
            lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
            DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndDlg,lpfnMsgProc);
            FreeProcInstance(lpfnMsgProc);
          }
          mkdir(dlg_edit);
          GetLocalDirForDlg(hWndDlg);
          break;
        case BTN_LRMDIR:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_LDIRS,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_LDIRS,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              wsprintf(szString,"Are you sure you want to delete \"%s\"?",szMsgBuf);
              if(MessageBox(hWndDlg,szString,"Verify Deletion",MB_YESNO)==IDYES)
                if(rmdir(szMsgBuf)==0)
                  GetLocalDirForDlg(hWndDlg);
            }
          break;
        case BTN_LDELETE:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              wsprintf(szString,"Are you sure you want to delete \"%s\"?",szMsgBuf);
              if(MessageBox(hWndDlg,szString,"Verify Deletion",MB_YESNO)==IDYES)
                if(unlink(szMsgBuf)==0)
                  GetLocalDirForDlg(hWndDlg);
            }
          break;
        case BTN_LRENAME:
          if((nIndex=SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
          {
            SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETTEXT,nIndex,
                               (LONG)szMsgBuf);
            { FARPROC lpfnMsgProc;
              wsprintf(dlg_prompt,"Enter new name for \"%s\":",szMsgBuf);
              dlg_edit[0]=0;
              lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
              DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndDlg,lpfnMsgProc);
              FreeProcInstance(lpfnMsgProc);
            }
            if(rename(szMsgBuf,dlg_edit)==0)
              GetLocalDirForDlg(hWndDlg);
          }
          break;
        case DLG_LDIRS:
          if(HIWORD(lParam)!=LBN_DBLCLK) return(FALSE);
        case BTN_LCHANGE:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_LDIRS,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_LDIRS,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              if(chdir(szMsgBuf)==0)
                GetLocalDirForDlg(hWndDlg);
            }
          break;
        case DLG_LFILES:
          if(HIWORD(lParam)!=LBN_DBLCLK) return(FALSE);
        case BTN_LOCAL_TO_REMOTE:
          {
            char tmp[80];
            char localname[80];
            int selects[30];
            int count;

            count=SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETSELITEMS,30,(int far *)selects);
            if(count>0 && count!=LB_ERR) {
              for(nIndex=0;nIndex<count;nIndex++) {
                SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETTEXT,selects[nIndex],
                                 (LONG)localname);
                wsprintf(tmp,"sending %s (%u of %u)",localname,nIndex+1,count);
                SetDlgItemText(hWndDlg,DLG_STATUS,tmp);
                wsprintf(tmp,"STOR %s",localname);
                nRC=SendFile((SOCKET)ctrl_socket,(LPSTR)tmp,(LPSTR)localname,TYPE_I);
                SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
                if(nRC!=2) break;
              }  
              GetRemoteDirForDlg(hWndDlg);
            }
          }
          break;
        case BTN_LDISPLAY:
          {
            char remotename[80];
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_LFILES,LB_GETTEXT,nIndex,
                                 (LONG)remotename);
              wsprintf(szMsgBuf,"notepad %s",remotename);
              WinExec(szMsgBuf,SW_SHOW);
            }
          }
          break;

// remote buttons
        case BTN_RMKDIR:
          { FARPROC lpfnMsgProc;
            lstrcpy(dlg_prompt,"Enter new remote directory name:");
            dlg_edit[0]=0;
            lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
            DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndDlg,lpfnMsgProc);
            FreeProcInstance(lpfnMsgProc);
          }
          nRC=command(ctrl_socket,"MKD %s",dlg_edit);
          SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
          if(nRC==FTP_COMPLETE)
            GetRemoteDirForDlg(hWndDlg);
          break;
        case BTN_RRMDIR:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_RDIRS,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_RDIRS,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              wsprintf(szString,"Are you sure you want to delete \"%s\"?",szMsgBuf);
              if(MessageBox(hWndDlg,szString,"Verify Deletion",MB_YESNO)==IDYES) {
                nRC=command(ctrl_socket,"RMD %s",szMsgBuf);
                SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
                if(nRC==FTP_COMPLETE)
                  GetRemoteDirForDlg(hWndDlg);
              }
            }
          break;
        case BTN_RDELETE:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              wsprintf(szString,"Are you sure you want to delete \"%s\"?",szMsgBuf);
              if(MessageBox(hWndDlg,szString,"Verify Deletion",MB_YESNO)==IDYES) {
                nRC=command(ctrl_socket,"DELE %s",szMsgBuf);
                SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
                if(nRC==FTP_COMPLETE)
                  GetRemoteDirForDlg(hWndDlg);
              }
            }
          break;
        case BTN_RRENAME:
          if((nIndex=SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
          {
            SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETTEXT,nIndex,
                               (LONG)szMsgBuf);
            { FARPROC lpfnMsgProc;
              wsprintf(dlg_prompt,"Enter new name for \"%s\":",szMsgBuf);
              dlg_edit[0]=0;
              lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
              DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndDlg,lpfnMsgProc);
              FreeProcInstance(lpfnMsgProc);
            }
            nRC=command(ctrl_socket,"RNFR %s",szMsgBuf);
            SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
            if(nRC==FTP_CONTINUE) {
              nRC=command(ctrl_socket,"RNTO %s",dlg_edit);
              SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
              if(nRC==FTP_COMPLETE)
                GetRemoteDirForDlg(hWndDlg);
            }
          }
          break;
        case DLG_RDIRS:
          if(HIWORD(lParam)!=LBN_DBLCLK) return(FALSE);
        case BTN_RCHANGE:
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_RDIRS,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_RDIRS,LB_GETTEXT,nIndex,
                                 (LONG)szMsgBuf);
              nRC=command(ctrl_socket,"CWD %s",szMsgBuf);
              SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
              if(nRC==FTP_COMPLETE)
                GetRemoteDirForDlg(hWndDlg);
            } else {
              { FARPROC lpfnMsgProc;
                lstrcpy(dlg_prompt,"Enter remote directory name:");
                dlg_edit[0]=0;
                lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
                DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndDlg,lpfnMsgProc);
                FreeProcInstance(lpfnMsgProc);
                nRC=DoCWD((SOCKET)ctrl_socket,dlg_edit);
                SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
                if(nRC==FTP_COMPLETE)
                  GetRemoteDirForDlg(hWndDlg);
              }
            }
          break;
        case DLG_RFILES:
          if(HIWORD(lParam)!=LBN_DBLCLK) return(FALSE);
        case BTN_REMOTE_TO_LOCAL:
          {
            char tmp[80];
            char remotename[80];
            int selects[30];
            int count;

            count=SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETSELITEMS,
                                 30,(int far *)selects);
            if(count>0 && count!=LB_ERR) {
              for(nIndex=0;nIndex<count;nIndex++) {
                SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETTEXT,selects[nIndex],
                                 (LONG)remotename);
                wsprintf(tmp,"receiving %s (%u of %u)",remotename,nIndex+1,count);
                SetDlgItemText(hWndDlg,DLG_STATUS,tmp);
                wsprintf(tmp,"RETR %s",remotename);
                nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,(LPSTR)remotename,TYPE_I);
                SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
                if(nRC!=2) break;
              }  
              GetLocalDirForDlg(hWndDlg);
            }
          }
          break;
        case BTN_RDISPLAY:
          {
            char tmp[80];
            char remotename[80];
            if((nIndex=SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETCURSEL,
                0,0L))!=LB_ERR)
            {
              SendDlgItemMessage(hWndDlg,DLG_RFILES,LB_GETTEXT,nIndex,
                                 (LONG)remotename);
              wsprintf(tmp,"RETR %s",remotename);
              nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,
                           (LPSTR)szTmpFile,TYPE_A);
              SetDlgItemText(hWndDlg,DLG_STATUS,szMsgBuf);
              if(nRC==2) {
                wsprintf(szMsgBuf,"notepad %s",szTmpFile);
                WinExec(szMsgBuf,SW_SHOW);
              }
              GetLocalDirForDlg(hWndDlg);
            }
          }
          break;

// misc buttons
        case BTN_STAT:
          { FARPROC lpfnMsgProc;
            lpfnMsgProc = MakeProcInstance((FARPROC)WS_StatMsgProc, hInst);
            DialogBox(hInst, (LPSTR)"DLG_STATUS", hWndDlg, lpfnMsgProc);
            FreeProcInstance(lpfnMsgProc);
          }
          break;
        case IDM_CLOSE:
          SendMessage(hWndMain,WM_COMMAND,IDM_CLOSE,0L);
          GetRemoteDirForDlg(hWndDlg);
          break;
        case IDM_ABOUT:
          { FARPROC lpfnMsgProc;
            lpfnMsgProc = MakeProcInstance((FARPROC)WS_AboutMsgProc, hInst); 
            DialogBox(hInst, (LPSTR)"DLG_ABOUT", hWndDlg, lpfnMsgProc);
            FreeProcInstance(lpfnMsgProc);
          }
          break;

        case IDOK:
        case IDCANCEL:
          SendMessage(hWndMain,WM_COMMAND,IDM_CLOSE,0l);
          EndDialog(hWndDlg, wParam==IDOK);
          PostMessage(hWndMain,WM_COMMAND,IDM_EXIT,0L);
          break;
      }
      break;    // End of WM_COMMAND
    default:
      return FALSE;
  }
  return TRUE;
}

BOOL FAR PASCAL WS_StatMsgProc(HWND hWndDlg, WORD Message, 
                               WORD wParam, LONG lParam)
{ 
  switch(Message)
  {
    case WM_INITDIALOG:
      break;

    case WM_CLOSE:
      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
      break;

    case WM_SETCURSOR:
      if(bCmdInProgress)
        SetCursor(hWaitCursor);
      else
        return FALSE;
      break;

    case WM_COMMAND:
      switch(wParam)
      {
        case IDOK:
          EndDialog(hWndDlg, TRUE);
          break;
        case IDCANCEL:
          EndDialog(hWndDlg, FALSE);
          break;
      }
      break;    // End of WM_COMMAND
    default:
      return FALSE;
  }
  return TRUE;
}

