/******************************************************************************
**
**  Project Name:	DropShell
**     File Name:	DropShell.c
**
**   Description:	Main application code for the QuickShell
**
*******************************************************************************
**                       A U T H O R   I D E N T I T Y
*******************************************************************************
**
**	Initials	Name
**	--------	-----------------------------------------------
**	LDR			Leonard Rosenthol
**	MTC			Marshall Clow
**	SCS			Stephan Somogyi
**
*******************************************************************************
**                      R E V I S I O N   H I S T O R Y
*******************************************************************************
**
**	  Date		Author	Description
**	---------	------	---------------------------------------------
**	23 Jun	94	LDR		Implemented support for disk insertion events
**	02 Feb	94	LDR		Updated for Final SDK & CodeWarrior a2
**						Removed the ResumeProc as per new Apple recommendations
**	11 Dec 93	SCS		Universal Headers/UPPs (Phoenix 68k/PPC & PPCC)
**						Skipped System 6 compatible rev of DropShell source
**	09 Dec 91	LDR		Added support for new "Select FileÉ" menu item
**						Quit now sends AEVT to self to be politically correct
**						Added support for the new gSplashScreen
**	24 Nov 91	LDR		Added support for the Apple Menu (duh!)
**	29 Oct 91	SCS		Changes for THINK C 5
**	28 Oct 91	LDR		Officially renamed DropShell (from QuickShell)
**						Added a bunch of comments for clarification
**	06 Oct 91	MTC		Converted to MPW C
**	09 Apr 91	LDR		Added to Projector
**
******************************************************************************/

#ifndef __MWERKS__
#include <Desk.h>
#include <Dialogs.h>
#include <Errors.h>
#include <Files.h>
#include <Fonts.h>
#include <Memory.h>
#include <Menus.h>
#include <StandardFile.h>
#include <TextEdit.h>
#include <Types.h>
#include <Windows.h>
#endif

#include "CWindow.h"
#include "DSGlobals.h"
#include "DSUserProcs.h"
#include "DSAppleEvents.h"

#include "DropShell.h"

#include "ADFS_Menus.h"


Boolean		gDone, gOApped, gHasAppleEvents, gWasEvent;
EventRecord	gEvent;
MenuHandle	gAppleMenu, gFileMenu;
WindowPtr	gSplashScreen;

#ifdef MPW
extern void _DataInit();	
#endif


#pragma segment Initialize
void InitToolbox (void) 
{

#ifdef MPW
	UnloadSeg ((Ptr) _DataInit );
#endif

	InitGraf ( &qd.thePort );
	InitFonts ();
	InitWindows ();
	InitMenus ();
	TEInit ();
	InitDialogs (0L);		// use of ResumeProcs no longer approved by Apple
	InitCursor ();
	FlushEvents ( everyEvent, 0 );
	
	// how about some memory fun! Two should be enough!
	MoreMasters ();
	MoreMasters ();
	}

/*
	Let's setup those global variables that the DropShell uses.
	
	If you add any globals for your own use,
	init them in the InitUserGlobals routine in DSUserProcs.c
*/
#pragma segment Initialize
Boolean InitGlobals (void) 
{
	long aLong;

	gDone			= false;
	gOApped			= false;	// probably not since users are supposed to DROP things!
	gHasAppleEvents	= Gestalt ( gestaltAppleEventsAttr, &aLong ) == noErr;
	gSplashScreen	= NULL;

	return(InitUserGlobals());	// call the user proc
}

/*
	Again, nothing fancy.  Just setting up the menus.
	
	If you add any menus to your DropBox - insert them here!
*/
#pragma segment Initialize
void SetUpMenus (void) {

	gAppleMenu = GetMenu ( kAppleNum );
	AddResMenu ( gAppleMenu, 'DRVR' );
	InsertMenu ( gAppleMenu, 0 );

	gFileMenu = GetMenu ( kFileNum );
	InsertMenu ( gFileMenu, 0 );

	InsertMenu(GetMenu(kEditMenu), 0);
	InsertMenu(GetMenu(kViewMenu), 0);
	DrawMenuBar ();
}

