/*
Pencil V2.0, Copyright 1994, 95 by Florian Marquardt.
This program may be distributed under the terms of the GNU general
public license (Start Pencil and select "Copyright" in the Help panel for a copy of the
license).
Pencil has a built-in TCL interpreter (tcl 7.3 by John Ousterhout). This is under a separate
license (see "Copyright").
*/
#import "PencilInspector.h"
#import "PencilView.h"

#import <remote/NXConnection.h>
#import <remote/NXProxy.h>


extern BOOL globalOutlines;
BOOL globalTermination=NO;
BOOL load_at_start=NO;
BOOL globalComposite=YES;

extern Tcl_Interp *initPencilTCL(id inspector); // in PencilTCL.m

id Pinspector; // global: there is only one inspector
id Pview; // global: Pencil view of current main window
extern char GUI_string[]; // in GUI.m
Tcl_Interp *TCLip; // global: the TCL interpreter

unsigned long long int layersVisible1=0xFFFFFFFFFFFFFFFFULL;	// bits give visible layers
unsigned long long int layersVisible2=0xFFFFFFFFFFFFFFFFULL;	// 128 layers
unsigned long long int layersSelectable1=0xFFFFFFFFFFFFFFFFULL;	// bits give selectable layers
unsigned long long int layersSelectable2=0xFFFFFFFFFFFFFFFFULL;	// 128 layers
unsigned char currentLayer=0;

@implementation PencilInspector
// app delegate methods:
- initTCL
{
	if(!TCLip) {
	Pinspector=self;
	TCLip=initPencilTCL( self); // initialize TCL interpreter
	[self initPopUpLists];
	}
	return self;
}

- appDidInit:sender
{
	[self initTCL];
    	if (NXArgc > 1) {
	    [self openFile:NXArgv[1]];
    	} else  if(!load_at_start) [NXApp loadNibSection:"EmptyDocument.nib" owner:self];
	return self;
}

- (int)app:sender openFile:(const char *)path type:(const char *)type
/*
 * This method is performed whenever a user double-clicks on an icon
 * in the Workspace Manager representing a .pencil file.
 */
{
	[self initTCL];
    if (type && !strcmp(type, "pencil")) {
	[self openFile:path];
	load_at_start=YES;
	return YES;
    }
    return NO;
}

- (BOOL)appAcceptsAnotherFile:(Application *)sender
{
    return YES;
}

- appWillTerminate:sender
{
	id list,listv;
	int i,j;

	globalTermination=YES;
	list=[NXApp windowList];
	for(i=[list count]-1;i>=0;i--)	{
		if(listv=[[[list objectAt:i] contentView] subviews])
		{
			for(j=[listv count]-1;j>=0;j--) if([[listv objectAt:j] isMemberOf:[ScrollView class]])	if([[[listv objectAt: j] docView] isMemberOf: [PencilView class]]) break;
			if(j>=0)
			{
				[[list objectAt:i] performClose:self];
				if(!globalTermination)	break;
			}
		}
	}
	if(globalTermination)
		return self;
	else
		return nil;
}

- initPopUpLists
{
	Tcl_GlobalEval(TCLip, "P_initPopUps");	return self;
}

- popup:(int)num
{
	switch(num) {
		case 0: return pathPopUp;
		case 1: return drawPopUp;
		case 2: return fillPopUp;
		case 3: return strokePopUp;
	}
	return nil;
}

- takeNew:sender
{
	if(view)
	{
	switch([sender tag])
	{
	case METHODNAME: [view setMethodname:[sender stringValue]]; break;
	case COLOR1: [view setColor1:[sender color]]; break;
	case COLOR2: [view setColor2:[sender color]]; break;
	case LINEWIDTH: [view setLineWidth:[sender floatValue]]; break;
	case DRAWMETHOD: [view setDrawingMethod:[sender stringValue]]; break;
	case FILLMETHOD: [view setFillMethod:[sender stringValue]]; break;
	case STROKEMETHOD: [view setStrokeMethod:[sender stringValue]]; break;
	case SPECIALATTRIBUTES: [view setSpecialAttributes:[sender stringValue]]; break;
	}
	}
    return self;
}

