/* SYSGRAPH  2.0   (c) Copyright 1988, Bill Crow, Hewlett-Packard Co. */

/* Version 2.0 4/20/88   Renamed from SYSQUEUE to SYSGRAPH
                         Added dynnamic scaling
                         Added menu commands for rescaling and Auto Rescaling
                         Added About... Dialog box */

/* Previous versions: */

/* SysQueue.C -- Windows application that displays system load*/
/* by Barry Press, adapted from FreeMem written               */
/* by Charles Petzold as printed in Microsoft Systems Journal */

/* Adapted for Graphic Display by Alec Saunders       */
/* Graph goes down when load increases and rises when */
/* load decreases    				      */


#include <windows.h>	/* all Windows functions */
#include <stdlib.h>	/* ltoa */
#include <string.h>	/* strcat & strlen */
#include "sysgraph.h"   /* RC defines */

#define MAXCOUNT 25
 
static HANDLE globhInst;

static int  lLoopCount[MAXCOUNT];
static int  iMaxSize=0;

static BOOL bRescale=FALSE;
static BOOL bAutoRescale=FALSE;

long FAR PASCAL WndProc     (HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL AboutDlgProc(HWND, unsigned, WORD, LONG);

/* WinMain - Main loop for all Windows applications */
int PASCAL WinMain ( hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int     nCmdShow;
{
	static   char szAppName [] = "SysGraph";
	WNDCLASS WndClass;
	HWND     hWnd;
	MSG      msg;
        HMENU    hMenu;
	int	 i;

	/* allow only one instance */
	if (hPrevInstance)
	   return FALSE;

        globhInst = hInstance;

	/* define Window class */
	WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClass.hIcon         = NULL;
	WndClass.cbClsExtra    = 0;
	WndClass.cbWndExtra    = 0;
	WndClass.lpszMenuName  = NULL;
	WndClass.lpszClassName = szAppName;
	WndClass.hbrBackground = GetStockObject( WHITE_BRUSH );
	WndClass.hInstance     = hInstance;
	WndClass.style         = CS_VREDRAW | CS_HREDRAW;
	WndClass.lpfnWndProc   = WndProc;

	/* register this new class with WINDOWS */
	if (!RegisterClass( &WndClass ))
	   return FALSE;   /* Initialization failed */

	/* create window */
	hWnd = CreateWindow( szAppName,
			szAppName,
			WS_TILEDWINDOW,
			0, 0, 0, 0,
			(HWND)   NULL,
			(HMENU)  NULL,
			hInstance,
			NULL);

	/* set up timer (1 update/sec) */
	if (!SetTimer (hWnd, 1, 500, NULL) )
	   return FALSE;

	hMenu = GetSystemMenu(hWnd,FALSE);
	ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
	ChangeMenu(hMenu,0,(LPSTR)"R&escale", IDRESCALE,
            MF_APPEND | MF_STRING | (bAutoRescale? MF_GRAYED : MF_ENABLED));
	ChangeMenu(hMenu,0,(LPSTR)"A&uto Rescale", IDAUTORESCALE, 
            MF_APPEND | MF_STRING | (bAutoRescale? MF_CHECKED : MF_UNCHECKED));
	ChangeMenu(hMenu,0,(LPSTR)"A&bout...",IDABOUT, MF_APPEND | MF_STRING);
	   
        /* show window (start in ICONIC state) */
	ShowWindow( hWnd, SHOW_ICONWINDOW );
	UpdateWindow( hWnd );

	/* initialize loop count which is bumped in loop */
	for(i=0;i<MAXCOUNT;lLoopCount[i++] = 0)
		;

	/* main program loop */
	while (TRUE) {
		lLoopCount[MAXCOUNT - 1]++;
		if (PeekMessage( &msg, NULL, 0, 0, TRUE )) {
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	/* exit back to Windows */
	return (int) msg.wParam;

} /* end WinMain */

/* WndProc - Window procedure for main window */
long FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND	 hWnd;
unsigned message;
WORD	 wParam;
LONG	 lParam;
{
	char	buffer[MAXCOUNT];
	PAINTSTRUCT ps;
	RECT	rect;
        HMENU   hMenu;
	int	i;

	/* switch on message type sent to window by Windows dispatcher */
	switch(message) {

	   case WM_TIMER:
              if (iMaxSize<lLoopCount[MAXCOUNT-1])
                  iMaxSize=lLoopCount[MAXCOUNT-1];
	      for (i=0; i<(MAXCOUNT - 1); i++)
	     	 lLoopCount[i] = lLoopCount[i+1];
	      lLoopCount[MAXCOUNT - 1] = 0;
              InvalidateRect( hWnd, NULL, TRUE );
	      break;

	   case WM_PAINT:
	      BeginPaint( hWnd, &ps );
	      GetClientRect( hWnd, &rect );
	      SetMapMode( ps.hdc, MM_ANISOTROPIC);
              if (bRescale | bAutoRescale) {
		 iMaxSize=0; 
		 for (i=0;i<MAXCOUNT;i++) {
		    if (iMaxSize<lLoopCount[i])
			iMaxSize=lLoopCount[i];
		 }
                 bRescale=FALSE;
              }
	      SetWindowOrg( ps.hdc, 0, 0);
	      SetWindowExt( ps.hdc, MAXCOUNT, iMaxSize);
	      SetViewportOrg(ps.hdc, 0, 0);
	      SetViewportExt(ps.hdc, rect.right - rect.left,
	      			  rect.bottom - rect.top);

	      MoveTo( ps.hdc, 0, iMaxSize-lLoopCount[0]);
	      for (i = 1; i < (MAXCOUNT - 1); i++)
	      	LineTo( ps.hdc, i, iMaxSize-lLoopCount[i]);

	      EndPaint( hWnd, &ps );
	      break;

	      case WM_SYSCOMMAND:
		switch (wParam)
		{
		  case IDABOUT:
		    DialogBox(globhInst,
		      (LPSTR)"AboutBox",
		      hWnd,
		      MakeProcInstance( (FARPROC)AboutDlgProc, globhInst));
		    break;

		  case IDRESCALE:
		    bRescale=TRUE;
                    break;

		  case IDAUTORESCALE:
		    bAutoRescale = ! bAutoRescale;
		    hMenu = GetSystemMenu(hWnd,FALSE);
		    CheckMenuItem(hMenu,
		       IDAUTORESCALE,
                       MF_BYCOMMAND | 
                         (bAutoRescale? MF_CHECKED : MF_UNCHECKED));
		    EnableMenuItem(hMenu,
		       IDRESCALE,
		       MF_BYCOMMAND | 
                         (bAutoRescale? MF_GRAYED : MF_ENABLED));
		    break;

		  default:
		    return DefWindowProc(hWnd,message,wParam,lParam);  
		    break;

		}
		break;

	   case WM_DESTROY:
	      KillTimer (hWnd, 1);
	      PostQuitMessage( 0 );
	      break;

	   default:
	      return DefWindowProc( hWnd, message, wParam, lParam);
	}

	return (long) 0;

} /* end WndProc */

BOOL FAR PASCAL AboutDlgProc(hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
if (message == WM_COMMAND) 
{
   EndDialog( hDlg, TRUE );
   return TRUE;
}
else
 return FALSE;
}   /* end About */
