/* 
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 "iowaobject.h"
#include "iowascript.h"
#include <applet.h>
#include <appletcardops.h>
#include "iowainfowindow.h"




 
static hdlcard infowindowcard = nil;

static hdlcard sizewindowcard = nil;

static hdlcard colorwindowcard = nil;

static hdlcard recalcwindowcard = nil;

static hdlcard errorwindowcard = nil;

static hdlappwindow hfoundwindow = nil;

static hdlcard *globalstaticcardaddress; /*an essential link*/

static short globalresnum; /*another link, perhaps less essential*/



typedef struct tyrefconrecord { /*one of these is hanging off each info card*/
	
	short resnum;
	
	hdlcard *staticaddress;
	
	boolean flreseteverything;
	
	boolean flcheckenable;
	} tyrefconrecord, **hdlrefconrecord;


	
static void setcheckenable (void) {
	
	hdlrefconrecord hrefcon = (hdlrefconrecord) (**currentcard).refcon;
	
	(**hrefcon).flcheckenable = true;
	} /*setcheckenable*/
	

static void setreseteverything (void) {
	
	hdlrefconrecord hrefcon = (hdlrefconrecord) (**currentcard).refcon;
	
	(**hrefcon).flreseteverything = true;
	} /*setreseteverything*/
	

static boolean frontwindowvisit (hdlappwindow appwindow) {
	
	hfoundwindow = appwindow;
	
	return (false); 
	} /*frontwindowvisit*/
	
	
static boolean getfrontappwindow (hdlappwindow *frontappwindow) {

	hfoundwindow = nil;
	
	visitappwindows (&frontwindowvisit);
	
	*frontappwindow = hfoundwindow;
	
	return (hfoundwindow != nil);
	} /*getfrontappwindow*/
	
	
static void checkenable (hdlobject targetobject) {
	
	if (targetobject == nil) {
	
		/*enableallcardobjects (false);*/ /*disable and inval all objects*/
	
		return;
		}
		
	enableallcardobjects (true); /*enable and inval all objects*/
	
	/*enable or disable the recalcperiod object*/ {
		
		boolean fl = false;
		
		if (cardobjectexists ("\pagentrecalc"))
			fl = getcardbit ("\pagentrecalc");
			
		setcardenable ("\precalcperiod", fl);
		}
	
	setcardenable ("\papply", (**currentcard).runmodechanges);
	} /*checkenable*/
	
	
static void copyrecttodialog (hdlobject h) {
	
	Rect r;
	
	if (h == nil) {
	
		setcardstring ("\ptop", "\p");
		
		setcardstring ("\pleft", "\p");
		
		setcardstring ("\pbottom", "\p");
		
		setcardstring ("\pright", "\p");
		
		return;
		}
		
	r = (**h).objectrect;
	
	setcardnumber ("\ptop", r.top);

	setcardnumber ("\pleft", r.left);

	setcardnumber ("\pbottom", r.bottom);

	setcardnumber ("\pright", r.right);
	} /*copyrecttodialog*/
	
	
static void copytodialog (hdlobject hobj) {
	
	tyobject obj;
	
	if (hobj == nil) {
		
		clearbytes (&obj, longsizeof (obj));
		
		obj.objectfillcolor = obj.objectframecolor = obj.objecttextcolor = whitecolor;
		}
	else 
		obj = **hobj;
	
	copyrecttodialog (hobj);
	
	setcardflag ("\pnorecalc", obj.objectrecalcstatus == neverrecalc);
	
	setcardflag ("\pstartuprecalc", obj.objectrecalcstatus == initrecalc);
	
	setcardflag ("\pchangerecalc", obj.objectrecalcstatus == changerecalc);
	
	setcardflag ("\pagentrecalc", obj.objectrecalcstatus == timerecalc);
	
	setcardnumber ("\precalcperiod", obj.objectrecalcperiod);
	
	setcardtexthandle ("\pname", obj.objectname);
	
	setcardtexthandle ("\perrormessage", obj.objecterrormessage);
	
	setcardtexthandle ("\precalcscript", obj.objectrecalcscript);
	
	setcardcolorpopup ("\pfillcolor", &obj.objectfillcolor);

	setcardcolorpopup ("\pframecolor", &obj.objectframecolor);

	setcardcolorpopup ("\ptextcolor", &obj.objecttextcolor);
	
	/*check the current item in the languages popup*/ {
		
		short i, checkeditem = 1, ct;
		
		ct = countlangcomponents ();
		
		for (i = 0; i < ct; i++) {
			
			OSType id;
			
			getlanguageid (i, &id);
			
			if (id == obj.objectlanguage) {
				
				checkeditem = i + 1;
				
				break;
				}
			} /*for*/
		
		setcardpopupcheckeditem ("\planguages", checkeditem);
		}
	
	checkenable (hobj);
	} /*copytodialog*/
	
	
