/* 
Copyright (c) 1991-2000 UserLand Software, Inc. 

Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the 
"Software"), to deal in the Software without restriction, including 
without limitation the rights to use, copy, modify, merge, publish, 
distribute, sublicense, and/or sell copies of the Software, and to 
permit persons to whom the Software is furnished to do so, subject to the 
following conditions: 

The above copyright notice and this permission notice shall be 
included in all copies or substantial portions of the Software. 

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
*/ 


#include "iowacore.h"
#include <applet.h>
#include <appletmenu.h>
#include <appletmenuops.h>
#include <appletresource.h>
#include <appletmain.h>
#include <appletwindowmenu.h>
#include "iowamenu.h"
#include "iowapack.h"
#include "iowadialogs.h"
#include "iowaobject.h"
#include "iowawindowatts.h"
#include "iowacleanup.h"
#include "iowatestcard.h"
#include "iowafrontier.h"
#include "iowaquickscript.h"
#include "iowainfowindow.h"


#ifdef flstatusbar

	#include "iowastatusbar.h"

#endif



MenuHandle hdldrawmenu = nil;


#define ideditmenu editmenu
#define edittableitem 15


#define drawmenu 			140
#define groupitem 			1
#define ungroupitem 		2
#define alignleftitem 		4
#define alignrightitem 		5
#define aligntopitem 		6
#define alignbottomitem 	7
#define centervertitem		9
#define centerhorizitem		10
#define snaptoitem			12
#define showgriditem		13
#define setgriditem			14
#define cleanupitem			16
#define runcarditem			18

#define firstdrawitem 		groupitem
#define lastdrawitem		runcarditem


MenuHandle hdlobjectmenu = nil;

#define objectmenu			142
#define objectinfoitem		1
#define objectcolorsitem	3
#define recalcinfoitem		4
#define errorinfoitem 		5
#define specialattsitem		7
#define flagitem			9
#define hasframeitem		10
#define transparentitem 	11
#define visibleitem			12
#define enableditem			13
#define autosizeitem		14
#define frontitem			16
#define backitem			17

#define firstobjectitem 		flagitem
#define lastobjectitem			backitem


#define windowattsitem		1 /*we add 2 items at the head of the Window menu*/
#define quickscriptitem		2


typedef struct tyattributesrecord {
	
	boolean firstobject;
	
	bigstring flagnameval;
	
	boolean uniformflagname;
	
	bigstring typenameval;
	
	boolean uniformtypename;
	
	boolean flagval;
	
	boolean uniformflag;
	
	boolean frameval;
	
	boolean uniformframe;
	
	boolean transparentval;
	
	boolean uniformtransparent;
	
	boolean visibleval;
	
	boolean uniformvisible;
	
	boolean enabledval;
	
	boolean uniformenabled;
	
	boolean autosizeval;
	
	boolean uniformautosize;
	
	short shadowval;
	
	boolean uniformshadow;
	} tyattributesrecord;
	
tyattributesrecord atts;
	
	


boolean iowainsertmenus (void) {
	
	installmenu (drawmenu, &hdldrawmenu);

	installmenu (objectmenu, &hdlobjectmenu);

	return (true);
	} /*iowainsertmenus*/
	
	
static void changedobject (hdlobject h) {

	invalobject (h);
	
	madechanges ();
	} /*changedobject*/
	

static boolean setflagvisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objectflag = !atts.flagval;
	
	invalobject (h); /*for correct display of bold buttons becoming not bold*/
	
	(**h).objectflag = !atts.flagval;
	
	changedobject (h);
	
	return (true);
	} /*setflagvisit*/
	
	
static boolean setframevisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objecthasframe = !atts.frameval;
	
	(**h).objecthasframe = !atts.frameval;
	
	changedobject (h);
	
	return (true);
	} /*setframevisit*/
	
	
static boolean settransparentvisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objecthasframe = !atts.transparentval;
	
	(**h).objecttransparent = !atts.transparentval;
	
	changedobject (h);
	
	return (true);
	} /*settransparentvisit*/
	
	
static boolean setvisiblevisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objectvisible = !atts.visibleval;
	
	(**h).objectvisible = !atts.visibleval;
	
	changedobject (h);
	
	return (true);
	} /*setvisiblevisit*/
	
	
