/***********************************************************************
 *                                                                     *
 *  MODULE      : BROWSE.c                                             *
 *                                                                     *
 *  PURPOSE     : Contains the Browse dialog and helper functions.     *
 *                                                                     *
 *  FUNCTIONS   : IsWild ()       - Checks a string for DOS wildcard   *
 *                                  characters.                        *
 *                                                                     *
 *                FileExists()    - Checks to see if a file exists.    *                                   *
 *                                                                     *
 *                SelectFile()    - If the filename supplied has a     *
 *                                  wildcard, this function fills the  *
 *                                  listboxes in the Browse dialog,    *
 *                                  otherwise it sets the filename     *
 *                                  and closes the dialog.             *
 *                                                                     *
 *                ChangeExt()     - Changes the default file extension *
 *                                  mask for the Browse dialog.        *
 *                                                                     *
 *                BrowseDlg()     - Dialog funcion for the Browse      *
 *                                  dialog.                            *
 *                                                                     *
 ***********************************************************************/
#include "browse.h"

#include <sys\types.h>     /* Additional includes needed      */
#include <sys\stat.h>      /* for the fstat() function        */    

OFSTRUCT OfStruct;         /* Information from OpenFile()     */

char szProgName[128];
char szDefSpec[14]="*.*";

/**********************************************************************
 *                                                                    *
 *  FUNCTION   : IsWild(PSTR)                                         *
 *                                                                    *
 *  PURPOSE    : Checks if the string (referenced by a NEAR pointer)  *
 *               contains a DOS wildcard character ("*" or "?").      *
 *                                                                    *
 *  RETURNS    : TRUE  - if the string contains a wildcard character. *
 *               FALSE - otherwise.                                   *
 *                                                                    *
 **********************************************************************/
BOOL NEAR PASCAL IsWild(psFileName)
register PSTR psFileName;
{
    for(;;)
       switch (*psFileName++)
              {
              case '*':
              case '?':
                   /* Found wildcard */
                   return (TRUE);

              case 0:
                   /* Reached end of string */
                   return (FALSE);

              default:
                   continue;
              }
}


/***********************************************************************
 *                                                                     *
 *  FUNCTION   : FileExists(PSTR)                                      *
 *                                                                     *
 *  PURPOSE    : Checks to see if a file exists with the path/filename *
 *               described by the string pointed to by 'psFileName'.   *
 *                                                                     *
 *  RETURNS    : TRUE  - if the described file does exist.             *
 *               FALSE - otherwise.                                    *
 *                                                                     *
 ***********************************************************************/
BOOL NEAR FileExists(PSTR psFileName)
{
    int hFile;  /* DOS file handle */

    if ((hFile = _lopen((LPSTR)psFileName, NULL)) < 0)
       return (FALSE);

    _lclose(hFile);

    return (TRUE);
}


/***********************************************************************
 *                                                                     *
 *  FUNCTION   : SelectFile (HWND)                                     *
 *                                                                     *
 *  PURPOSE    : Reads the string in the edit control of the File/Open *
 *               dialog. If it contains a wildcard, then it attempts   *
 *               to fill the listboxes in the File/Open dialog.        *
 *               otherwise it ends the dialog.                         *
 *                                                                     *
 ***********************************************************************/
VOID NEAR PASCAL SelectFile(hDlg)
HWND hDlg;
{

    /* Get the text from the dialog's edit control into this address */
    GetDlgItemText(hDlg, IDC_FILENAME, szProgName, 64);

    if (IsWild(szProgName))
       {
       /* Select the directory and make a listing of the directories */
       DlgDirList(hDlg, (LPSTR)szProgName, IDC_DIRS, IDC_PATH, ATTR_DIRS);

       /* List the files in this directory based on the wildcard. */
       DlgDirList(hDlg, (LPSTR)szProgName, IDC_FILES, IDC_PATH, ATTR_FILES);

       /* Set the dialog's edit control to the filename. */
       SetDlgItemText (hDlg, IDC_FILENAME, szProgName);
       }
    else /* The filename is not a wildcard */
       {
       if (FileExists(szProgName))
          {
          OpenFile (szProgName, &OfStruct, OF_EXIST);
          lstrcpy (szProgName, OfStruct.szPathName);
          EndDialog (hDlg, TRUE);
          }
       else /* file does not exist */
          {
          /* see if it is a directory without a wildcard */ 
          if (DlgDirList(hDlg, (LPSTR)szProgName, IDC_DIRS, IDC_PATH, ATTR_DIRS))
             {
             lstrcpy((LPSTR)szProgName, (LPSTR)szDefSpec);
             DlgDirList(hDlg, (LPSTR)szProgName, IDC_FILES, IDC_PATH, ATTR_FILES);
             SetDlgItemText(hDlg, IDC_FILENAME, szProgName);
             }
          else /* path was invalid - error */
             {
             lstrcpy((LPSTR)str,"Cannot find file ");
             lstrcat((LPSTR)str,(LPSTR)szProgName);
             lstrcat((LPSTR)str," !\n\n");
             lstrcat((LPSTR)str,"Check to ensure the path and \n");
             lstrcat((LPSTR)str,"filename are correct.");
             MessageBox(hDlg,str,"Browse",MB_OK | MB_ICONEXCLAMATION);
             SendDlgItemMessage(hDlg, IDC_FILENAME, EM_SETSEL,
                                 NULL,MAKELONG(0,64)); 
             SetActiveWindow(hDlg);
             }
          }
       }
}