static void copyfromdialog (hdlobject targetobject) {
	
	tyobject obj; 
	
	if (targetobject == nil) 
		return;
	
	obj = **targetobject;
	
	if (cardobjectexists ("\pnorecalc")) {
	
		obj.objectrecalcperiod = 0;
	
		if (getcardbit ("\pnorecalc"))
			obj.objectrecalcstatus = neverrecalc;
		}
	
	if (cardobjectexists ("\pstartuprecalc")) {
	
		if (getcardbit ("\pstartuprecalc"))
			obj.objectrecalcstatus = initrecalc;
		}
	
	if (cardobjectexists ("\pchangerecalc")) {
	
		if (getcardbit ("\pchangerecalc"))
			obj.objectrecalcstatus = changerecalc;
		}
	
	if (cardobjectexists ("\pagentrecalc")) {
	
		if (getcardbit ("\pagentrecalc")) {
		
			obj.objectrecalcstatus = timerecalc;
			
			getcardshort ("\precalcperiod", &obj.objectrecalcperiod);
			}
		}
	
	getcardshort ("\ptop", &obj.objectrect.top);
	
	getcardshort ("\pleft", &obj.objectrect.left);
	
	getcardshort ("\pbottom", &obj.objectrect.bottom);
	
	getcardshort ("\pright", &obj.objectrect.right);
	
	getcardcolorpopup ("\pfillcolor", &obj.objectfillcolor);

	getcardcolorpopup ("\pframecolor", &obj.objectframecolor);

	getcardcolorpopup ("\ptextcolor", &obj.objecttextcolor);
	
	if (cardobjectexists ("\planguages"))
		getlanguageid (getcardpopup ("\planguages") - 1, &obj.objectlanguage);
	
	replacecardtexthandle ("\pname", &obj.objectname);
	
	replacecardtexthandle ("\precalcscript", &obj.objectrecalcscript);
	
	/*inval the changed object, mark window as dirty*/ {
	
		hdlappwindow appwindow;
		
		getfrontappwindow (&appwindow);
		
		pushmacport ((**appwindow).macwindow);
		
		setappwindow (appwindow);
		
		appprecallback ();
		
		madechanges ();
		
		invalobject (targetobject);
			
		**targetobject = obj;
		
		invalobject (targetobject);
			
		apppostcallback ();
		
		popmacport ();
		}
	} /*copyfromdialog*/
	
	
static void initdialog (void) {
	
	if (cardobjectexists ("\planguages")) {
	
		MenuHandle hlangmenu;
		
		getlangmenu (&hlangmenu);
		
		setcardpopupfrommenu ("\planguages", hlangmenu, 0);
	
		DisposeMenu (hlangmenu);
		}
	} /*initdialog*/
	
	
static boolean gettargetobject (hdlobject *targetobject) {
	
	/*
	return true if the target object changed
	*/

	hdlobject origtarget = *targetobject;
	hdlappwindow appwindow;
	
	*targetobject = nil; /*default return*/
		
	getfrontappwindow (&appwindow);
	
	if (appwindow == nil) /*no open windows*/
		goto exit;
		
	*targetobject = (**(hdlcard) (**appwindow).appdata).selectionlist;
	
	exit:
	
	if (*targetobject == origtarget) /*didn't change*/
		return (false);
		
	return (true);
	} /*gettargetobject*/
	
	