static boolean setenabledvisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objectenabled = !atts.enabledval;
	
	(**h).objectenabled = !atts.enabledval;
	
	changedobject (h);
	
	return (true);
	} /*setenabledvisit*/
	
	
static boolean setautosizevisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objectautosize = !atts.autosizeval;
	
	(**h).objectautosize = !atts.autosizeval;
	
	changedobject (h);
	
	return (true);
	} /*setautosizevisit*/
	
	
static boolean setshadowdepthvisit (hdlobject h) {
	
	hdlcard hc = iowadata;
	
	(**hc).defaults.objectdropshadowdepth = atts.shadowval;
	
	invalobject (h); /*in case the drop shadow shrinks*/
	
	(**h).objectdropshadowdepth = atts.shadowval;
	
	changedobject (h);
	
	return (true);
	} /*setshadowdepthvisit*/
	
	
static boolean bringtofrontvisit (hdlobject h) {
	
	makefrontobject (h);
	
	changedobject (h);
	
	return (true);
	} /*bringtofrontvisit*/
	
	
static boolean sendtobackvisit (hdlobject h) {
	
	sendobjecttoback (h);
	
	changedobject (h);
	
	return (true);
	} /*sendtobackvisit*/
	

static void shadowdepthdialog (void) {
	
	bigstring prompt, answer;
	boolean fl;
	long x;
	
	iowagetstring (shadowdepthprompt, prompt);
	
	NumToString (atts.shadowval, answer);
	
	apppostcallback (); 
	
	fl = askdialog (prompt, answer);
		
	appprecallback ();
	
	if (!fl)
		return;
	
	StringToNum (answer, &x);
	
	atts.shadowval = x;
	
	flatvisitselectedobjects (&setshadowdepthvisit);
	} /*shadowdepthdialog*/
	
	
static void setgriddialog (void) {
	
	hdlcard hc = iowadata;
	bigstring prompt, answer;
	boolean fl;
	long x;
	
	iowagetstring (setgridprompt, prompt);
	
	NumToString ((**hc).gridunits, answer);
	
	apppostcallback (); 
	
	fl = askdialog (prompt, answer);
		
	appprecallback ();
	
	if (!fl)
		return;
	
	StringToNum (answer, &x);
	
	(**hc).gridunits = x;
	
	madechanges ();
	
	zapcardwindow ();
	} /*setgriddialog*/
	
	
static boolean saveasappcommand (void) {
	
	/*
	create a 2clickable application out of the card in app.appwindow.
	
	the data fork contains a packed card. the resource fork is a copy of
	the STUB 128 resource in the Card Editor application.
	
	note: we overwrite the resources that saveaswindow puts in the file,
	this isn't a problem for Iowa 1.0, but it may be a problem in the
	future.
	*/
	
	hdlappwindow ha = app.appwindow;
	tyfilespec fs;
	
	getappwindowfilespec (ha, &fs);
		
	if (!sfdialog (true, "\pSave As AppÉ", &fs, app.filefiltercallback, 'APPL'))
		return (false);
	
	/*save packed card in the data fork of the file*/ {
	
		OSType origtype = app.filetype;
		OSType origcreator = app.creator;
		boolean fl;
		
		app.filetype = 'APPL'; app.creator = 'DRPb';
		
		apppostcallback (); /*DW 3/19/93: can do window update*/
		
		updateappwindow (ha);
		
		watchcursor ();
		
		fl = saveaswindow (&fs);
		
		appprecallback ();
		
		app.filetype = origtype; app.creator = origcreator;
		
		if (!fl)
			return (false);
		}
	
	/*copy STUB resource into the resource fork of the file*/ {
	
		Handle h = nil;
		short fnum = 0;
		
		if (!getresourcehandle (0, 'STUB', 128, &h)) {
			
			alertdialog ("\pTell DW that the 'STUB' 128 resource is missing.");
			
			goto error;
			}
			
		if (!fileopenresourcefork (&fs, &fnum)) {
			
			alertdialog ("\pCouldnŐt open the fileŐs resource fork.");
			
			goto error;
			}
		
		if (!filewritehandle (fnum, h)) {
		
			alertdialog ("\pCouldnŐt write to the file.");
			
			goto error;
			}
			
		if (!fileseteof (fnum, gethandlesize (h))) {
			
			alertdialog ("\pCouldnŐt set the fileŐs size.");
			
			goto error;
			}
			
		fileclose (fnum);
		
		disposehandle (h);
	
		return (true);
		
		error:
		
		disposehandle (h);
		
		fileclose (fnum);
		
		filedeletefile (&fs);
		
		return (false);
		}
	} /*saveasappcommand*/
	
	
