//******************************************************************************
//
//  File name   : SPWINMAN.C
//
//  Description : make ascii file from host spool file
//
//  FUNCTIONS:
//
//  WinMain()                  - Calls init functions, processes msg loop
//  RegisterApplicationClass() - Register's window class
//  InitInstance()             - Saves instance handle and creates main window
//  SpoolToFileWndProc()       - Processes messages
//  PCFilenameDialog()         - Processes messages for "PCfilename" dialog box
//  About()                    - Processes messages for "About" dialog box
//
//  COMMENTS:
//
//  1.  Windows can have several copies of this application running at the
//      same time.  The variable hGlobalInst keeps track of which instance this
//      application is so that processing will be to the correct window.
//
//  2.  Each instance of this application corresponds to one session
//      instance. This allows menu sensitivity on a session by session
//      basis.
//
//  3.  Invocation:  SPL2FILE /x   where "x" is the alpha session ID. A .. Z
//
//  Copyright  (C) 1993, 1996 IBM Corporation
//                        All rights reserved.
//
//******************************************************************************

#include <windows.h>                // required for all Windows applications
#include <windowsx.h>               // Windows Macro APIs, window message crackers

#include <string.h>                 // String functions
#include <stdio.h>                  // sscanf  function
#include <ctype.h>                  // toupper function

#include "spl2file.h"               // specific to this program

#define MAIN                        // Instance the data in this module
#include "spdata.h"                 // Global Data

//******************************************************************************
//
// Local Function Definitions
//
//******************************************************************************

BOOL NEAR GetSessionIDs( LPSTR );
BOOL NEAR SpawnOtherSessions( void );

//******************************************************************************
//
//  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
//
//  PURPOSE: calls initialization function, processes message loop
//
//  COMMENTS:
//
//      Windows recognizes this function by name as the initial entry point
//      for the program.  This function calls the application initialization
//      routine, if no other instance of the program is running, and always
//      calls the instance initialization routine.  It then executes a message
//      retrieval and dispatch loop that is the top-level control structure
//      for the remainder of execution.  The loop is terminated when a WM_QUIT
//      message is received, at which time this function exits the application
//      instance by returning the value passed by PostQuitMessage().
//
//      If this function must abort before entering the message loop, it
//      returns the conventional value NULL.
//
//******************************************************************************
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpzCmdLine, int nCmdShow)
{
  MSG msg;

  GetSessionIDs(lpzCmdLine);                        // Get our Session ID A .. H
                                                    //
  lstrcpy(zSpoolToFileClassName, zSpoolToFileClassPrefix ); // Build SpoolToFile Class Name
  lstrcat(zSpoolToFileClassName, zSessionID      ); //
                                                    //
  lstrcpy(zSessionClassName, zSessionClassPrefix ); // Build PC/5250 Session
  lstrcat(zSessionClassName, zSessionID          ); // Class Name
                                                    //
  if( FindWindow(zSpoolToFileClassName, NULL) == NULL ) // Does prev class ins
  {                                                 //
    if( !RegisterApplicationClass(hInstance) )      //
    {                                               //
      LoadString(hInstance, LS_ERROR2_TEXT, zFmtBuffer, sizeof(zFmtBuffer));
      wsprintf( (LPSTR) zMsgBuffer, (LPSTR) zFmtBuffer, (LPSTR) zSessionID);
      MessageBox(NULL, (LPSTR) zMsgBuffer, (LPSTR) zSpoolToFileClassPrefix, MB_OK | MB_ICONQUESTION );
      return( FALSE );                              //
    }                                               //
  }                                                 //
  else                                              //
  {                                                 //
    LoadString(hInstance, LS_ERROR1_TEXT, zFmtBuffer, sizeof(zFmtBuffer));
    wsprintf( (LPSTR) zMsgBuffer, (LPSTR) zFmtBuffer, (LPSTR) zSessionID);
    MessageBox(NULL, (LPSTR) zMsgBuffer, (LPSTR) zSpoolToFileClassPrefix, MB_OK | MB_ICONQUESTION );
    return( FALSE );                                //
  }                                                 //

  //** Perform initializations that apply to a specific instance

  if (!InitInstance(hInstance, nCmdShow))           //
  {                                                 //
    return( FALSE );                                //
  }                                                 //

  if( !InitDDE() )                                  // Init DDE
  {                                                 //
    return( FALSE );                                // Return if ERROR
  }                                                 //

  // Dispatch messages until a WM_QUIT message is received.

  SpawnOtherSessions();                             // Spawn other sessions

  while( GetMessage(&msg, NULL, (unsigned int)NULL, (unsigned int)NULL) )       //
  {                                                 //
    TranslateMessage(&msg);                         // Translates virtual key codes
    DispatchMessage(&msg);                          // Dispatches message to window
  }                                                 //

  return (msg.wParam);                              // Returns the value from PostQuitMessage
}                                                   //

