/*
		       Five in one

               (c) Eric Lapaille - Belgium - 1991

		       Do not remove this comment

*/

#include "no.h"
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>

#if (_MSC_VER >= 600)
   long FAR PASCAL WndProc( HWND , unsigned ,WORD , LONG );
#else
   /* Borland C++ (don't know for Zortech and Topspeed) */
   long FAR PASCAL _export WndProc( HWND , unsigned ,WORD , LONG );
#endif

BOOL FAR PASCAL About        (HWND , unsigned , WORD , LONG );
BOOL FAR PASCAL ShellWnd     (HWND , unsigned , WORD , LONG );

void emm_get_num_pages( int *, int *);
void SetFontScreen (void);
void Process(short);

#define EMS 1
#define IDM_ABOUT  100
#define IDM_FAST   101
#define IDM_SHELL  102

#define IDSH      200

BOOL    bBlack     = FALSE;
BOOL    bFirstShell=FALSE;
BOOL    bMode      = FALSE;
FARPROC lpProcShell;
HANDLE  hInst;
HWND    hWShell,hOldWnd;
HWND    hWnd;
LOGFONT logfont;
char    szAppName[]  = "5IN1";

/* ---------------------------------------------------------- */

int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int cmdShow )
  {
  WNDCLASS WndClass;
  MSG      msg;

  DWORD    dwFlags;
  HMENU    hMenu;

  if (hPrevInstance)
     return FALSE;

  WndClass.hCursor          = LoadCursor( NULL, IDC_ARROW );
  WndClass.hIcon            = NULL;
  WndClass.cbClsExtra	    = 0;
  WndClass.cbWndExtra	    = 0;
  WndClass.lpszMenuName	    = szAppName;
  WndClass.lpszClassName    = szAppName;
  WndClass.hbrBackground    = (HBRUSH)GetStockObject( LTGRAY_BRUSH );
  WndClass.hInstance	    = hInstance;
  WndClass.style            = CS_HREDRAW | CS_VREDRAW;
#if (_MSC_VER >= 600)
   #pragma message ("sorry, no way to suppress specific warning with Microsoft")
   cmdShow = cmdShow;
#else
   #pragma warn -sus
#endif
  WndClass.lpfnWndProc      = WndProc;

  if (!RegisterClass( (LPWNDCLASS)&WndClass ) )
     return(FALSE);

  SetFontScreen();

  bFirstShell = (GetNumTasks() == 1);

  hWnd = CreateWindow(szAppName, szAppName,
		      WS_OVERLAPPED | WS_CAPTION| WS_SYSMENU ,
		      0, 0, 40, 40, NULL, NULL, hInstance, NULL );

  if (!SetTimer( hWnd, 1, 2000, NULL ))
     return FALSE;

  hInst = hInstance;

  dwFlags = GetWinFlags();

  if (dwFlags & WF_ENHANCED)
     SetWindowText(hWnd," Enhanced Mode ");
  else
     {
     if (dwFlags & WF_STANDARD)
        SetWindowText(hWnd, " Standard Mode ");
     else
        SetWindowText(hWnd, " Real Mode ");
     }
  if (dwFlags & WF_SMALLFRAME || dwFlags & WF_LARGEFRAME)
     bMode = EMS;

  hMenu = GetSystemMenu(hWnd,FALSE);
  AppendMenu(hMenu, MF_SEPARATOR, NULL      ,(LPSTR)NULL          );
  AppendMenu(hMenu, MF_STRING   , IDM_ABOUT ,(LPSTR)"&About ..."  );
  AppendMenu(hMenu, MF_STRING   , IDM_FAST  ,(LPSTR)"Fast &Exit"  );
  AppendMenu(hMenu, MF_STRING   , IDM_SHELL ,(LPSTR)"Small S&hell");

  ShowWindow( hWnd, SW_SHOWMINIMIZED );
  UpdateWindow( hWnd );
  if (bFirstShell)
     {
     char szB[80];

     if (lpszCmdLine[0])
        Process(WinExec(lpszCmdLine,SW_SHOW));
     GetProfileString ("windows","load","",szB,80);
     if (szB[0])
        Process(WinExec(szB,SW_SHOWMINIMIZED));
     GetProfileString ("windows","run" ,"",szB,80);
     if (szB[0])
        Process(WinExec(szB,SW_SHOW));
     }

  while (GetMessage( &msg, NULL, 0, 0 ))
     {
     if (!(hWShell && IsDialogMessage(hWShell,&msg)))
        {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
        }
     }

  return (int)msg.wParam;
  }

