text: #include "C_APP.h"
  #include "C_MAIN_VIEW.h"
  #include "C_ICON_TABLE.h"
  #include "C_COLOR_SWATCH.h"
  
  #include "C_SPEED_LIM_SCROLLER.h"
  #include "C_NET_QTABLE.h"
  #include "C_PI_PARENTS_TABLE.h"
  #include "C_PI_AMPS_TABLE.h"
  
  #include "C_ND_PROBS_TABLE.h"
  
  #include "C_BI_ND_PROBS_WIND.h"
  #include "C_BI_ND_PROBS_TABLE.h"
  #include "C_MARGINED_SCROLLER.h"
  #include "C_BI_ND_PROBS_MARGIN.h"
  
  #include "C_PROJECT_MENU.h"
  
  #include "C_SG_MAGNET_TABLE.h"
  
  #include "C_KEYS.h"
  
  #include "EXCEPTIONS.h"
  
  #include <MacMemory.h>
  #include <LDebugMenuAttachment.h>
  
  SHORT		C_APP::its_res_file_ref_num;
  
  #pragma mark --creation/destruction--
  //******************************************
  C_APP::C_APP()
  {
  //	register pane classes	
  //	RegisterAllPPClasses();
  	RegisterClass_(LWindow);
  	RegisterClass_(LScroller);
  	RegisterClass_(LView);
  	RegisterClass_(LCaption);
  	RegisterClass_(LTable);
  	RegisterClass_(LDialogBox);
  	RegisterClass_(LGroupBox);	
  	RegisterClass_(LStdButton);
  //	RegisterClass_(LStdPopupMenu); 
  	RegisterClass_(LStdCheckBox);
  	RegisterClass_(LEditField);
  	RegisterClass_(LPlaceHolder);
  	RegisterClass_(LPrintout);
  	RegisterClass_(LListBox);
  	RegisterClass_(LIconPane);
  	RegisterClass_(LRadioGroup);
  	RegisterClass_(LStdRadioButton);
  	RegisterClass_(LTableView);	
  	RegisterClass_(LPicture);
  	RegisterClass_(LCicnButton);
  	RegisterClass_(LButton);
  	
  	RegisterClass_(LPopupButton);
  	
  	RegisterClassID_(C_MAIN_VIEW, 			'MnVu');
  	
  	RegisterClassID_(C_PALETTE, 			'Ette');
  	RegisterClassID_(C_ICON_TABLE, 			'IcTb');
  	RegisterClassID_(C_COLOR_SWATCH, 		'CoSw');
  
  	RegisterClassID_(C_SPEED_LIM_SCROLLER,	'SLSc');	
  	RegisterClassID_(C_NET_QTABLE, 			'NeQT');	
  
  	RegisterClassID_(C_PI_WIND, 			'PiWi');
  	RegisterClassID_(C_PI_ND_EFIELD, 		'PNEf');
  	RegisterClassID_(C_PI_ND_POPUP, 		'NdPo');
  	RegisterClassID_(C_PI_PARENTS_TABLE, 	'PaTa');
  	RegisterClassID_(C_PI_AMPS_TABLE, 		'AmTa');
  			
  	RegisterClassID_(C_BI_ND_WIND, 			'BiNd');
  	RegisterClassID_(C_BI_ND_LBOX, 			'LiBx');
  	
  	RegisterClassID_(C_ND_PROBS_WIND, 		'NPWi');
  	RegisterClassID_(C_ND_PROBS_TABLE, 		'NPTa');
  	
  	RegisterClassID_(C_BI_ND_PROBS_WIND, 	'BNPW');
  	RegisterClassID_(C_BI_ND_PROBS_TABLE, 	'BNPT');
  	RegisterClassID_(C_MARGINED_SCROLLER, 	'MaSc');
  	RegisterClassID_(C_BI_ND_PROBS_MARGIN, 	'BNPM');
  	
  	RegisterClassID_(C_STORIES_WIND, 		'StoW');
  
  	RegisterClassID_(C_HOST_VIEW, 			'HoVu');	
  	RegisterClassID_(C_SG_MAGNET_TABLE, 	'SGTa');
  	
  	//see 
  	//"Appearance Notes" and 
  	//"How to use PP AppMgr Classes"
  	//in Release Notes for PP
  	UControlRegistry::RegisterClassicControls();//needed for LPopupButton
  
  #if _do_debug
  	its_debug_attachment_p = 0;
  #endif	
  }
  //******************************************
  VOID	C_APP::Initialize()
  {
  	//This method is always called when C_APP is created;
  	//It's like a FinishCreateSelf.
  
  	//The method LApplication::Initialize() is empty.
  
  	//according to John Daub:
  	//We flush any pending events.
  	//Without this, if you launch your app,
  	//and then immediately hit a menu key combination to open
  	//a window, there may be a crash.
  	::FlushEvents(everyEvent, nil);
  #if _do_debug
  	//build the debug menu
  	its_debug_attachment_p = new LDebugMenuAttachment();
  	//delete:
  	ThrowIfNil_(its_debug_attachment_p);
  	AddAttachment(its_debug_attachment_p);
  #endif
  
  
  	//From CMenusApp.cp:
  	//Initialize the text-related menus.
  	//These classes & functions are defined in
  	//UTextMenus.cp. The BOOLEAN parameter specifies
  	//whether the menu is initially enabled.
  	UFontMenu::Initialize(true);
  	USizeMenu::Initialize(kDefaultReservedItems, true);
  	C_PROJECT_MENU::init();
  	
  	 
  	its_res_file_ref_num = ::CurResFile();
  	
  	USHORT vers_rid = 1;
  	::UseResFile(its_res_file_ref_num);
  	VersRecHndl  app_vers_h = (VersRecHndl)::Get1Resource('vers', vers_rid);
  	//create_h: 	This creates the memory for app_vers_h
  	//throwif_h:	I throwif below
  	//destroy_h:	in this method
  	ThrowIfResFail_(app_vers_h);
  	NumVersion	num_vers = (**app_vers_h).numericVersion;
  	SignalIf_(k_vers_app !=  *(SInt32 *)(&num_vers));
  	ReleaseResource_((Handle)app_vers_h);
  /*
  //Snippet from CDebugApp.cp
  const	SInt32	kAppVersion			=	0x01008000; // 1.0.0, fin, release0
  	// check the version
  	{
  		StResource versH('vers', 1);
  		SInt32 theVers = *((SInt32*)(*versH));
  		if ( kAppVersion != theVers ) {
  			SignalPStr_("\pVersions don't match");
  		}
  	}
  */	
  	 
  	//Without the next step, the computer crashes if I try to start the
  	// application by double clicking on a 'QNet' file
  	its_palette_p = 0;
  
  }
  //******************************************
  VOID C_APP::StartUp()
  {  
  //This method is NOT always called when C_APP is created. It's called only when the app 
  //receives an open app event, but not when it receives an open doc event.
  
  //MUST enable (appl-is-high-level-event-aware) flag for Startup() to be called!!!! 
  
  /*	
  	// show splash 	
  
  	WindowPtr	splash_window_p = ::GetNewWindow(splash_window_rid, 0, (WindowPtr)-1);
  	::SetPort(splash_window_p);
  	::ShowWindow(splash_window_p); //disposed at the end
  	   
  	PicHandle	splash_pict_h = ::GetPicture(splash_pict_rid);
  	//destroy_h: in this method
  	ThrowIfNil_(splash_pict_h);
  	Rect 	my_rect;
  	::SetRect(&my_rect, 0, 0, 100, 100);
  	::DrawPicture(splash_pict_h, &my_rect);
  	ReleaseResource_((Handle)splash_pict_h);
  	
  	
  	//play sound
  	long 			sound_volume;	
  	::GetDefaultOutputVolume(& sound_volume );
  	::SetDefaultOutputVolume(5);
  	
  	SndListHandle	sound_h = (SndListHandle)::GetResource('snd ', fog_horn_rid);
  	//destroy_h: in this method
  	ThrowIfResFail_(sound_h!=0);
  	ThrowIfOSErr_(::SndPlay(0, sound_h, true));
  	ReleaseResource_((Handle)sound_h);
  	
  	::SetDefaultOutputVolume(sound_volume);
  
  	
  	while (!::Button()){
  	}
  	 
  	//dispose of splash  
  	::HideWindow(splash_window_p);
  	::DisposeWindow(splash_window_p);
  	::FlushEvents(everyEvent, 0);
  */
  	
  	create_pal();
  	
  	ProcessCommand(cmd_New, 0);
  	
  }
  #pragma mark --exception catcher--
  //******************************************
  VOID	C_APP::CatchExceptionCode(
  ExceptionCode	inError)	//in
  {
  #if		_do_debug
  	//PP definition
  	LStr255	msg("\pException caught in LApplication. Error Code: ");
  	msg += inError;
  	SignalPStr_(msg);
  #else
  	my_gen_alert("Quantum Fog is behaving unexpectedly. We suggest that you save your work immediately. Then quit Quantum Fog and restart it.");
  #endif
  }
  
  #pragma mark --palette--
  //******************************************
  VOID C_APP::create_pal() //pal = palette
  {
  
  	its_palette_p = (C_PALETTE  *)LWindow::CreateWindow(pal_rid, this);//SuperCommander declared
  	C_DOC  *  doc_p = get_ptr_to_doc_on_duty();
  	if(doc_p!=0)doc_p->get_mview_ptr()->get_pal_bds_reco().change_wind(its_palette_p);
  	C_ICON_TABLE  *		icon_table_p =
  		(C_ICON_TABLE  *)(its_palette_p->FindPaneByID(pal_icon_table_rid));
  	
  	TableCellT   init_sel_cell;
  	init_sel_cell.row = 1;
  	init_sel_cell.col = 1;
  	icon_table_p->SelectCell(init_sel_cell);
  	its_palette_p->Show();//necessary!	
  
  	//This is an LCommander inline that just changes the needs-update data member.
  	//It does not itself do the menu updating.
  	LCommander::SetUpdateCommandStatus( true );	
  
  	
  }
  //******************************************
  VOID  C_APP::finish_palette_closing()
  { 
  	C_DOC  *  doc_p = get_ptr_to_doc_on_duty();
  	if(doc_p!=0)doc_p->get_mview_ptr()->set_pal_bds_reco();
  	its_palette_p = 0;
  	//This is an LCommander inline that just changes the needs-update data member.
  	//It does not itself do the menu updating.	
  	LCommander::SetUpdateCommandStatus( true );	
  
  }
  #pragma mark --about box--
  //******************************************
  VOID	C_APP::ShowAboutBox()
  {
  
  	//See UModalDialogs::AskForOneNumber
  	//ata = about this application
  	StDialogHandler		d_handler( ata_window_rid, this );//SuperCommander declared
  	
  	LWindow	 * 	dialog_p = d_handler.GetDialog();
  //	LStdButton  *  fog_horn_but_p = (LStdButton  *)dialog_p->FindPaneByID(ata_fog_horn_but_rid);
  
  
  
  	if ( dialog_p!=0) {
  	
  		while ( true ) {
  			MessageT	hit_message = d_handler.DoDialog();
  			switch(hit_message){
  				case msg_ata_fog_horn_but:
  //					long  saved_sound_volume;
  //					::GetDefaultOutputVolume(& saved_sound_volume );
  //					::SetDefaultOutputVolume(5);
  					SndListHandle	sound_h = (SndListHandle)::Get1Resource('snd ', fog_horn_snd_rid);
  					//destroy_h: in this method
  					ThrowIfNil_(sound_h);
  					if(sound_h!=0){						
  						ThrowIfOSErr_(::SndPlay(0, sound_h, false));
  						ReleaseResource_((Handle)sound_h);					
  					}
  //					::SetDefaultOutputVolume(saved_sound_volume);
  					//don't return yet
  					break;			
  				case msg_OK:
  					//LPicture allocates the PICT handle with a call to GetResource() but
  					//it does not have a destructor that releases the PICT handle
  					Handle  pict_h = ::GetResource('PICT', 128);
  					//destroy_h: in this method
  					ThrowIfResFail_(pict_h);
  					ReleaseResource_(pict_h);
  					return;			
  					break;
  			}
  		}
  	}
  	
  }
  #pragma mark --docs--
  //******************************************
  C_DOC  * 	C_APP::get_ptr_to_doc_on_duty()
  {
  	//returns nil if there is no doc on duty
  	LArrayIterator	iterator(LDocument::GetDocumentList(), LArrayIterator::from_Start);
    	C_DOC  *  doc_p = 0;
     	while (iterator.Next(&doc_p)) {
  		if(doc_p->IsOnDuty())break;
  	}
  	return doc_p;
  }		 
  //******************************************
  // one of the steps of ChooseDocument() below:
  
  VOID 	C_APP::OpenDocument(
  FSSpec  * inMacFSSpec)		//in
  {
  /*
     LArrayIterator iterator(LDocument::GetDocumentList(), LArrayIterator::from_Start);
     C_DOC  *  doc_p = 0;
     LFile  *  file_p = 0;
     FSSpec	fs_spec;
     while (iterator.Next(&doc_p)) {
     		file_p = doc_p->GetFile();
     		if(file_p != 0){
  	   		file_p->GetSpecifier(fs_spec);
  	      	if(LFile::EqualFileSpec(*inMacFSSpec, fs_spec)){ 
  	      		(doc_p->GetWindow())->Select();
  	      		return;
  	      	}
        	}
  	}
  	
  	new C_DOC(this, inMacFSSpec);
  */
  	
  	LDocument	*	doc_p = LDocument::FindByFileSpec(*inMacFSSpec);	
  	if (doc_p != 0) {				
  		doc_p->MakeCurrent();			
  	} else {
  		doc_p = new C_DOC(this, inMacFSSpec);
  		//delete:	PP deletes it in LDocument::Close() and LDocument::AttemptQuitSelf()
  		ThrowIfNil_(doc_p);
  	}
  
  }
  //******************************************
  VOID	C_APP::ChooseDocument()
  {
  	UNavServicesDialogs::LFileChooser	chooser;
  	
  	if (chooser.AskOpenFile(PP_PowerPlant::LFileTypeList(my_file_type_id))) {
  		AEDescList		doc_list;
  		chooser.GetFileDescList(doc_list);
  		OpenOrPrintDocList(doc_list, PP_PowerPlant::ae_OpenDoc);
  	}
  }
  #pragma mark --command center--
  //******************************************
  BOOLEAN		C_APP::ObeyCommand(
  CommandT	inCommand,	//in
  VOID * 		ioParam)	//i-o
  {
  	//MONITOR_THE_CHANGE_HERE
  	//doc: no change
  	
  	BOOLEAN				obeyed = true;
  
  	ResIDT				menuID;
  	SInt16				menuItem;
  
  
  	if (IsSyntheticCommand(inCommand, menuID, menuItem)) {
  		if (menuID == project_menu_rid) {
  			C_DOC  *  doc_p = C_PROJECT_MENU::menu_item_to_doc_ptr( menuItem );
  			(doc_p->GetWindow())->Select();
  		}else{
  			obeyed = LDocApplication::ObeyCommand(inCommand, ioParam);
  		}
  		
  	}else{
  		switch (inCommand) {
  			case cmd_choose_color:
  				Point		pt = {-1,-1};
  				RGBColor	new_color;
  				RGBColor	cur_color = its_palette_p->get_cur_color();
  				Str255 	pstr="\ptop(bot.)half =new(old)color";
  				UDesktop::Deactivate();
  				if ( ::GetColor( pt, pstr, &cur_color, &new_color ) ) {
  					set_cur_color(new_color);
  				}
  				UDesktop::Activate();
  				break;
  			case cmd_show_palette:
  				if(its_palette_p==0){
  					LCommander  *  saved_target_p = LCommander::GetTarget();
  					create_pal();
  					LCommander::SwitchTarget(saved_target_p);
  				}else{
  					if(C_KEYS::KeyIsDown(0X3A)){ //option_key=0x3A
  						C_WIND_BDS_RECO  bds_reco;
  						bds_reco.move_to_top_right_corner_of_screen(its_palette_p);
  						C_DOC  *  doc_p = get_ptr_to_doc_on_duty();
  						if(doc_p!=0)doc_p->get_mview_ptr()->set_pal_bds_reco();
  					}
  					its_palette_p->Select();			
  				}
  				break;
  			case cmd_close_all_non_main_winds:// continues process started by C_MAIN_VIEW
  /*				
  				if(its_palette_p!=0){			
  					its_palette_p->ProcessCommand(cmd_Close);			
  					finish_palette_closing();
  				}
  */
  				break;
  			default:
  				obeyed = LDocApplication::ObeyCommand(inCommand, ioParam);
  				break;
  		}
  	}
  	
  	return obeyed;
  }
  //******************************************
  VOID 	C_APP::FindCommandStatus(
  CommandT		inCommand,		//in
  BOOLEAN		&	outEnabled,		//out
  BOOLEAN		&	outUsesMark,	//out
  UInt16		&	outMark,		//out
  Str255			outName_pstr)	//out
  {
  	outEnabled = false;
  	outUsesMark = false;
  	outMark = noMark;
  
  	ResIDT	menuID;
  	SInt16	menuItem;
  
  	if (IsSyntheticCommand(inCommand, menuID, menuItem)) {
  		if (menuID == project_menu_rid) {
  			C_DOC  *  doc_p = C_PROJECT_MENU::menu_item_to_doc_ptr( menuItem );
  			outEnabled = true;
  			outUsesMark = true;
  			//doc_p may be zero
  			if ( doc_p!=0 && doc_p->IsOnDuty() ) {
  				outMark = checkMark;
  			}			
  		}else if (menuID == MENU_Font && menuItem == 0){
  			//This is called only if there is is no mview.
  			//In such a case,  then the app handles the font and size menus.
  			//All their items should be disabled, because they apply to nothing.
  			UFontMenu::DisableEveryItem();
  		}else if (menuID == MENU_Size && menuItem == 0){
  			USizeMenu::DisableEveryItem();
  		}else{
  			LDocApplication::FindCommandStatus(inCommand, outEnabled, 
  												outUsesMark, outMark, outName_pstr);
  		}
  	} else {
  		switch (inCommand) {
  			case cmd_active_project:
  				//This is very necessary, or else project menu always disabled.
  				outEnabled = true; 
  				break;
  			case cmd_choose_color:
  				if(its_palette_p!=0)outEnabled = true;
  				break;
  			case cmd_show_palette:
  				outEnabled = true;
  				if ( its_palette_p==0 ) {
  					LString::CopyPStr( "\pOpen Palette", outName_pstr );
  				} else {
  					LString::CopyPStr( "\pSELECT Palette", outName_pstr );
  				}		
  				break;
  			default:
  				LDocApplication::FindCommandStatus(inCommand, outEnabled,
  													outUsesMark, outMark, outName_pstr);
  				break;
  		}
  	}
  }		