//******************************************************************************
//
//  FUNCTION: RegisterApplicationClass(HANDLE)
//
//  PURPOSE: Initializes window data and registers window class
//
//  COMMENTS:
//
//      This function is called at initialization time only if no other
//      instances of the application are running.  This function performs
//      initialization tasks that can be done once for any number of running
//      instances.
//
//      In this case, we initialize a window class by filling out a data
//      structure of type WNDCLASS and calling the Windows RegisterClass()
//      function.  Since all instances of this application use the same window
//      class, we only need to do this when the first instance is initialized.
//
//
//******************************************************************************
BOOL RegisterApplicationClass( HANDLE hInstance )
{
  WNDCLASS  wc;

  // Fill in window class structure with parameters that describe the
  // main window.


  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(SPICON));
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  wc.cbClsExtra    = (int)NULL;
  wc.cbWndExtra    = (int)NULL;
  wc.style         = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  wc.lpszMenuName  = MAKEINTRESOURCE(SPMENU);
  wc.lpszClassName = zSpoolToFileClassName;
  wc.lpfnWndProc   = SpoolToFileWndProc;

  // Register the window class and return success/failure code.

  return ( RegisterClass(&wc) );
}

//******************************************************************************
//
//  FUNCTION:  InitInstance(HANDLE, int)
//
//  PURPOSE:  Saves instance handle and creates main window
//
//  COMMENTS:
//
//      This function is called at initialization time for every instance of
//      this application.  This function performs initialization tasks that
//      cannot be shared by multiple instances.
//
//      In this case, we save the instance handle in a static variable and
//      create and display the main program window.
//
//******************************************************************************
BOOL InitInstance(HANDLE hInstance, int iCmdShow)
{
  HWND hWnd;
  int iX, iY;
  uchar zTag[33];                        //

  // Save the instance handle in static variable, which will be used in
  // many subsequence calls from this application to Windows.

  hGlobalInst = hInstance;

  // Create a main window for this application instance.

  iX = GetSystemMetrics( SM_CXSCREEN );
  iY = GetSystemMetrics( SM_CYSCREEN );

  LoadString(hInstance, LS_TITLE_TEXT, zFmtBuffer, sizeof(zFmtBuffer));

  wsprintf( (LPSTR) zMsgBuffer, (LPSTR) zFmtBuffer, (LPSTR) zSessionID);

  hWnd = CreateWindow(
      zSpoolToFileClassName,           // See RegisterClass() call.
      zMsgBuffer,                      // Text for window title bar.
      WS_OVERLAPPEDWINDOW,             // Window style.
      (iX / 4),                        // Default horizontal position.
      (iY / 4),                        // Default horizontal position.
      (iX / 2),                        // Default Width
      (iY / 2),                        // Default Height
      NULL,                            // Overlapped windows have no parent.
      NULL,                            // Use the window class menu.
      hInstance,                       // This instance owns this window.
      NULL                             // Pointer not needed.
  );

  // If window could not be created, return "failure"

  if ( hWnd == NULL )
  {
    return(FALSE);
  }

  hMainWnd = hWnd;                         // Save
                                           //
  LoadString(hGlobalInst, LS_OPTIONS_TAG, zTag, sizeof(zTag) );
  lstrcat(zTag, zSessionID );              // Qualify to session
                                           //
  GetProfileString(zSpoolToFileClassPrefix,// WIN.INI section name
                   zTag,                   // value tag
                   "1 1",                  // Default String to use
                   zMsgBuffer,             // receiving buffer
                   sizeof(zMsgBuffer));    // size of receiving buf

  sscanf(zMsgBuffer, "%d %d", &bVisible, &bRemoveSoSi);

  // Show the window based on user's choice

  if( bVisible )
  {
    ShowWindow(hWnd, SW_MINIMIZE);  // Show the window
                                    //
    UpdateWindow(hWnd);             // Sends WM_PAINT message
  }                                 //
  else                              //
  {                                 //
    ShowWindow(hWnd, SW_HIDE);      // Show the window HIDDEN
  }                                 //
                                    //
  return(TRUE);                     // Return OK
}