// ----------------------------------------------------------
#if (_MSC_VER >= 600)
   long FAR PASCAL WndProc( HWND hWnd, unsigned message,WORD wParam, LONG lParam )
#else
   long FAR PASCAL _export WndProc( HWND hWnd, unsigned message,WORD wParam, LONG lParam )
#endif
{
  static int mem2,mem1,lastmem1,lastmem2;
  char buffer[20];
  PAINTSTRUCT ps;
  FARPROC lpProc;
  RECT rect;
  int num_pages, unalloc_pages;
  HFONT hFont;

  switch (message)
     {
     case WM_COMPACTING:
        {
        short nI;
        for (nI = 0 ; nI<5 ; nI++)
           FlashWindow(hWnd, 0);
        }
        break;

     case WM_TIMER:
        switch (wParam)
           {
           case 1:
              mem1 = (int) ( GetFreeSpace (0) / 1024L);
              if (bMode == EMS)
                 {
                 emm_get_num_pages( &num_pages, &unalloc_pages );
                 mem2 = unalloc_pages * 16;
                 }
              if (mem1 != lastmem1 || mem2 !=lastmem2)
                 InvalidateRect( hWnd, NULL, TRUE );
              lastmem1 = mem1;
              lastmem2 = mem2;
              break;
           }
        break;

     case WM_PAINT:
        
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        strcat( itoa( mem1, buffer, 10 ), "K" );
        hFont = SelectObject (ps.hdc, CreateFontIndirect(&logfont));
        GetClientRect(hWnd,(LPRECT)&rect);
        MoveTo(ps.hdc,0,rect.bottom-1);
        SelectObject(ps.hdc,GetStockObject(WHITE_PEN));
        LineTo(ps.hdc,0,rect.top);
        LineTo(ps.hdc,rect.right-1,rect.top);
        SelectObject(ps.hdc,GetStockObject(BLACK_PEN));
        LineTo(ps.hdc,rect.right-1,rect.bottom-1);
        LineTo(ps.hdc,0,rect.bottom-1);
        SetBkMode(ps.hdc,TRANSPARENT);
        SetTextColor(ps.hdc,RGB(0,0,255));
        TextOut( ps.hdc, 1,  1, buffer, strlen( buffer ) );
        if (bMode == EMS)
           {
           strcat( itoa( mem2, buffer, 10 ), "K" );
           SetTextColor(ps.hdc,RGB(0,255,0));
           TextOut( ps.hdc, 0, 11, buffer, strlen( buffer ) );
           }
        strcat( itoa( GetNumTasks(), buffer, 10 ), " T" );
        SetTextColor(ps.hdc,RGB(255,0,0));
        TextOut( ps.hdc, 1, 21, buffer, strlen( buffer ) );
        DeleteObject (SelectObject (ps.hdc, hFont));
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

     case WM_SYSCOMMAND:
        switch (wParam)
           {
           case IDM_ABOUT:
              lpProc = MakeProcInstance(About, hInst);
              DialogBox(hInst,"AboutBox",hWnd,lpProc);
              FreeProcInstance(lpProc);
              break;
           case IDM_FAST:
              ExitWindows(0,0);
              break;
           case IDM_SHELL:
              if (hWShell)
                 {
                 SetFocus(GetDlgItem(hWShell,IDSH));
                 SendDlgItemMessage(hWShell,IDSH,EM_SETSEL,0,MAKELONG(0,32767));
                 }
              else
                 {
                 lpProcShell = MakeProcInstance(ShellWnd, hInst);
                 hWShell = CreateDialog(hInst,"SHELL",hWnd,lpProcShell);
                 }
              break;
	   default:
              break;
	   }
	return DefWindowProc( hWnd, message, wParam, lParam );

    case WM_DESTROY:
       KillTimer( hWnd, 1 );
       PostQuitMessage( 0 );
       break;

    case WM_CLOSE:
       if (bFirstShell)
          {
          if (!ExitWindows(0,0))
             break;
          }
       // no break;
    default:
       return DefWindowProc( hWnd, message, wParam, lParam );
    }
    return(0L);
}


