/*	XGAppSingleWindow.cpp
 *
 *		This creates a single-window application.
 */

/*  YAAF - Yet another application framework
 *  Copyright (C) 1997, 1998 William Edward Woody
 *  
 *  This library is free software; you can redistribute it
 *  and/or modify it under the terms of the GNU Library
 *  General Public License as published by the Free Software
 *  Foundation; either version 2 of the License, or any
 *  later version.
 *  
 *  This library is distributed in the hope that it will be
 *  useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABIILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE. See the GNU Library General Public License for
 *  more details.
 *  
 *  You should have received a copy of the GNU Library General
 *  Public License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 *  
 *  To contact the author, either e-mail me at woody@pandawave.com, 
 *	or write to
 *  
 *          William Edward Woody
 *          In Phase Consulting
 *          1545 Ard Eevin Avenue
 *          Glendale, CA 91202
 *
 *	Or visit us on the web at http://www.pandawave.com
 */

#include <XConfig.h>			// must be first to optimize compile on MSVC++
#include <XWindow.h>
#include <XMenu.h>
#include <XError.h>
#include <XApplication.h>
#include <XMessages.h>
#include <XAppMenu.h>

/************************************************************************/
/*																		*/
/*	Construction/Destruction											*/
/*																		*/
/************************************************************************/

// @G"Construction/Destruction"

/*	@F"XGAppSingleWindow::XGAppSingleWindow" @I
 *
 *		Create me
 */

XGAppSingleWindow::XGAppSingleWindow()
{
	fMyWindow = NULL;
	fMyMenuBar = NULL;

#if OPT_WINOS == 1
	_GMainWindow = NULL;
	_GMDIWindow = NULL;				/* Make sure this is clear */
	if (_GPrevInstance == NULL) InitApplication();
	InitInstance();					/* Start up instance */
#endif

	XGBroadcast::AddBroadcast(this);
}

/*	@F"XGAppSingleWindow:::~XGAppSingleWindow" @I
 *
 *		Delete me
 */

XGAppSingleWindow::~XGAppSingleWindow()
{
	if (fMyWindow) delete fMyWindow;
	if (fMyMenuBar) delete fMyMenuBar;
}

/************************************************************************/
/*																		*/
/*	Construction/Destruction											*/
/*																		*/
/************************************************************************/

// @G"Event Processing"

/*	@F"XGAppSingleWindow::Run" @I
 *
 *		This verifies that a window was in fact created. If not, this
 *	complains and quits
 */

void XGAppSingleWindow::Run(void)
{
	if (fMyWindow == NULL) throw XGPostError(KXGSingleAppError);
	XGAppCore::Run();
}

/************************************************************************/
/*																		*/
/*	Event Dispatch														*/
/*																		*/
/************************************************************************/

/*
 *	Dispatch table
 */

BEGINDISPATCH(XGAppSingleWindow,XGAppCore)
	DISPATCHTABLE(KXGEventWindowCreate,XGAppSingleWindow::DoWindowCreate)
	DISPATCHTABLE(KXGEventWindowDestroy,XGAppSingleWindow::DoWindowDestroy)
	DISPATCHTABLE(KXGAppPostEvent,XGAppSingleWindow::DoPostPeriodic)
ENDDISPATCH

/*	XGAppSingleWindow::DoWindowCreate
 *
 *		Handle the window create event
 */

long XGAppSingleWindow::DoWindowCreate(long, void *parg)
{
	XGWindow *w;
	int menuID;
	
	w = ((XGSWindowEvent *)parg)->window;
	if (w->GetWindowKind() != KWinDocument) return -1;

	/*
	 *	Record the creation of this window. We only allow one
	 */
	
	if (fMyWindow) throw XGPostError(KXGSingleAppDupError);
	fMyWindow = w;
	
	/*
	 *	Now that we have a window, initialize the menu bar
	 *	that is associated with this menu
	 */
	
#if OPT_MACOS == 1
	fMyMenuBar = new XGMenuBar();
#endif

#if OPT_WINOS == 1
	_GMainWindow = w->GetHWND();
	fMyMenuBar = new XGMenuBar(_GMainWindow,false);
#endif

#if OPT_XWIN == 1
	fMyMenuBar = new XGMenuBar(w->GetWindow());
	w->SetMenuBar(fMyMenuBar);
#endif
			
	menuID = GetCurFocus()->SendDispatch(KXGCurMenuBar,0,NULL);
	Assert(menuID != -1);
	if (menuID == 0) menuID = KXGDefaultMenu;
	fMyMenuBar->LoadFromResource(menuID);
	return -1;
}