//****************************************************************************
//
//  FUNCTION: SpoolToFileWndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages
//
//  MESSAGES:
//
//      WM_COMMAND    - application menu (About dialog box)
//      WM_DESTROY    - destroy window
//
//  COMMENTS:
//
//      To process the ID_ABOUT message, call MakeProcInstance() to get the
//      current instance address of the About() function.  Then call Dialog
//      box which will create the box according to the information in your
//      spl2file.rc file and turn control over to the About() function.  When
//      it returns, free the intance address.
//
//**************************************************************************
long FAR PASCAL SpoolToFileWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  FARPROC      lpProcModalDialog;
  BYTE         Event;

  switch (message)
  {
    case WM_COMMAND:
    {
      switch (GET_WM_COMMAND_ID(wParam,lParam))
      {
        case ID_ABOUT:
          lpProcModalDialog = MakeProcInstance(About, hGlobalInst);
          DialogBox(hGlobalInst, MAKEINTRESOURCE(ABOUTBOX), GET_WM_COMMAND_HWND(wParam,lParam), lpProcModalDialog);
          FreeProcInstance(lpProcModalDialog);
          break;

        case ID_SPOOL:   // Spool to File
        {
          TerminateConversation();
          StartSpoolToFile( GET_WM_COMMAND_HWND(wParam,lParam) );
        }
        break;

        case ID_ZCONFG: // Configure SpoolToFile
        {
          TerminateConversation();
          ConfigureSpoolToFile( GET_WM_COMMAND_HWND(wParam,lParam) );
        }
        break;

        default:
          return( DefWindowProc(hWnd, message, wParam, lParam) );
          break;
      }
    }
    break;

    case WM_QUERYOPEN:  // Do not allow ICON to open
      return( FALSE );
      break;

    case WM_DESTROY:                  // message: window being destroyed
      TerminateConversation();
      PostQuitMessage(0);
      break;

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
//
//  DDE Messages .....
//
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **

    case WM_DDE_INITIATE:
      return( SpDDEInitiate(hWnd, message, wParam, lParam) );
      break;

    case WM_DDE_ACK:
      return( SpDDEAck(hWnd, message, wParam, lParam) );
      break;

    case WM_DDE_DATA:
      return( SpDDEData(hWnd, message, wParam, lParam) );
      break;

    case WM_DDE_REQUEST:
      return( SpDDERequest(hWnd, message, wParam, lParam) );
      break;

    case WM_DDE_TERMINATE:
      return( SpDDETerminate(hWnd, message, wParam, lParam) );
      break;

// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
//
//  User defined
//
// ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
    case WM_USER_END:
      Event = EV_END;
      return ( FSM_Event(Event, (unsigned short)NULL, NULL) );
      break;

    case WM_USER_ERROR:
      Event = EV_ERROR;
      return ( FSM_Event(Event, (unsigned short)NULL, NULL) );
      break;

    case WM_USER_ABORT:
      Event = EV_ABORT;
      return ( FSM_Event(Event, (unsigned short)NULL, NULL) );
      break;

    case WM_USER_CONT:
      Event = EV_CONT;
      return ( FSM_Event(Event, (unsigned short)NULL, NULL) );
      break;

    case WM_USER_BREAK:
      Event = EV_BRK;
      return ( FSM_Event(Event, (unsigned short)NULL, NULL) );
      break;

    default:                          /* Passes it on if unproccessed    */
      return( DefWindowProc(hWnd, message, wParam, lParam) );
      break;
  }
  return( FALSE );
}

//******************************************************************************
//
//  GetSessionIDs - Retrieve the session ID's from the command line.
//
//  Abstract:
//
//  If sessions ID's are specified on the command line start them. If no
//  ID's are specified on the command line use this instance as session A's
//  instance as a default.
//
//  The command line for a session instance will be
//
//     session  /[a][b][c]...[z]  allowed session ID's
//
//
//  Notes:
//
//
//  Attributes:
//
//  Returns: BOOL  (FALSE = ERROR)
//
//******************************************************************************
BOOL NEAR GetSessionIDs( LPSTR lpzCmdLine )
{
  int  i, j;
  int  iLength          = lstrlen(lpzCmdLine);
  int  iOtherCount      = (int)NULL;
  BOOL bForThisInstance = TRUE;

  zSessionID[1] = (unsigned char)NULL;        // Null Terminator
                                              //
  for( i = 0; i < iLength; i++ )              // Scan across for "/"
  {                                           //
    if( *lpzCmdLine++ == '/' )                //
    {                                         //
      for( j = i+1; j < iLength; j++ )        //
      {                                       //
        uchar cID = *lpzCmdLine++;            //
                                              //
        cID = (uchar) toupper( cID );         // Upcase the character
                                              //
        if( 'A' <= cID && cID <= 'Z' )        //
        {                                     //
          if( bForThisInstance )              //
          {                                   //
            zSessionID[0] = (uchar) cID;      //
            bForThisInstance = FALSE;         //
          }                                   //
          else                                //
          {                                   //
            zOtherSessionIDs[iOtherCount++] = (uchar) cID;
          }                                   //
        }                                     //
      }                                       //
      zOtherSessionIDs[iOtherCount] = (unsigned char)NULL;   // Terminate it
      return(TRUE);                           // Never an Error
    }                                         //
  }                                           //
                                              //
  zSessionID[0] = (uchar) 'A';                // Default to 'A'
                                              //
  return(TRUE);                               //
}                                             //