- giveSettings:(char **)name:(NXColor *)col1:(NXColor *)col2:(float *)lw:(char **)dm:(char **)fm:(char **)sm:(char **)ud
{
	if(!(*name=[methodname stringValue])) *name="rect";
	if(!(*fm=[fillmethod stringValue])) *fm="fill";
	if(!(*dm=[drawmethod stringValue])) *dm="dF";
	if(!(*sm=[strokemethod stringValue])) *sm="stroke";
	*ud=[special stringValue];
	*col1=[color1 color];
	*col2=[color2 color];
	*lw=[linewidth floatValue];
	return self;
}

- (void)updateWithUDef: (char *)ud
{
	if( !ud || !strcmp(ud, "")) {
		Tcl_UnsetVar( TCLip, "udef", TCL_GLOBAL_ONLY);
		Tcl_GlobalEval( TCLip, "P_upd");
	} else {
		Tcl_SetVar( TCLip, "u", ud, TCL_GLOBAL_ONLY);
		Tcl_VarEval( TCLip, "P_parse $u", NULL);
		Tcl_GlobalEval( TCLip, "P_upd");
	} 
}

- takeSettings:(char*)name:(NXColor)col1:(NXColor)col2:(float)lw:(char *)dm:(char *)fm:(char *)sm:(char *)ud
{
	[methodname setStringValue:name];
	[self findName:name in:0];
	[drawmethod setStringValue:dm];
	[self findName:dm in:1];
	[fillmethod setStringValue:fm];
	[self findName:fm in:2];
	[strokemethod setStringValue:sm];
	[self findName:sm in:3];
	[special setStringValue:ud];
	[color1 setColor:col1];
	[color2 setColor:col2];
	[linewidth setFloatValue:lw];
	[self updateWithUDef: ud];
	return self;
}

- findName:(char *)nm in:(int)l
{
	int i;
	char *res;
	id mpop;
	
		if(res=Tcl_GetVar2(TCLip, "P_t", nm, TCL_GLOBAL_ONLY)) {
		i=atoi(res);
		mpop=[self popup:l];
		[[[mpop target] itemList] selectCellWithTag:i];
		[mpop setTitle:[[[[mpop target] itemList] selectedCell] title]];
		}
	return self;
}

- (void)setPathM: (char*)name
{
	if(view) [view setMethodname:name];
	[methodname setStringValue:name];
	[self findName: name in: 0];
}

- (void)setDraw: (char*)name
{
	if(view) [view setDrawingMethod:name];
	[drawmethod setStringValue:name];
	[self findName: name in: 1];
}

- (void)setFill: (char*)name
{
	if(view) [view setFillMethod:name];
	[fillmethod setStringValue:name];
	[self findName: name in: 2];
}

- (void)setStroke: (char*)name
{
	if(view) [view setStrokeMethod:name];
	[strokemethod setStringValue:name];
	[self findName: name in: 3];
}