/*
	This routine is called during startup to display a splash screen.
	
	This was recommend by the Blue Team HI person, John Sullivan, who
	feels that all apps should display something so that users can easily
	tell what is running, and be able to switch by clicking.  Thanks John!
*/
#pragma segment Initialize
void InstallSplashScreen(void) 
{
	#define windowPicID	128


/*
	PicHandle	picH;

	if (!gSplashScreen) {  // show the splash screen window
		picH = GetPicture(windowPicID);
		if (picH) {
			gSplashScreen = GetNewWindow(windowPicID, NULL, (WindowPtr)-1L);
			if (gSplashScreen) {
				SetWindowPic(gSplashScreen, picH);
				// Don't show it here, since we only want to it for oapp launches!
				// ShowWindow(gSplashScreen);
			}
		}
	}
*/
}


/*	--------------- Standard Event Handling routines ---------------------- */
#pragma segment Main
void ShowAbout () {
	(void) Alert ( 128, NULL );
	}


#pragma segment Main

static	void	DoAppleMenu(short menuChoice)
{
	if ( menuChoice == 1 )
		ShowAbout ();	/*	Show the about box */
	else {
		Str255	itemStr;
		
		GetItem(GetMHandle(kAppleNum), menuChoice, itemStr);
		OpenDeskAcc(itemStr);
	}
}

static	void	DoFileMenu(short menuChoice)
{
	switch (menuChoice) {

		case kFileNew: {
			break;
		}

		case kFileOpen: {
			SelectFile();		// call file selection userProc
			break;
		}

		case kFileClose: {
			break;
		}

		case kFileGetInfo: {
			break;
		}

		case kFileDuplicate: {
			break;
		}

		case kFilePutAway: {
			break;
		}

		case kFileQuit: {
			SendQuitToSelf();	// send self a 'quit' event
			break;
		}
	}
}

static	void	DoEditMenu(short menuChoice)
{
}

static	void	DoViewMenu(short menuChoice)
{
}

CWindow		*GetCWin(WindowRef windowRef)
{
	CWindow		*window	= NULL;

	if (windowRef) {
		window = (CWindow *)GetWRefCon(windowRef);

		if (window && window->i_magic != kCWindowMagic) {
			window = NULL;
		}
	}

	return window;
}

static	void	UpdateMenus(void)
{
	CWindow		*window;
	WindowRef	windowRef = LMGetWindowList();

	do {
		if (window = GetCWin(windowRef)) {
			window->UpdateMenus();
		}
		windowRef = GetNextWindow(windowRef);
	} while (windowRef);
}


static	Boolean	DoCommand(long command)
{
	CWindow		*window;
	WindowRef	windowRef = LMGetWindowList();

	while (windowRef) {
		if (window = GetCWin(windowRef)) {
			if (window->DoCommand(command)) {
				return TRUE;
			}
		}
		windowRef = GetNextWindow(windowRef);
	};

	return FALSE;
}

void DoMenu ( long retVal ) 
{
	if (!DoCommand(retVal)) {
		short	menuID, itemID;

		menuID = HiWord ( retVal );
		itemID = LoWord ( retVal );
		
		switch ( menuID ) {

			case kAppleMenu:
				DoAppleMenu(itemID);
				break;
				
			case kFileMenu:
				DoFileMenu(itemID);
				break;

			case kEditMenu:
				DoEditMenu(itemID);
				break;

			case kViewMenu:
				DoViewMenu(itemID);
				break;
		}
	}

	HiliteMenu(0);		// turn it off!
}

CWindow		*GetCWin(WindowRef windowRef)
{
	CWindow		*window = (CWindow *)GetWRefCon(windowRef);

	if (window && window->i_magic != kCWindowMagic) {
		window = NULL;
	}

	return window;
}