// ----------------------------------------------------------

BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
    lParam=lParam;
    switch (message)
       {
       case WM_INITDIALOG:
          return (TRUE);

       case WM_COMMAND:
	  if (wParam == IDOK || wParam == IDCANCEL)
             {
	     EndDialog(hDlg, TRUE);
	     return (TRUE);
             }
          break;
       }
    return (FALSE);
}

// ----------------------------------------------------------

void SetFontScreen ()
   {
   logfont.lfHeight         = 1;
   logfont.lfWidth          = 1;
   logfont.lfEscapement     = 0;
   logfont.lfOrientation    = 0;
   logfont.lfWeight         = 400;
   logfont.lfItalic         = 0;
   logfont.lfUnderline      = 0;
   logfont.lfStrikeOut      = 0;
   logfont.lfCharSet        = ANSI_CHARSET ;
   logfont.lfOutPrecision   = OUT_DEFAULT_PRECIS;
   logfont.lfClipPrecision  = CLIP_DEFAULT_PRECIS;
   logfont.lfQuality        = DEFAULT_QUALITY;
   logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN ;
   strcpy (logfont.lfFaceName, "Tms Rmn") ;
   }

// ----------------------------------------------------------

BOOL FAR PASCAL ShellWnd(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
   {
   short nRet;
   char szBuf[60];

   #if (_MSC_VER >= 600)
      lParam=lParam;
   #else
      #pragma warn -par
   #endif

   switch (message)
      {
      case WM_INITDIALOG:
         ShowWindow(hDlg,SW_SHOW);
         return TRUE;

      case WM_COMMAND:
         switch (wParam)
            {
            case IDOK:
               GetDlgItemText(hDlg,IDSH,szBuf,60);
               if (szBuf[0])
                  {
                  nRet=WinExec(szBuf,SW_SHOW);
                  Process(nRet);
                  if (nRet <32)
                     {
                     SetFocus(GetDlgItem(hDlg,IDSH));
                     SendDlgItemMessage(hDlg,IDSH,EM_SETSEL,0,MAKELONG(0,32767));
                     }
                  }
               else
                  MessageBeep(MB_OK);
               break;
            default:
               break;
            }
         break;
      case WM_CLOSE:
         DestroyWindow(hDlg);
         hWShell=0;
         FreeProcInstance(lpProcShell);
         return TRUE;
      default:
         break;
      }
   return FALSE;
   }

// ----------------------------------------------------------

void emm_get_num_pages( int *num_pages, int *unalloc_pages )
  {
  union REGS regs;

  regs.h.ah = 0x42;
  int86( 0x67, &regs, &regs );
  *num_pages = regs.x.dx;
  *unalloc_pages = regs.x.bx;
  }


void Process(short nRet)
   {
   if (nRet < 32)
      {
      char szBuf[60];

      MessageBeep(MB_OK);
      if (!LoadString(hInst,nRet,szBuf,60))
         sprintf(szBuf,"Undocumented Error %d",nRet);
      MessageBox(hWnd, szBuf,"Error",MB_OK|MB_TASKMODAL|MB_ICONSTOP);
      }
   }
