// GptFrame.cpp
// copyright 1992 Pittsburgh Supercomputing Center
#include "gpt.h"
char FrameWindow::szClass[]       = "gptFrame";
char FrameWindow::szMenu[]        = "gptMenuInit";
char FrameWindow::szAccel[]       = "gptAccel";
HMENU FrameWindow::hMenu          = NULL;
HMENU FrameWindow::hMenuWindow    = NULL;
HANDLE FrameWindow::hAccel = NULL;
// ******************** FrameWindow Class Definitions ************

// **** AboutDlgProc
BOOL FAR PASCAL  _export FrameWindow::AboutDlgProc( HWND hDlg, WORD message, WORD wParam,
					 LONG /* lParam */)
	{
	switch (message)
		{
		case WM_INITDIALOG :  return TRUE;
		case WM_COMMAND:
		switch (wParam)
			{
			case IDOK:
			case IDCANCEL:
			EndDialog( hDlg, 0);
			return TRUE;
			}
		break;
		}
	return FALSE;
	}

BOOL FAR PASCAL FrameWindow::CloseEnumProc (HWND childhWnd, LONG )
	  {
	  if (GetWindow (childhWnd, GW_OWNER))         // check for icon title
			 return 1 ;

	  //SendMessage (GetParent (childhWnd), WM_MDIRESTORE, childhWnd, 0L) ;

	  if (!SendMessage (childhWnd, WM_QUERYENDSESSION, 0, 0L))
			 return 1 ;

	  SendMessage (GetParent (childhWnd), WM_MDIDESTROY, childhWnd, 0L) ;
			 return 1 ;
	  }


// *** FrameWindow::WndProc
long FrameWindow::WndProc( HWND hWnd,WORD iMessage, WORD wParam, LONG lParam )
	{
	FileObjectPt FObj;
	HWND hWndChild;
	CLIENTCREATESTRUCT clientcreate;
	MDICREATESTRUCT mdicreate;
	this->iMessage = iMessage;
	this->wParam   = wParam;
	this->lParam   = lParam;
	switch (iMessage)
		{
		case WM_INITMENUPOPUP:
		hWndChild = LOWORD (SendMessage (Appl::hWndClient,
																WM_MDIGETACTIVE, 0, 0L)) ;
		if (IsWindow (hWndChild))
				 SendMessage (hWndChild, WM_INITMENUPOPUP, wParam, lParam) ;

		return 0;


		case WM_CREATE:
		hWndThis = hWnd;
		Appl::hWndFrame = hWnd;
		clientcreate.hWindowMenu  = hMenuWindow;
		clientcreate.idFirstChild = IDM_FIRSTCHILD;
		// create "client" window
		hWndClient = Appl::hWndClient =
		 CreateWindow("MDICLIENT", NULL,	WS_CHILD |WS_CLIPCHILDREN | WS_VISIBLE,
				  0,0,0,0, hWnd,1,Appl::hInstance, (LPSTR)&clientcreate);
		if (!hWndClient) exit(0);
		DoCaption("pcGPlot");
		PostMessage(hWndThis, WM_COMMAND, IDM_FILEARG, 0);
		return 0;

		case WM_COMMAND:
		switch (wParam)
			{
			case IDM_FILEARG:		//use filename arg on command line
			LPSTR pt;
			BOOL metFlag = FALSE;
			if (Appl::CmdParam && Appl::CmdParam[0])
				{
				// see if filename ends in .met
				pt = _fstrrchr(Appl::CmdParam, '.');
				if (pt  && !_fstricmp(pt, ".met")  && !pt[4] ) metFlag = TRUE ;
				FObj = new FileObject();
				// Do dialog for opening Disk Metafile or CGM
				FObj->DialogFileSetup(
					metFlag?"&Open and Paint Windows Metafile :"
					 :"&Open and Render CGM Binary or Clear Text File :",
					"",
					Appl::CmdParam,
					metFlag?".MET":".CGM",
					0x4010);
				if ( FObj->OpenRead( hWndThis) )
					{
					if (metFlag)  new WMetaWindow(FObj);
					else          new CGMWindow(FObj);
					}
				else delete FObj;
				}

			return 0;

			case IDM_ABOUT:
			DialogBox(Appl::hInstance, "AboutBox", hWnd, lpfnAboutDlgProc);
			return 0;


			case IDM_CLOSE:          // Close the active window
			hWndChild = LOWORD (SendMessage (hWndClient,
															  WM_MDIGETACTIVE, 0,0L));
			if (SendMessage (hWndChild, WM_QUERYENDSESSION, 0, 0L))
				SendMessage (hWndClient, WM_MDIDESTROY, hWndChild, 0L) ;
			return 0;

			case IDM_EXIT:           // Exit the program
			SendMessage (hWnd, WM_CLOSE, 0, 0L) ;
			return 0;

			case IDM_OPEN:           // Open a file and window for it
			FObj = new FileObject();
			// Do dialog for opening CGM's
			FObj->DialogFileSetup(
						"&Open and Render CGM Binary or Clear Text File :",
						"",
						"*.CGM",
						".CGM",
						0x4010);
			if ( FObj->OpenRead( hWndThis) )  new CGMWindow(FObj);
			else delete FObj;
			return 0;

			case IDM_OPENMETA:   // Open a Windows Metafile and window for it
			FObj = new FileObject();
			// Do dialog for opening Disk Metafile
			FObj->DialogFileSetup(
						"&Open and Paint Windows Metafile :",
						"",
						"*.MET",
						".MET",
						0x4010);
			if ( FObj->OpenRead( hWndThis) )  new WMetaWindow(FObj);
			else delete FObj;
			return 0;

			// Messages for arranging windows
			case IDM_TILE:
			SendMessage (hWndClient, WM_MDITILE, 0, 0L) ;
			return 0;

			case IDM_CASCADE:
			SendMessage (hWndClient, WM_MDICASCADE, 0, 0L) ;
			return 0;

			case IDM_ARRANGE:
			SendMessage (hWndClient, WM_MDIICONARRANGE, 0, 0L) ;
			return 0;

			case IDM_CLOSEALL:       // Attempt to close all children
			lpfnCloseEnumProc = MakeProcInstance (
				 (FARPROC)FrameWindow::CloseEnumProc, Appl::hInstance) ;
			EnumChildWindows (hWndClient, lpfnCloseEnumProc, 0L) ;
			FreeProcInstance (lpfnCloseEnumProc) ;
			return 0;

			default:            // Pass to active child
			hWndChild = LOWORD (SendMessage (Appl::hWndClient,
																WM_MDIGETACTIVE, 0, 0L)) ;
			if (IsWindow (hWndChild))
				 SendMessage (hWndChild, WM_COMMAND, wParam, lParam) ;
			break;  // and return defFrameProc
			}
		break;

		case WM_QUERYENDSESSION:
		case WM_CLOSE:                     // Attempt to close all children

		SendMessage (hWnd, WM_COMMAND, IDM_CLOSEALL, 0L) ;
	  // Note if close Icon, this screws up ???
		if (NULL != GetWindow (hWndClient, GW_CHILD)) return 0 ;
		break;


		case WM_DESTROY :
		PostQuitMessage (0) ;
		return 0;
		}
	return DefFrameProc( hWnd,hWndClient, iMessage, wParam, lParam );
	}