boolean iowamenu (short idmenu, short iditem) {
	
	hdlcard hc = iowadata;
	
	switch (idmenu) {
		
		#ifdef customizedfilemenu
		
		case filemenu: /*we add a command to this menu, so the itemnumbers change*/
			
			/*DW 2/26/93 -- be careful, things will break if you open or close a window here*/
			
			switch (iditem) {
			
				case saveasappitem:
					saveasappcommand ();
					
					return (true); /*we handled the command*/
				} /*switch*/
			
			return (false); /*the applet toolkit should handle the command*/
		
		#endif
			
		case windowmenu:
			switch (iditem) {
				
				case windowattsitem:
					windowattributesdialog ();
					
					return (true); /*we handled the command*/
					
				case quickscriptitem:
					iowaopenquickscript ();
					
					return (true);
				} /*switch*/
	
			break;
			
		case editmenu:
			switch (iditem) {
				
				case edittableitem: {
					bigstring tablewindowtitle;
					
					getappwindowtitle (app.appwindow, tablewindowtitle);
					
					pushstring ("\p Table", tablewindowtitle);
					
					frontEditTable (tablewindowtitle);
					
					madechanges ();
					
					return (true);
					}
				} /*switch*/
				
			break;
			
		case objectmenu: {
			hdlobject hfirst = (**hc).selectionlist;
			
			switch (iditem) {
				
				case objectinfoitem:
					maininfowindow ();
					
					break;
					
				case objectcolorsitem:
					colorinfowindow ();
					
					break;
					
				case errorinfoitem:
					errorinfowindow ();
					
					break;
					
				case recalcinfoitem:
					recalcinfowindow ();
					
					break;
					
				case specialattsitem:
					iowaSpecialAttsDialog (hfirst);
					
					break;
				
				case flagitem:
					flatvisitselectedobjects (&setflagvisit); 
					
					break;
					
				case hasframeitem:
					flatvisitselectedobjects (&setframevisit); 
					
					break;
					
				case transparentitem:
					flatvisitselectedobjects (&settransparentvisit);
					
					break;
				
				case visibleitem:
					flatvisitselectedobjects (&setvisiblevisit);
					
					break;
				
				case enableditem:
					flatvisitselectedobjects (&setenabledvisit);
					
					break;				
					
				case autosizeitem:
					flatvisitselectedobjects (&setautosizevisit);
					
					break;		
				
				/*
				case shadowdepthitem:
					shadowdepthdialog ();
					
					break;
				*/
					
				case frontitem:
					flatvisitselectedobjects (&bringtofrontvisit);
					
					break;
					
				case backitem:
					flatvisitselectedobjects (&sendtobackvisit);
					
					break;
				} /*switch*/
				
			return (true);
			}
		
		case drawmenu:
			
			switch (iditem) {
				
				case groupitem:
					groupselectedobjects ();
					
					break;
					
				case ungroupitem:
					ungroupselectedobjects ();
					
					break;
					
				case alignleftitem:
					alignselectedobjects (left);
					
					break;
					
				case alignrightitem:
					alignselectedobjects (right);
					
					break;
					
				case aligntopitem:
					alignselectedobjects (up);
					
					break;
					
				case alignbottomitem:
					alignselectedobjects (down);
					
					break;
					
				case centervertitem:
					alignselectedobjects (flatdown);
					
					break;
					
				case centerhorizitem:
					alignselectedobjects (flatup);
					
					break;
					
				case snaptoitem:
					(**hc).flgrid = !(**hc).flgrid;
					
					zapcardwindow ();
					
					madechanges ();
					
					break;
					
				case showgriditem:
					(**hc).flinvisiblegrid = !(**hc).flinvisiblegrid;
					
					zapcardwindow ();
					
					madechanges ();
					
					break;
					
				case setgriditem:
					setgriddialog ();
					
					break;
					
				case cleanupitem: 
					cleanupcommand ();
					
					break;
					
				case runcarditem: 
					testfrontcard ();
					
					break;
				} /*switch*/
				
			return (true); /*we handled the menu selection*/
			
		} /*switch*/
	
	return (false); /*it wasn't one of our menus*/
	} /*iowamenu*/
	