static void infowindowfilter (EventRecord *ev) {
	
	static hdlobject targetobject = nil;
	
	switch ((*ev).what) {
		
		case iowaInitEvent: 
			currentcard = (hdlcard) (*ev).message;
			
			/*set up the refcon handle*/ {
				
				tyrefconrecord refcon;
				Handle hrefcon;
				
				clearbytes (&refcon, longsizeof (refcon));
				
				refcon.resnum = globalresnum;
				
				refcon.staticaddress = globalstaticcardaddress;
				
				newfilledhandle (&refcon, longsizeof (refcon), &hrefcon);
				
				(**currentcard).refcon = (long) hrefcon;
				}
			
			*globalstaticcardaddress = currentcard;
			
			gettargetobject (&targetobject); 
			
			initdialog ();
			
			checkenable (targetobject);
			
			copytodialog (targetobject);
			
			break;
			
		case activateEvt: 
			if ((*ev).modifiers & activeFlag) {
			
				if (gettargetobject (&targetobject)) /*target changed*/ 
					copytodialog (targetobject);
				}
				
			break;
			
		case iowaButtonHitEvent: {
			hdlobject hobject = (hdlobject) (*ev).message;
			bigstring bs;
			
			texthandletostring ((**hobject).objectname, bs);
			
			if (equalstrings (bs, "\papply")) {
			
				currentcard = (hdlcard) (**hobject).owningcard;
				
				copyfromdialog (targetobject);
				
				(**currentcard).runmodechanges = false; 
	
				checkenable (targetobject);
				}
							
			break;
			}
			
		case iowaCloseEvent:
			currentcard = (hdlcard) (*ev).message; 
			
			/*use the information that was tucked away in the refcon handle*/ {
				
				hdlrefconrecord hrefcon = (hdlrefconrecord) (**currentcard).refcon;
				
				if (hrefcon != nil) {
					
					appsavedialoginfo ((**hrefcon).resnum); /*remember window position*/
					
					*(**hrefcon).staticaddress = nil;
					}
				}
			
			break;
				
		case nullEvent: {
			hdlrefconrecord hrefcon;

			currentcard = (hdlcard) (*ev).message; /*copy into global*/
			
			gettargetobject (&targetobject); 
			
			hrefcon = (hdlrefconrecord) (**currentcard).refcon;
			
			if ((**hrefcon).flreseteverything) {
				
				(**hrefcon).flreseteverything = false;
			
				copytodialog (targetobject);
				}
			
			if ((**hrefcon).flcheckenable) {
				
				(**hrefcon).flcheckenable = false;
				
				checkenable (targetobject);
				}
	
			break;
			}
			
		case iowaSetHandleEvent:
			currentcard = (hdlcard) (*ev).message; /*copy into global*/
			
			break;			
			
		case keyDown: case autoKey: case mouseUp: case mouseDown:
			setcheckenable ();
			
			break;
		} /*switch*/
	} /*infowindowfilter*/
	
	
static void resetwindow (hdlcard hcard) {
	
	hdlrefconrecord hrefcon;
	
	if (hcard == nil) /*the window isn't open*/
		return;
	
	hrefcon = (hdlrefconrecord) (**hcard).refcon;
	
	(**hrefcon).flreseteverything = true;
	
	(**hrefcon).flcheckenable = true;
	} /*resetwindow*/
	

void resetinfowindows (void) {
	
	/*
	call this when some attribute of the selected object changed.
	*/
	
	resetwindow (infowindowcard);
	
	resetwindow (sizewindowcard);
	
	resetwindow (colorwindowcard);
	
	resetwindow (recalcwindowcard);
	
	resetwindow (errorwindowcard);
	} /*resetinfowindows*/
	
	
void reseterrorinfowindow (void) {
	
	resetwindow (errorwindowcard);
	} /*reseterrorinfowindow*/
	

static void iowaopeninfowindow (short resnum, hdlcard *staticaddress) {
	
	if (*staticaddress == nil) {
		
		globalstaticcardaddress = staticaddress;
		
		globalresnum = resnum;
		
		appopencardresource (resnum, &infowindowfilter);
		}
	else 
		SelectWindow ((**(*staticaddress)).drawwindow); 
	} /*iowaopeninfowindow*/


void maininfowindow (void) {
	
	iowaopeninfowindow (132, &infowindowcard);
	} /*maininfowindow*/
	
	
void recalcinfowindow (void) {
	
	iowaopeninfowindow (133, &recalcwindowcard);
	} /*recalcinfowindow*/
	
	
void colorinfowindow (void) {
	
	iowaopeninfowindow (134, &colorwindowcard);
	} /*colorinfowindow*/
	

void errorinfowindow (void) {
	
	iowaopeninfowindow (135, &errorwindowcard);
	} /*errorinfowindow*/