//******************************************************************************
//
//  SpawnOtherSessions - Spawns other sessions when multiple sessions
//                       are started on the spl2file command line.
//
//  Abstract:
//
//  The command line for a session instance will be
//
//     session  /[a][b][c][d][e][f][g][h]  allowed session ID's
//
//
//  Notes:
//
//
//  Attributes:
//
//  Returns: BOOL  (FALSE = ERROR)
//
//******************************************************************************
BOOL NEAR SpawnOtherSessions( void )
{
  int  iRC, i;
  int  iLength = lstrlen(zOtherSessionIDs);

  if( iLength > 0 )
  {
    for( i = 0; i < iLength; i++ )
    {
      wsprintf(zMsgBuffer,"Spl2File /%c", (uchar) zOtherSessionIDs[i]);
      iRC = WinExec((LPSTR) zMsgBuffer, SW_SHOWMINIMIZED);
      if( iRC <= 32 )
      {
        MessageBox(NULL, (LPSTR) "Winexec for Spl2File Failed", (LPSTR) "Spl2File", MB_OK | MB_ICONQUESTION );
      }
    }
  }
  return( TRUE );
}

//******************************************************************************
//
//  FUNCTION: PCFilenameDialog(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for PC filename dialog box
//
//  MESSAGES:
//
//      WM_INITDIALOG - initialize dialog box
//      WM_COMMAND    - Input received
//
//  COMMENTS:
//
//      No initialization is needed for this particular dialog box, but TRUE
//      must be returned to Windows.
//
//      Wait for user to click on "Ok" button, then close the dialog box.
//
//******************************************************************************
BOOL FAR PASCAL PCFilenameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
    case WM_INITDIALOG:                     // message: initialize dialog box
      CenterDialogOnScreen( hDlg );         // Center it
      return(TRUE);
      break;

    case WM_COMMAND:                        // message: received a command
      switch (GET_WM_COMMAND_ID(wParam,lParam))
      {
        case IDOK:
          {
            HWND hEditControl = GetDlgItem(hDlg, ID_EDIT1);
            if (GetWindowText(hEditControl, zPCFilename, sizeof(zPCFilename) ) == 0)
              EndDialog(hDlg, FALSE);         // Exits the dialog box
            else
              EndDialog(hDlg, TRUE);          // Exits the dialog box
          }
          return(TRUE);
          break;

        case IDCANCEL:
          EndDialog(hDlg, FALSE);           // Exits the dialog box
          return(TRUE);
          break;

        default:
          break;

      }
      break;
  }
  return(FALSE);                            // Didn't process a message
}

//******************************************************************************
//
//  FUNCTION: About(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for "About" dialog box
//
//  MESSAGES:
//
//      WM_INITDIALOG - initialize dialog box
//      WM_COMMAND    - Input received
//
//  COMMENTS:
//
//      No initialization is needed for this particular dialog box, but TRUE
//      must be returned to Windows.
//
//      Wait for user to click on "Ok" button, then close the dialog box.
//
//******************************************************************************
BOOL FAR PASCAL About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
    case WM_INITDIALOG:                     // message: initialize dialog box
      CenterDialogOnScreen( hDlg );         // Center it
      return(TRUE);
      break;

    case WM_COMMAND:                        // message: received a command
      switch (GET_WM_COMMAND_ID(wParam,lParam))
      {
        case IDOK:
        case IDCANCEL:
          EndDialog(hDlg, TRUE);            // Exits the dialog box
          return(TRUE);
          break;

        default:
          break;

      }
      break;
  }
  return(FALSE);                            // Didn't process a message
}
