
#if GS_MAC_CFM
	#include <Dialogs.h>
	#include <Events.h>
	#include <Quickdraw.h>
	#include <Gestalt.h>
	#include <Sound.h> // for SysBeep()
	#include <QDGlobals.h>
	#include <ToolUtils.h> // for LoWord and HiWord
#endif
#include <UDrawingUtils.h>
#include <UDrawingState.h>
#include <UEnvironment.h>
#include <LStdControl.h>
#include <LListener.h>
#include <PP_Messages.h>

#include "RegisterMyClasses.h"
#include "ScrollingPane.h"
#include "InfoPane.h"
#include "RunDialog.h"
#include "GSString.h"

const short kGrafPortViewPPob = 128;


const short kIDGrafPortView = 1;
const short kIDScroller = 2;
const short kIDListView = 3;
const short kIDDone = 4;
const short kIDInfoGroupBox = 5;
const short kIDInfoPane = 6;
const short kIDZoomPopUp = 7;
const short kIDGrowIconPane = 8;



void MyPPDialog::ListenToMessage(MessageT inMessage, void *)
{
	switch(inMessage) {
		case 'Done': {
			fDone = true;
			break;
		}
	}
}



void MyPPDialog::DoDialog(const Rect& theRect)
{
	WindowPtr theMMWindow;
	GrafPtr savePort;
		
	// we are assuming color for now
	
	long qdVersion = gestaltOriginalQD;
	Gestalt(gestaltQuickdrawVersion, &qdVersion);
	if (qdVersion > gestaltOriginalQD) {
		PStr63 libraryRoutineName = "GetMainDisplayBounds";
		Rect mainDisplayRect = { 0, 0, 0, 0};
		long status = 0;
		
		PluginLibraryArgTable* theArgs = new PluginLibraryArgTable;
		if (VERIFYN(kLyndsey, theArgs)) {
			
			for (int i = 0; i < 4; i++) {
				theArgs->args[i].argType = kIntegerVarArgType;
				theArgs->args[i].intValue = 0;
			}
			
			Boolean wasCalled = GS_CallPluginLibrary(gCBP, libraryRoutineName, theArgs, status);
			if (wasCalled) {
				mainDisplayRect.top 	= theArgs->args[0].intValue;
				mainDisplayRect.left 	= theArgs->args[1].intValue;
				mainDisplayRect.bottom 	= theArgs->args[2].intValue;
				mainDisplayRect.right 	= theArgs->args[3].intValue;
			}
			delete theArgs;
		}
		Rect theScreenBitsBounds = mainDisplayRect;
	
		const Boolean supportsColor = true;
		
		theMMWindow = NewCWindow(nil, &theRect, "\pPowerPlant Sample",
							false, movableDBoxProc, (WindowPtr)-1L, false, 0L);
		
		if (theMMWindow) {
			GetPort(&savePort);
			SetPortWindowPort(theMMWindow);		// Carbon change, was SetPort(theMMWindow);
			
			/* Set up PowerPlant */
			// Carbon change, was UQDGlobals::SetQDGlobals(GetQDGlobalPtr(gCBP));
			UEnvironment::SetFeature(env_SupportsColor, supportsColor);
			
			RegisterMyPPClasses();
			
			
			ShowWindow(theMMWindow);
			
			
			fParentView = LMyGrafPortView::CreateMyGrafPortView(kGrafPortViewPPob, this);
			
			if (fParentView) {
				EventRecord theEvent;
				
				fDone = false;
				fDoneButtonPtr = (LStdButton*) fParentView->FindPaneByID(kIDDone);
				if(fDoneButtonPtr)
					fDoneButtonPtr->AddListener(this);
				else
					DSTOP((kPaul, "fParentView->FindPaneByID(kIDDone) failed!!"));
				
				
				// tell the list view to listen to the zoom menu
				CMCListView* listView = (CMCListView*)fParentView->FindPaneByID(kIDListView);
				LStdPopupMenu* zoomMenu = (LStdPopupMenu*)fParentView->FindPaneByID(kIDZoomPopUp);
				if(listView && zoomMenu) {
					zoomMenu->AddListener(listView);
				}
				else
					DSTOP((kPaul, "listView - %lx  zoomMenu - %lx", listView, zoomMenu));

				// tell the info pane to listen to the list view for mouse tracking
				CMCInfoPane* infoPane = (CMCInfoPane*)fParentView->FindPaneByID(kIDInfoPane);
				if(listView && zoomMenu) {
					listView->AddListener(infoPane);
					listView->StartIdling(); // so it can track the mouse
				}
				else
					DSTOP((kPaul, "listView - %lx  infoPane - %lx", listView, infoPane));
	
				
				fParentView->ResizeFrameTo(theRect.right - theRect.left, theRect.bottom - theRect.top, false);
				fParentView->Activate();
				//fParentView->Draw(nil); //theMMWindow->visRgn

				do {
					if (GetNextEvent(everyEvent, &theEvent)) {
						switch (theEvent.what) {
							short winPart;
							WindowPtr whichWin;
							
							case mouseDown: {
								winPart = FindWindow(theEvent.where, &whichWin);
								switch (winPart) {
									case inDesk:{
										break;
									}
									case inMenuBar:{
										break;
									}
									case inSysWindow:{
										break;
									}
									case inContent:{
										if (whichWin != theMMWindow)
											SysBeep(10);
										else {
											GrafPtr savePort;
											Point localPoint = theEvent.where;
											
											GetPort(&savePort);
											SetPortWindowPort(whichWin);	// Carbon change, was SetPort(whichWin);
											GlobalToLocal(&localPoint);
											SetPort(savePort);
											
											LPane* growIcon = fParentView->FindPaneByID(kIDGrowIconPane);
											if(growIcon && growIcon->PointIsInFrame(localPoint.h, localPoint.v)) {
												Rect	theRect = {200,200,1500,1500};	

												long	newSize = ::GrowWindow(whichWin, theEvent.where, &theRect);

												if (newSize != 0) {
													short width = LoWord(newSize);
													short height = HiWord(newSize);
													
													::SizeWindow(whichWin, width, height, false);
													fParentView->ResizeFrameTo(width, height, true);
												}

												
											}
											else
												fParentView->ClickInContent(theEvent);
											
											//fDone = true; // kludge it until we listen
										}
										break;
									}
									case inDrag:{
										if (whichWin != theMMWindow)
											SysBeep(10);
										else {
											Rect limitRect = theScreenBitsBounds;	//qdp->screenBits.bounds;
											limitRect.top += GetMBarHeight();
											InsetRect(&limitRect, 4, 4);
											DragWindow(whichWin, theEvent.where, &limitRect);
										}
										break;
									}
									

									default:{
										SysBeep(10);
										break;
									}
								}
								
								break;
							}
							case updateEvt: {
								if ((WindowPtr)theEvent.message == theMMWindow)		// Carbon change, was (GrafPtr)
									fParentView->UpdatePort();
								else
									GS_DoUpdateOrActivate(gCBP, theEvent);
								break;
							}
							case activateEvt: {
								
								if ((WindowPtr)theEvent.message == theMMWindow) {	// Carbon change, was (GrafPtr)
									if ((theEvent.modifiers & activeFlag) != 0) {
										fParentView->Activate();
									}
									else {
										fParentView->Deactivate();
									}
								}
								else
									GS_DoUpdateOrActivate(gCBP, theEvent);
								break;
							}
						}
					}
					else {
						// null event
						fParentView->DoIdle(theEvent);
						// here's where we do the mouse tracking
					
					}
				} while (!fDone);
				
				
				if(listView)
					listView->StopIdling();
			}
			
			
			delete fParentView; // this must be done before deleting the theMMWindow
								// upon which it's based 
			SetPort(savePort);
			DisposeWindow(theMMWindow);
		}
	}
	else
		SysBeep(10);
}