/*	XGAppSingleWindow::DoWindowDestroy
 *
 *		Handle the window destruction event
 */

long XGAppSingleWindow::DoWindowDestroy(long, void *parg)
{
	XGWindow *w;
	
	w = ((XGSWindowEvent *)parg)->window;
	if (w->GetWindowKind() != KWinDocument) return -1;

	/* 
	 *  Record destruction of this window. Quit if it's mine 
	 */
	
	if (fMyWindow == w) {
		fMyWindow = NULL;

#if OPT_WINOS == 1
		_GMainWindow = NULL;
#endif
		GetCurFocus()->SendDispatch(KXGQuitApplication,0,NULL);
	}
	return -1;
}

/*	XGAppSingleWindow::DoPostPeriodic
 *
 *		Process postperiodic event to update menu bar
 */

long XGAppSingleWindow::DoPostPeriodic(long, void *)
{
	int menuID;
	bool f;
	
	/*
	 *	Update the menu bar
	 */
	
	if ((fMyMenuBar != NULL) && (fMyWindow != NULL)) {
		menuID = GetCurFocus()->SendDispatch(KXGCurMenuBar,0,NULL);
		if (menuID == -1) return 0;
		if (menuID == 0) menuID = KXGDefaultMenu;

		f = fMyMenuBar->LoadFromResource(menuID);
		fEventOwner = fMyWindow;
		fMyMenuBar->UpdateMenuBar(fMyWindow);
		fEventOwner = NULL;
		
#if OPT_XWIN
		if (f) fMyWindow->RedrawMenuBar();
#endif
	}
	return 0;
}

/************************************************************************/
/*																		*/
/*	Construction/Destruction											*/
/*																		*/
/************************************************************************/

/*	XGAppSingleWindow::GetCurMenu
 *
 *		The current menu for this single window application
 */

XGMenuBar *XGAppSingleWindow::GetCurMenu()
{
	return fMyMenuBar;
}

/*	XGAppSingleWindow::GetCurFocus
 *
 *		The current menu for this single window application
 */

XGFocus *XGAppSingleWindow::GetCurFocus()
{
	if (fModalWindow) return fModalWindow;
	if (fMyWindow) return fMyWindow;
	return this;
}

/************************************************************************/
/*																		*/
/*	Windows initialization support										*/
/*																		*/
/************************************************************************/

#if OPT_WINOS == 1

/*	XGAppSingleWinodw::InitApplication
 *
 *		Register the classes which are in me
 */

void XGAppSingleWindow::InitApplication(void)
{
	static bool gInit = false;
	WNDCLASSEX wc;
	
	if (gInit) return;					// run this only once.
	gInit = true;
	
	/*
	 *	Initialize three instances: a class of class name "_XGWindow"
	 *	and a class of class name "_XGView", and "_XGDialog"
	 */
	
	wc.cbSize = sizeof(wc);
	wc.style = CS_DBLCLKS;
	wc.lpfnWndProc = _GSingleWindowProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = _GInstance;
	wc.hIcon = (HICON)LoadImage(_GInstance,"AppIcon",IMAGE_ICON,32,32,LR_SHARED);;
	wc.hCursor = NULL;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = _GWindowClass;
	wc.hIconSm = (HICON)LoadImage(_GInstance,"AppIconSmall",IMAGE_ICON,16,16,LR_SHARED);
	Assert(RegisterClassEx(&wc));
	
	wc.cbSize = sizeof(wc);
	wc.style = CS_DBLCLKS;
	wc.lpfnWndProc = _GSingleWindowProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = _GInstance;
	wc.hIcon = (HICON)LoadImage(_GInstance,"AppIcon",IMAGE_ICON,32,32,LR_SHARED);;
	wc.hCursor = NULL;
	wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = _GDlogClass;
	wc.hIconSm = (HICON)LoadImage(_GInstance,"AppIconSmall",IMAGE_ICON,16,16,LR_SHARED);
	Assert(RegisterClassEx(&wc));
}

/*	XGAppSingleWindow::InitInstance
 *
 *		Initialize the instance of this thing. This does nothing; we assume
 *	the window that is initialized elsewhere will provide me the UI.
 */

void XGAppSingleWindow::InitInstance(void)
{
}


#endif