int FrameWindow::MessageLoop( void )
	{
	MSG msg;

	while( GetMessage( &msg, NULL, 0, 0 ) )
		{
		if (!TranslateMDISysAccel(hWndClient, &msg) &&
			 !TranslateAccelerator(hWndThis, hAccel, &msg) )
			{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
			}
		}
	return msg.wParam;
	}


// *** FrameWindow constructor
FrameWindow::FrameWindow( void )
	{
		//  strcpy(LocalPath, DefPath);
	  //	  strcpy(LocalSpec,"*");
		//  strcat(LocalSpec,DefExt);
	  //	  strcat(LocalExt, DefExt);
	GetDisplayCaps();
	lpfnAboutDlgProc = MakeProcInstance(
			(FARPROC)FrameWindow::AboutDlgProc, Appl::hInstance );

	 // lpfnFileOpenDlgProc = MakeProcInstance(
	 //	  (FARPROC)FrameWindow::FileOpenDlgProc, Appl::hInstance) ;
	 // lpfnFileSaveDlgProc = MakeProcInstance(
	 //    (FARPROC)FrameWindow::FileSaveDlgProc, Appl::hInstance) ;

	// Pass 'this' pointer in lpParam of CreateWindow().
	CreateWindow( szClass,
		szClass,
		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		hMenu,
		Appl::hInstance,
		(LPSTR) this );
   // Send WM_CREATE message to window
	if ( ! hWndThis ) exit( FALSE );
	//Appl::hWndClient = GetWindow(hWndThis,Appl::nCmdShow );
	//Appl::hWndFrame  = hWndThis;         //only 1 frame for application
	Show( Appl::nCmdShow );
	Update();
	}

// FrameWindow Destructor
FrameWindow::~FrameWindow( void )
	{
   if (lpfnAboutDlgProc)
		FreeProcInstance(lpfnAboutDlgProc);
  //	if (lpfnFileOpenDlgProc)
  //		FreeProcInstance(lpfnFileOpenDlgProc);
  // if (lpfnFileSaveDlgProc)
  //    FreeProcInstance(lpfnFileSaveDlgProc);
   }