static boolean getobjectattributesvisit (hdlobject h) {
	
	bigstring bs;
	
	if (atts.firstobject) { 
		
		atts.firstobject = false;
		
		atts.flagval = (**h).objectflag;
		
		atts.frameval = (**h).objecthasframe;
		
		atts.transparentval = (**h).objecttransparent;
		
		atts.visibleval = (**h).objectvisible;
		
		atts.enabledval = (**h).objectenabled;
		
		atts.autosizeval = (**h).objectautosize;
		
		atts.shadowval = (**h).objectdropshadowdepth;
		
		callgetobjectflagname (h, atts.flagnameval);
		
		callgetobjectname (h, atts.typenameval);
		
		return (true);
		}
	
	callgetobjectflagname (h, bs);
	
	if (!equalstrings (bs, atts.flagnameval))
		atts.uniformflagname = false;
		
	callgetobjectname (h, bs);
	
	if (!equalstrings (bs, atts.typenameval))
		atts.uniformtypename = false;
	
	if ((**h).objectflag != atts.flagval)
		atts.uniformflag = false;
		
	if ((**h).objecthasframe != atts.frameval)
		atts.uniformframe = false;
		
	if ((**h).objecttransparent != atts.transparentval)
		atts.uniformtransparent = false;
		
	if ((**h).objectenabled != atts.enabledval)
		atts.uniformenabled = false;
		
	if ((**h).objectautosize != atts.autosizeval)
		atts.uniformautosize = false;
		
	if ((**h).objectvisible != atts.visibleval)
		atts.uniformvisible = false;
		
	if ((**h).objectdropshadowdepth != atts.shadowval)
		atts.uniformshadow = false;
		
	return (true);
	} /*getobjectattributesvisit*/
	
	