//==================================================================
// LMyGrafPortView - this class provides the additional functionality of
// converting from QuickDraw global space.
//==================================================================



LMyGrafPortView* LMyGrafPortView::CreateMyGrafPortView(ResIDT inGrafPortView, LCommander *inSuper)
{
	return (LMyGrafPortView*)LGrafPortView::CreateGrafPortView(inGrafPortView, inSuper);
}
	
	
	
LMyGrafPortView* LMyGrafPortView::CreateMyGrafPortViewStream(LStream *inStream)
{
	return new LMyGrafPortView(inStream);
}



// this is ugly - copied straight from PP code
// need to get rid of this when possible

// ---------------------------------------------------------------------------
//		¥ GlobalToPortPoint
// ---------------------------------------------------------------------------
//	Convert a point from global (screen) coordinates to a Window's Port
//	coordinates

void
LMyGrafPortView::GlobalToPortPoint(
	Point	&ioPoint) const
{
		// Windows have a reference to the pixel image of the main screen--
		// portBits for B&W and portPixMap for color windows. The bounds
		// of the pixel image specify the alignment of the *local* Window
		// coordinates with *global* coordinates:
		//		localPt = globalPt + topLeft(imageBounds)
		//
		// To convert from *local* to *port* coordinates, we offset by
		// the top left of the Window's port rectangle:
		//		portPt = localPt - topLeft(portRect)
		//
		// Therefore,
		//		portPt = globalPt + topLeft(imageBounds) - topLeft(portRect)
		//
		// Note: We don't use the Toolbox routine GlobalToLocal because
		// that routine depends on the current port and the current port
		// origin. To use GlobalToLocal we would have to do the following:
		//		GrafPtr savePort;
		//		GetPort(&savePort);
		//		Point	saveOrigin = topLeft(mMacWindowP->portRect);
		//		SetPort(mMacWindowP);
		//		SetOrigin(0,0);
		//		GlobalToLocal(ioPoint);
		//		SetOrigin(saveOrigin.h, saveOrigin.v);
		//		SetPort(savePort);
		// The equation above avoids all this saving/setting/restoring
		// of the current port and port origin.

	GrafPtr myPort = GetMacPort();
									
	Point	localOffset;
#ifdef COMMENTEDOUT
	if (UDrawingUtils::IsColorGrafPort(myPort)) {
		CGrafPtr	colorPortP = (CGrafPtr) myPort;
		localOffset = topLeft((**(colorPortP->portPixMap)).bounds);
	}
	else
		localOffset = topLeft(myPort->portBits.bounds);

	ioPoint.h += (localOffset.h - myPort->portRect.left);
	ioPoint.v += (localOffset.v - myPort->portRect.top);
#else
	PixMapHandle pixMapHand = GetPortPixMap(myPort);
	Rect pixBounds;
	GetPixBounds(pixMapHand, &pixBounds);	// Rect *GetPixBounds (PixMapHandle pixMap, Rect *bounds);
	localOffset = topLeft(pixBounds);
	
	Rect portBounds;
	GetPortBounds(myPort, &portBounds);

	ioPoint.h += (localOffset.h - portBounds.left);
	ioPoint.v += (localOffset.v - portBounds.top);

#endif
	
}