// *** FrameWindow::Register - static window class register
void FrameWindow::Register( void )
	{
	WNDCLASS wndclass;   // Structure used to register Windows class.

	wndclass.style         = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc   = ::WndProc;     // the global one
	wndclass.cbClsExtra    = 0;
	// Reserve extra bytes for each instance of the window;
	// we will use these bytes to store a pointer to the C++
	// (FrameWindow) object corresponding to the window.
	// the size of a 'this' pointer depends on the memory model.
	wndclass.cbWndExtra  = sizeof( FrameWindow * );
	wndclass.hInstance   = Appl::hInstance;
	wndclass.hIcon       = LoadIcon( Appl::hInstance,szClass );
	wndclass.hCursor     = LoadCursor( NULL, IDC_ARROW );
	wndclass.hbrBackground = COLOR_APPWORKSPACE +1;  // same as client window
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = szClass;

	if ( ! RegisterClass( &wndclass ) ) exit( FALSE );
	}

void  FrameWindow::LoadMenu(HANDLE hInstance)
	{
	hMenu = ::LoadMenu( hInstance,szMenu);
	hMenuWindow =
		 GetSubMenu( hMenu,INIT_MENU_POS);
	}
void  FrameWindow::LoadAccelerators(HANDLE hInstance)
	{
	hAccel = ::LoadAccelerators( hInstance,szAccel);
	}

void FrameWindow::InitMenu( void )
	{
	SendMessage(hWndClient, WM_MDISETMENU,0,
					MAKELONG( hMenu, hMenuWindow) );
	}


void FrameWindow::GetDisplayCaps(void)
	{
/* ******
		HDC hdcInfo = CreateIC("DISPLAY", NULL,NULL,NULL);
		int Planes        = GetDeviceCaps(hdcInfo,PLANES);             // =1
		int BitsPixel     = GetDeviceCaps(hdcInfo,BITSPIXEL);          // =8

		int NumColors     = GetDeviceCaps(hdcInfo,NUMCOLORS);          // =20
		//Number of entries in the device's color table

		int TextCaps      =  GetDeviceCaps(hdcInfo,TEXTCAPS);          // =2004X
			// Bit   Meaning
			// 0    Device can do character output precision.
			// 1    Device can do stroke output precision.
			// 2    ** Device can do stroke clip precision.
			// 3    Device can do 90-degree character rotation.
			// 4    Device can do any character rotation.
			// 5    Device can do scaling independent of X and Y.
			// 6    Device can do doubled character for scaling.
			// 7    Device can do integer multiples for scaling.
			// 8    Device can do any multiples for exact scaling.
			// 9    Device can do double-weight characters.
			// 10    Device can do italicizing.
			// 11    Device can do underlining.
			// 12    Device can do strikeouts.
			// 13    ** Device can do raster fonts.
			// 14    Device can do vector fonts.
			// 15    Reserved. Must be returned zero.

		int PolygonalCaps =  GetDeviceCaps(hdcInfo, POLYGONALCAPS);    // =8
				// Bit   Meaning
				// 0    Device can do alternate fill polygon.
				// 1    Device can do rectangle.
				// 2    Device can do winding number fill polygon.
				// 3    ** Device can do scanline.
				// 4    Device can do wide borders.
				// 5    Device can do styled borders.
				// 6    Device can do borders that are wide and styled.
				// 7    Device can do interiors.

		int LineCaps      =  GetDeviceCaps(hdcInfo, LINECAPS);         // =22X
			//Bit   Meaning
			// 1    Device can do polyline.
			// 4    Device can do wide lines.
			// 5    Device can do styled lines.

		int CurveCaps     =  GetDeviceCaps(hdcInfo, CURVECAPS);        // =0
		// Just Circle

		int RasterCaps    =  GetDeviceCaps(hdcInfo, RASTERCAPS);       // =F99X
				// Raster Capabilities
				// RC_BITBLT           1        		Can do standard BLT.
				// RC_BITMAP64         8       		Device can support >64K bitmap
				// RC_GDI20_OUTPUT     0x0010       has 2.0 output calls
				// RC_DI_BITMAP        0x0080       supports DIB to memory
				// RC_PALETTE          0x0100       supports a palette
				// RC_DIBTODEV         0x0200       supports DIBitsToDevice
				// RC_BIGFONT          0x0400       supports >64K fonts
				// RC_STRETCHBLT       0x0800       supports StretchBlt

		// Following valid only if RC_PALETTE on in RASTERCAPS and
		//	Driver Version >= 3.00
		int ColorRes      =  GetDeviceCaps(hdcInfo, COLORRES);         // =18
						//Actual color resolution of the device in bits per pixel
		int NumReserved   =  GetDeviceCaps(hdcInfo, NUMRESERVED);      // =20
						// Number of reserved entries in the system palette
		int SizePalette   =  GetDeviceCaps(hdcInfo, SIZEPALETTE);      // =256
					  // Number of entries in the system palette

		int ClipCaps      =  GetDeviceCaps(hdcInfo, CLIPCAPS);         // =1
		//1 if the device can clip to a rectangle

		int DriverVersion =  GetDeviceCaps(hdcInfo, DRIVERVERSION);    // =300X
		// 3.00

		int Technology    =  GetDeviceCaps(hdcInfo, TECHNOLOGY);       // =1
		// raster display
		DeleteDC(hdcInfo);
************* */
	}