static	void	UpdateMenus(void)
{
	CWindow		*window;
	WindowRef	windowRef = LMGetWindowList();

	do {
		if (window = GetCWin(windowRef)) {
			window->UpdateMenus();
		}
		windowRef = GetNextWindow(windowRef);
	} while (windowRef);
}

static	void	DoWindowClick(WindowRef windowRef, EventRecord *curEvent)
{
	CWindow		*window = GetCWin(windowRef);
	
	if (window) {
		window->DoClick(event);
	}
}

#pragma segment Main
void DoMouseDown (EventRecord *event)
{
	WindowPtr	whichWindow;
	short		whichPart;
	CWindow		*window;

	whichPart	= FindWindow ( event->where, &whichWindow );
	window		= GetCWin(whichWindow);
	
	if (window) {

		switch (whichPart) {

			case inContent: {
				window->DoClick(event);
				break;
			}

			case inDrag: {
				window->Move(event);
				break;
			}

			case inGrow: {
				window->Size(event);
				break;
			}
			
			case inGoAway: {
				window->TrackGoAway(event);
				break;
			}
			
			case inZoomIn:
			case inZoomOut: {
				window->Zoom(event, whichPart);
				break;
			}
		}		
	} else {
	}	

	switch (whichPart) {
		//	case inDesk: defunct

		case inMenuBar:
			UpdateMenus();
			DoMenu ( MenuSelect ( curEvent->where ));
			break;
		
		case inSysWindow:
			SystemClick ( curEvent, whichWindow );
			break;
		
		case inDrag: {
			Rect	boundsRect = (*GetGrayRgn())->rgnBBox;
		
			DragWindow ( whichWindow, curEvent->where, &boundsRect );
			break;
		}

		case inGrow: {
			break;
		}
	}
}

#pragma segment Main
void DoKeyDown ( EventRecord *curEvent )
{
	if ( curEvent->modifiers & cmdKey ) {
		UpdateMenus();
		DoMenu ( MenuKey ((char) curEvent->message & charCodeMask ));
	} else {
		WindowRef	frontWind = FrontWindow();

		if (frontWind) {
			CWindow		*window = GetCWin(frontWind);
			
			if (window) {
				window->DoKeyDown(curEvent);
			}
		}
	}
}



#pragma segment Main
void main ( ) 
{

	InitToolbox ();
	if ( InitGlobals () ) {	// if we succeeding in initting self
		if ( !gHasAppleEvents )
			ErrorAlert ( kErrStringID, kCantRunErr, 0 );
		else {
			InitAEVTStuff ();
			SetUpMenus ();
			InstallSplashScreen ();
			
			while ( !gDone ) {
				gWasEvent = WaitNextEvent ( everyEvent, &gEvent, 0, NULL );
				if ( gWasEvent ) {
					switch ( gEvent.what ) {
						case kHighLevelEvent:
							DoHighLevelEvent ( &gEvent );
							break;
							
						case mouseDown:
							DoMouseDown ( &gEvent );
							break;
							
						case keyDown:
						case autoKey:
							DoKeyDown ( &gEvent );
							break;
						
						case activateEvt: {
							WindowRef	windowRef	= (WindowRef)theEvent->message;
							CWindow		window		= *GetCWin(windowRef);
							
							if (window) {
								window->ReActivate((theEvent->modifiers & activeFlag) != 0
							}
							break;
						}

						case diskEvt:
							if (HiWord(gEvent.message)) {
								Point diskInitPt;
								
								diskInitPt.v = diskInitPt.h = 100;
								DILoad();
								DIBadMount(diskInitPt, gEvent.message);
								DIUnload();
							}
							break;
							
						default:
							break;
					}
				}
			}
		}
		DisposeUserGlobals();	// call the userproc to clean itself up
	}
}