/**********************************************************************
 *                                                                    *
 *  FUNCTION   : ChangeExt(HWND,PSTR)                                 *
 *                                                                    *
 *  PURPOSE    : Changes the file extension after an 'Open From'.     *
 *                                                                    *
 *  RETURNS    : void                                                 *
 *                                                                    *
 **********************************************************************/
void NEAR ChangeExt(hDlg,psNewExt)
HWND hDlg;
PSTR psNewExt;
{
    PSTR psNameTemp;
    PSTR psExtTemp;

    /* set default file spec */
    lstrcpy (szDefSpec, "*.");
    lstrcat (szDefSpec, psNewExt);

    /* set szProgName to new default spec */
    lstrcpy(szProgName,szDefSpec);

    /* update the FILENAME edit control to show new extension */
    SetDlgItemText(hDlg,IDC_FILENAME,szProgName);

    /* select files that qualify with new extension */
    SelectFile(hDlg);
}


/***********************************************************************
 *                                                                     *
 *  FUNCTION   : BrowseDlg()                                           *
 *                                                                     *
 *  PURPOSE    : Dialog function for the 'Browse' dialog.  Takes care  *
 *               of calling the appropriate functions for extracting   *
 *               the filename and wildcard, filling the listboxes and  *
 *               changing the ProgName.                                *
 *                                                                     *
 *  RETURNS    : TRUE if a file was selected, else FALSE.              *
 *                                                                     *
 ***********************************************************************/
BOOL FAR PASCAL BrowseDlg(hDlg, message, wParam, lParam)
HWND hDlg;
WORD message;
WORD wParam;
LONG lParam;
{

    switch (message)
    {

    case WM_INITDIALOG:

         /* Set the default file extension on edit window, and try to
          * get a listing of the files and directories.    */
         SetDlgItemText (hDlg, IDC_FILENAME, "*.*");
         SendDlgItemMessage (hDlg, IDC_FILENAME, EM_LIMITTEXT, 80, NULL);
         SendDlgItemMessage (hDlg, IDC_FILENAME, EM_SETSEL,
                             NULL,MAKELONG(NULL,80)); 

         /* set the current default file mask specification to '*.*'   */
         SendDlgItemMessage (hDlg, IDC_DEF_STAR, BM_SETCHECK, TRUE, NULL);
         SendMessage (hDlg, WM_COMMAND, IDC_DEF_STAR, NULL);

         break;

    case WM_COMMAND:
         switch (wParam)
         {
         case IDOK:
              SelectFile(hDlg);
              break;

         case IDCANCEL:
              /* Set szProgName to NULL and quit */
              *szProgName = 0;
              EndDialog (hDlg, FALSE);
              break;

         case IDC_FILENAME:
              /* Enable the OK button if the edit control has text. */
              EnableWindow (GetDlgItem (hDlg, IDOK),
                            GetWindowTextLength((HWND)LOWORD (lParam)));
              break;

         case IDC_FILES:

              /* The files listbox. If file selection has changed,
               * set text in edit control. */
              if (HIWORD(lParam) == LBN_SELCHANGE)
                 {
                 DlgDirSelect (hDlg, (LPSTR)szProgName, IDC_FILES);
                 SetDlgItemText (hDlg, IDC_FILENAME, (LPSTR)szProgName);
                 }
              else if (HIWORD(lParam) == LBN_DBLCLK)
                      /* if the item was double-clicked, try to open it */
                      SelectFile(hDlg);
              break;

         case IDC_DIRS:

              /* The directories listbox. Append current filename in edit
               */
              if (HIWORD(lParam) == LBN_SELCHANGE)
                 {
                 PSTR psFilePart, psTemp1, psTemp2;

                 /* Get the new drive/dir and copy it to the TempName */
                 DlgDirSelect (hDlg, szProgName, IDC_DIRS);
                 psFilePart = szProgName + lstrlen(szProgName);

                 /* Get contents of dialog's edit control
                  * and add it to the TempName */
                 GetDlgItemText(hDlg,IDC_FILENAME,(LPSTR)psFilePart,80);

                 if (*psFilePart == 0 || !IsWild(psFilePart))
                    {  /* file part is null or non-wild */
                    lstrcpy((LPSTR)psFilePart,(LPSTR)szDefSpec);
                    }
                 else
                    {  /* file part is wild - remove old dir part if any */
                    for (psTemp1=psTemp2=psFilePart; *psTemp1; psTemp1++)
                        {
                        if (*psTemp1 == '\\' || *psTemp1 == ':')
                           psTemp2 = psFilePart;
                        else
                           *psTemp2++ = *psTemp1;
                        }
                    *psTemp2 = 0;
                    }
                                   
                 /* Set the edit control with new string */
                 SetDlgItemText (hDlg, IDC_FILENAME, (LPSTR)szProgName);
                 }
              else if (HIWORD(lParam) == LBN_DBLCLK)
                 SelectFile (hDlg);
              break;

         case IDC_DEF_STAR:
              ChangeExt(hDlg,"*");
              break;

         case IDC_DEF_1:
              ChangeExt(hDlg,"EXE");
              break;

         case IDC_DEF_2:
              ChangeExt(hDlg,"PIF");
              break;

         case IDC_DEF_3:
              ChangeExt(hDlg,"BAT");
              break;

         case IDC_DEF_4:
              ChangeExt(hDlg,"COM");
              break;

         default:
              return (FALSE);
         }
         break;

    default:
         return (FALSE);
    }
    return (TRUE);
}