boolean iowaadjustmenus (void) {
	
	hdlcard hc = iowadata;
	short ctselected;
	short i;
	boolean flhaveselection;
	
	setmenuitem (hdlobjectmenu, flagitem, "\pFlag");
	
	setmenuitem (hdlobjectmenu, specialattsitem, "\pSpecial AttributesÉ");
	
	if (hc == nil) {
	
		disableallmenuitems (hdldrawmenu);
		
		disableallmenuitems (hdlobjectmenu);
		
		uncheckallmenuitems (hdldrawmenu);
		
		uncheckallmenuitems (hdlobjectmenu);
		
		#ifdef customizedfilemenu
		
		disablemenuitem (hdlfilemenu, saveasappitem); /*DW 3/18/93*/
		
		#endif
		
		disablemenuitem (hdlwindowmenu, windowattsitem);
		
		disablemenuitem (hdleditmenu, edittableitem);
		
		return (true);
		}
		
	/*enable the Edit Table command if Frontier is running*/ {
	
		boolean fl = false;	
		short majorRev, minorRev, bugFixRev;
		boolean flRuntime;
		
		if (getFrontierVersion (&majorRev, &minorRev, &bugFixRev, &flRuntime))				
			fl = !flRuntime;
		
		setmenuitemenable (hdleditmenu, edittableitem, fl);
		} 
		
	enablemenuitem (hdlwindowmenu, quickscriptitem);
	
	#ifdef customizedfilemenu
	
	disablemenuitem (hdlfilemenu, saveasappitem); /*DW 12/30/95 -- disabled*/
	
	#endif
	
	enablemenuitem (hdlwindowmenu, windowattsitem);
		
	ctselected = countselectedobjects ();
	
	flhaveselection = ctselected > 0;
	
	if (!flhaveselection)
		flhaveselection = edithaveselection (getactiveeditrecord ()); /*dmb 1.0b20 -- added, checks for nil*/

	setmenuitemenable (hdldrawmenu, 0, true); /*DW 12/28/95 -- added*/
	
	setmenuitemenable (hdldrawmenu, groupitem, ctselected > 1);
	
	setmenuitemenable (hdldrawmenu, ungroupitem, groupinselection ());
	
	for (i = alignleftitem; i <= alignbottomitem; i++)
		setmenuitemenable (hdldrawmenu, i, ctselected > 1);
	
	for (i = centervertitem; i <= centerhorizitem; i++)
		setmenuitemenable (hdldrawmenu, i, ctselected > 1);
		
	/*set up the grid items in the Draw menu*/ {
	
		enablemenuitem (hdldrawmenu, snaptoitem);
	
		enablemenuitem (hdldrawmenu, showgriditem);
	
		enablemenuitem (hdldrawmenu, setgriditem);
	
		checkmenuitem (hdldrawmenu, snaptoitem, (**hc).flgrid);

		checkmenuitem (hdldrawmenu, showgriditem, !(**hc).flinvisiblegrid);
		}

	enablemenuitem (hdldrawmenu, cleanupitem);
	
	enablemenuitem (hdldrawmenu, runcarditem);

	enablemenuitem (hdlobjectmenu, objectinfoitem);
	
	enablemenuitem (hdlobjectmenu, objectcolorsitem);
	
	enablemenuitem (hdlobjectmenu, recalcinfoitem);
	
	enablemenuitem (hdlobjectmenu, errorinfoitem);
	
	/*enable or disable the special attributes item*/ {
		
		boolean fl = false;
		
		if (ctselected == 1)
			fl = callhasspecialcard ((**hc).selectionlist);
		
		setmenuitemenable (hdlobjectmenu, specialattsitem, fl);
		}
	
	setmenuitemenable (hdleditmenu, cutitem, flhaveselection);
	
	setmenuitemenable (hdleditmenu, copyitem, flhaveselection);
	
	setmenuitemenable (hdleditmenu, pasteitem, true);
	
	setmenuitemenable (hdleditmenu, clearitem, flhaveselection);
	
	setmenuitemenable (hdleditmenu, selectallitem, true);

	setmenuitemenable (hdlobjectmenu, 0, true); /*DW 12/28/95 -- added*/
	
	setmenuitemenable (hdlobjectmenu, flagitem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, hasframeitem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, transparentitem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, visibleitem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, enableditem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, autosizeitem, flhaveselection);
	
	setmenuitemenable (hdlobjectmenu, frontitem, flhaveselection);
	
	/*
	setmenuitemenable (hdlobjectmenu, shadowdepthitem, flhaveselection);
	*/
	
	setmenuitemenable (hdlobjectmenu, backitem, flhaveselection);
	
	clearbytes (&atts, longsizeof (atts));
	
	atts.uniformflag = true;
	
	atts.uniformflagname = true;
	
	atts.uniformtypename = true;
	
	atts.uniformframe = true;
	
	atts.uniformtransparent = true;
	
	atts.uniformvisible = true;
	
	atts.uniformenabled = true;
	
	atts.uniformautosize = true;
	
	atts.uniformshadow = true;
	
	atts.firstobject = true;
	
	flatvisitselectedobjects (&getobjectattributesvisit);
	
	/*smash the text in the flag item*/ {
		
		if (!atts.uniformflagname)
			setstringlength (atts.flagnameval, 0);
		
		if (stringlength (atts.flagnameval) != 0)
			setmenuitem (hdlobjectmenu, flagitem, atts.flagnameval);
		}
	
	/*set the text in the special attributes item*/ {
		
		if (!atts.uniformtypename)
			setstringlength (atts.typenameval, 0);
		
		if (stringlength (atts.typenameval) != 0) {
			
			bigstring bs;
			
			copystring (atts.typenameval, bs);
			
			pushstring ("\p Info", bs);
			
			setmenuitem (hdlobjectmenu, specialattsitem, bs);
			}
		}
	
	if (atts.uniformflag)
		checkmenuitem (hdlobjectmenu, flagitem, atts.flagval);
		
	if (atts.uniformframe)
		checkmenuitem (hdlobjectmenu, hasframeitem, atts.frameval);
		
	if (atts.uniformtransparent)
		checkmenuitem (hdlobjectmenu, transparentitem, atts.transparentval);
		
	if (atts.uniformvisible)
		checkmenuitem (hdlobjectmenu, visibleitem, atts.visibleval);
		
	if (atts.uniformenabled)
		checkmenuitem (hdlobjectmenu, enableditem, atts.enabledval);
		
	if (atts.uniformautosize)
		checkmenuitem (hdlobjectmenu, autosizeitem, atts.autosizeval);
	
	return (true);
	} /*iowaadjustmenus*/