- doChange:sender
{
	int mode=0, tag;
	char *name;
	
	tag=[[sender selectedCell] tag];
	sender=[sender window];
	if(sender==[pathPopUp target]) mode=0;
	if(sender==[drawPopUp target]) mode=1;
	if(sender==[fillPopUp target]) mode=2;
	if(sender==[strokePopUp target]) mode=3;
	sprintf(GUI_string, "%d.%d", mode, tag);
	if(name=Tcl_GetVar2(TCLip, "P_l", GUI_string, TCL_GLOBAL_ONLY)) {
	switch(mode)
	{
	case 0: if(view) if([view setMethodname:name]) [methodname setStringValue:name]; else [self setPathM: [methodname stringValue]]; break;
	case 1: if(view) [view setDrawingMethod:name]; [drawmethod setStringValue:name]; break;
	case 2: if(view) [view setFillMethod:name]; [fillmethod setStringValue:name]; break;
	case 3: if(view) [view setStrokeMethod:name]; [strokemethod setStringValue:name]; break;
	}
	}
	return self;
}
- athreshField { return aField; }
- sthreshField { return sField; }
- creationType { return cType; }
- inspectForView:(id)v { Pview=view=v; 	[view giveCustomTo:customPS];
return self; }
#define FOR(a) if(view) return [view a :sender]; else return self
- toFront:sender { FOR(toFront); }
- toBack:sender { FOR(toBack); }
- insertPoint:sender { FOR(insertPoint); }
- insertNextPoint:sender { FOR(insertNextPoint); }
- deletePoint:sender { FOR(deletePoint); }
- deleteGraphic:sender { FOR(deleteGraphic); }
- saveAs:sender { FOR(saveAs); }
- save:sender { FOR(save); }
- toCharP:sender { FOR(convertToCharPath); }
- print:sender { if(view) return [view printPSCode:sender]; else return self; }
- open:sender
{
	const char *types[]={ "pencil", NULL };

	if([[OpenPanel new] runModalForTypes:types]==NX_OKTAG)
	{
		[self openFile:[[OpenPanel new] filename]];
	}
	return self;
}
- openFile:(char *)name
{
	[NXApp loadNibSection:"EmptyDocument.nib" owner:self];
	[view readFromFilename:name];
	[view giveCustomTo:customPS];
	return self;
}

- new:sender
{
	[NXApp loadNibSection:"EmptyDocument.nib" owner:self];
	[customPS setText:""];
	return self;
}

- viewVanished:(id)v
{
	if(view==v)
	{
		Pview=view=nil;
		[customPS setText:""];
	}
	return self;
}

- executeCustom:sender
{
	if(view) [view takeCustomFrom:customPS];
	return self;
}

- setDrawOutlines:sender { globalOutlines=[sender state] ? YES:NO; if(view) [view displayWithCurrentGraphic]; return self; }

- copyAsPostScript:sender { if(view) [view copyAsPostScript:sender]; return self; }

- clearUserDef:sender
{
	[special setStringValue:""];
	if(sender)
		if(view) { [view takeCustomFrom:customPS]; [view displayWithCurrentGraphic]; }
	[self updateWithUDef: ""];
	return self;
}

- setUserDef:(char *)udef
{
	[special setStringValue:udef];
	[self updateWithUDef: ""];
	return self;
}

- takeUserDef: (char *)udef
{
	[special setStringValue: udef];
	if(view) { [view setSpecialAttributes: udef]; }
	return self;
}

- (char *)getUserDef
{
	return (char *)[special stringValue];
}

- importImage:sender
{
	if(view) [view importImage:sender];
	return self;
}

- registerAsTCLServer:sender
{
		if(!TCLconn)
		{
			TCLconn=[NXConnection registerRoot: self withName:"pencilTCLServer"];
			[TCLconn runFromAppKit];
		}
	return self;
}

- (char *)performCommand:(const char *)cmd
{
	Tcl_GlobalEval( TCLip, cmd);
	return( TCLip->result );
}

- takeLayer: (unsigned char) ly
{
	currentLayer=ly;
	Tcl_GlobalEval(TCLip, "takeLayer");
	return self;
}

- correctCurLayer
{
	Tcl_GlobalEval(TCLip, "correctLayer");
	return self;
}

- takeMenu: sender
{
	int t;
	char str[10];
	char *action;
	
	t=[[sender selectedCell] tag];
	sprintf(str,"%d", t);
	if (action=Tcl_GetVar2( TCLip, "menu", str, TCL_GLOBAL_ONLY)) {
		Tcl_GlobalEval( TCLip, action);
	}
	return self;
}

// will only be called when invoked from "P_print -"
- (BOOL)shouldRunPrintPanel: sender
{
	return NO;
}
@end
