/*
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 <tcl.h>
#import "GUI.h"
#import "PencilInspector.h"
#import "PencilView.h"
#import "Group.h"

#define ERR(a) { Tcl_SetResult(interp, a, TCL_STATIC); return TCL_ERROR; }

extern id GUI_findobject(Tcl_Interp *ip, char *key);
extern id Pinspector; // in PencilInspector.m
extern id Pview; // current view, in PencilInspector.m

extern unsigned long long int layersVisible1;
extern unsigned long long int layersVisible2;
extern unsigned long long int layersSelectable1;
extern unsigned long long int layersSelectable2;
extern unsigned char currentLayer;

extern BOOL globPrintTransp;

id globGUI;

extern BOOL globalClearBG;

int
P_additem(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=4) {
[[[[[[Pinspector popup: atoi(argv[3])] target] addItem:argv[1]] setTarget: Pinspector] setAction:@selector(doChange:)] setTag:atoi(argv[2])];
	return TCL_OK;
	}
	ERR("? P_additem <name> <tag> <list>");
}


int
P_clearitems(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	int i;
	id mylist=[[Pinspector popup: atoi(argv[1])] target];
	i=[mylist count];
	while(i--) [mylist removeItemAt: 0];
	return TCL_OK;
	}
	ERR("? P_clearitems <list>");
}

void convertToList (Tcl_Interp *interp, unsigned long long int ly1,  unsigned long long int ly2)
{
	int i;
	for(i=0;i<128;i++) {
	if(i<=63 ? (ly1&(1ULL<<i)): (ly2&(1ULL<<(i-64))))
		Tcl_AppendElement( interp, "1");
	else
		Tcl_AppendElement(interp, "0");
	}
}

int
P_getLayers(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	Tcl_AppendResult( interp, "{ ", NULL);
	convertToList( interp, layersVisible1, layersVisible2);
	Tcl_AppendResult( interp, "} {",NULL);
	convertToList( interp, layersSelectable1, layersSelectable2);
	Tcl_AppendResult( interp, "}", NULL);
	return TCL_OK;
}

char *swallowBrace( char *p)
{
	while(*p!=0 && *p!='{' && *p!='}') p++;
	if(*p=='{' || *p=='}') p++;
	return p;
}

char *convertToInt(char *p, unsigned long long int *i)
{
	int j=0;
	
	*i=0;
	
	while(*p!=0 && j<64) {
		while(*p==' ') p++;
		if(*p=='1') 			
			*i|=(1ULL<<j);
		if(*p!=0) p++;
		j++;
	}
	return p;
}

int
P_setLayers(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	char *pos;
	
	if(argc>=2) {
	pos=argv[1];
	pos=swallowBrace(pos);
	pos=convertToInt(pos, &layersVisible1);
	pos=convertToInt(pos, &layersVisible2);
	pos=swallowBrace(swallowBrace(pos));
	pos=convertToInt(pos, &layersSelectable1);
	pos=convertToInt(pos, &layersSelectable2);
	layersSelectable1&=layersVisible1;
	layersSelectable2&=layersVisible2;
	printf("lVis: 1 %d 2 %d lSel: 1 %d 2 %d cur:%d\n", (int)layersVisible1, (int)layersVisible2, (int)layersSelectable1, (int)layersSelectable2, (int)currentLayer);
	return TCL_OK;
	}
	ERR("? P_setLayers { {..visible..} {..selectable..} }");
}

int
P_setCurLayer(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	currentLayer=(unsigned char)atoi(argv[1]);
	if(currentLayer<=63 ? (layersSelectable1&(1ULL<<currentLayer)): (layersSelectable2&(1ULL<<(currentLayer-64)))) {
	if(Pview) [Pview takeLayer: currentLayer];
	strcpy(interp->result, "1");
	}
	else
	{
	strcpy(interp->result, "0");
	}
	return TCL_OK;
	}
	ERR("? P_setCurLayer <#>");
}

int
P_getCurLayer(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	sprintf(interp->result, "%d", (int)currentLayer);
	return TCL_OK;
}

int
P_setPath(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		[Pinspector setPathM: argv[1]];
		return TCL_OK;
	}
	ERR("? setPath <>");
}

int
P_setDraw(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		[Pinspector setDraw: argv[1]];
		return TCL_OK;
	}
	ERR("? setPath <>");
}

int
P_setFill(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		[Pinspector setFill: argv[1]];
		return TCL_OK;
	}
	ERR("? setPath <>");
}

int
P_setStroke(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		[Pinspector setStroke: argv[1]];
		return TCL_OK;
	}
	ERR("? setPath <>");
}

int
P_new(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	[Pinspector new: nil];
	return TCL_OK;
}

int
P_open(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		[(PencilInspector *)Pinspector openFile: argv[1]];
		return TCL_OK;
	}
	ERR("? P_open <file>");
}

int
P_objectcount(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) sprintf(interp->result, "%d", [Pview objectcount]);
	return TCL_OK;
}

int
P_getobject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		if(Pview) [Pview descFor: atoi(argv[1]): interp];
		return TCL_OK;
	}
	ERR("? P_getobject <#>");
}

int
P_changeobject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=3) {
		if(Pview) [Pview changeobject: interp: atoi(argv[1]): argv[2]];
		return TCL_OK;
	}
	ERR("? P_changeobject <#> <desc>");
}

int
P_addobject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=3) {
		if(Pview) {
			[Pview changeobject: interp: [Pview addObject: atoi(argv[1]): -1]: argv[2]];
			}
		return TCL_OK;
	}
	ERR("? P_addobject <type> <desc>");
}

int
P_display(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview displayWithCurrentGraphic];
	return TCL_OK;
}

int
P_resize(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=5) {
		NXRect f;
		f.origin.x=atof(argv[1]);
		f.origin.y=atof(argv[2]);
		f.size.width=atof(argv[3]);
		f.size.height=atof(argv[4]);
		if(Pview) { [[Pview window] placeWindowAndDisplay:&f];
		[Pview setEdited]; }
		return TCL_OK;
	}
	ERR("? P_resize <x> <y> <w> <h>");

}

int
P_save(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		if(Pview) [Pview doSave: argv[1]];
		return TCL_OK;
	}
	ERR("? P_save <file>");
}

int
P_selection(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview giveSelection: interp];
	return TCL_OK;
}

int
P_delete(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		if(Pview) [Pview deleteObj: atoi(argv[1])];
		return TCL_OK;
	}
	ERR("? P_delete <#>");
}

int
P_print(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) {
		if(argc>=2) [Pview printPSCode: Pinspector];
		else
			[Pview printPSCode: nil];
	}
	return TCL_OK;
}

int
P_name(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview giveName: interp];
	return TCL_OK;
}

int
P_move(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=3) {
	if(Pview) { [Pview translate: atof(argv[1]): atof(argv[2])]; }
	return TCL_OK;
	}
	ERR("? P_move <dx> <dy>");
}

int
P_scale(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	if(Pview) [Pview setScale: atof(argv[1])];
	return TCL_OK;
	}
	ERR("? P_scale <factor>");
}

int
P_paste(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview paste: nil];
	return TCL_OK;
}

int
P_select1(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
		if(Pview) [Pview select1: atoi(argv[1])];
		return TCL_OK;
	}
	ERR("P_select1 <#>");
}

int
P_select(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) return [Pview select: interp: argc: argv];
	return TCL_OK;
}

int
P_display1(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	if(Pview) [Pview display1: atoi(argv[1])];
	return TCL_OK;
	}
	ERR("? P_display1 <#>");
}

int
P_displayRect(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	NXRect r;
	
	r.origin.x=atof(argv[1]);
	r.origin.y=atof(argv[2]);
	r.size.width=atof(argv[3]);
	r.size.height=atof(argv[4]);
	if(Pview) [Pview display: &r: 1];
	return TCL_OK;
	}
	ERR("? P_displayRect <x> <y> <w> <h>");
}

int
P_group(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) {
		if([Pview makeGroup])
		[[Pview curGraphic] setGroupType:PENCIL_STANDARD_GROUP];
	}
	return TCL_OK;
}

int
P_clipgroup(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) {
		if([Pview makeGroup])
		[[Pview curGraphic] setGroupType:PENCIL_CLIP_GROUP];
	}
	return TCL_OK;
}

int
P_ungroup(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview ungroup];
	return TCL_OK;
}

int
P_front(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview toFront:nil];
	return TCL_OK;
}

int
P_back(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview toBack:nil];
	return TCL_OK;
}

int
P_objectBounds(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2 && Pview) {
	int n=atoi(argv[1]);
	id gl=[Pview glist];
	id o;
	
	if(n>=0 && n<[gl count]) {
		NXRect r;
		[o=[gl objectAt: n] calculateBoundingBox: Pview];
		[o giveBounds: &r];
		sprintf(interp->result, "%g %g %g %g", r.origin.x, r.origin.y, r.size.width, r.size.height);
		return TCL_OK;
	}	
	}
	ERR("? P_objectBounds <#>");
}

int
P_moveObject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=4 && Pview) {
	int n=atoi(argv[1]);
	id gl=[Pview glist];
	id o;
	
	if(n>=0 && n<[gl count]) {
		[o=[gl objectAt: n] addTranslation: atof(argv[2]): atof(argv[3])];
		[o calculateBoundingBox: Pview];
		return TCL_OK;
	}	
	}
	ERR("? P_moveObject <#> <dx> <dy>");
}

int
P_scaleObject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=6 && Pview) {
	int n=atoi(argv[1]);
	id gl=[Pview glist];
	id o;
	
	if(o=[gl objectAt: n]) {
		[o scaleCenter: atof(argv[2]):atof(argv[3]) by: atof(argv[4]): atof(argv[5])];
		[o calculateBoundingBox: Pview];
		return TCL_OK;
	}	
	}
	ERR("? P_scaleObject <#> <cx> <cy> <sx> <sy>");
}

int
P_rotateObject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=5 && Pview) {
	int n=atoi(argv[1]);
	id gl=[Pview glist];
	id o;
	
	if(o=[gl objectAt: n]) {
		[o rotateBy: atof(argv[2]):atof(argv[3]): atof(argv[4])];
		[o calculateBoundingBox: Pview];
		return TCL_OK;
	}	
	}
	ERR("? P_scaleObject <#> <phi> <cx> <cy>");
}

int
P_copyPS(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview copyAsPostScript: nil];
	return TCL_OK;
}

int
P_import(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=4) {
	if(Pview) [Pview importImageFromFile: argv[1]: atof(argv[2]): atof(argv[3])];
	return TCL_OK;
	}
	ERR("? P_import <file> <x> <y>");
}

int
P_userDef(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	Tcl_AppendResult(interp, [Pinspector getUserDef], NULL); 
	return TCL_OK;
}

int
P_setUserDef(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {	
	[Pinspector takeUserDef: argv[1]];
	return TCL_OK;
	}
	ERR("? P_setUserDef <udef>");
}

int
P_dispCurGr(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview displayCurrentGraphic];
	return TCL_OK;
}

int
P_resizeView(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=3) {
	if(Pview) {
	NXRect f, F;
	NXRect b;
	
	[Pview getBounds: &b];
	[Pview getFrame: &F];
	f.size.width=atof(argv[1]);
	f.size.height=atof(argv[2]);
	f.origin=F.origin;
	[Pview setFrame: &f];
	[Pview setDrawSize: atof(argv[1])*b.size.width/F.size.width: atof(argv[2])*b.size.height/F.size.height];
	[Pview setDrawOrigin: b.origin.x: b.origin.y ];
	}
	return TCL_OK;
	}
	ERR("? P_resizeView <w> <h>");
}

int
P_writeObject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=3) {
	if(Pview) {
	[Pview writeObject: atoi(argv[1]) to: argv[2]];
	return TCL_OK;
	}
	}
	ERR("? P_writeObject <#> <file>");
}

int
P_readObject(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	if(Pview) {
	[Pview readObjectFrom: argv[1]];
	return TCL_OK;
	}
	}
	ERR("? P_readObject <file>");
}

int
P_writePS(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=6) {
	if(Pview) {
	[Pview writePSIn: atof(argv[1]): atof(argv[2]): atof(argv[3]): atof(argv[4]): argv[5]];
	return TCL_OK;
	}
	}
	ERR("? P_writePS <x> <y> <w> <h> <file>");
}

int
P_setClearBG(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	globalClearBG=atoi(argv[1]);
	return TCL_OK;
	}
	ERR("? P_setClearBG <?>");
}

int
P_setPrintTransp(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	globPrintTransp=atoi(argv[1]);
	return TCL_OK;
	}
	ERR("? P_setPrintTransp <?>");
}

int
P_addMenuItem(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	static int tg=10;
	
	if(argc>=3) {
	id submenu;
	char str[10]; 
	++tg;
	if (submenu=[[[NXApp mainMenu] findCellWithTag: atoi(argv[1])] target]) {
		id menucell;
		
	 	menucell= [submenu addItem: argv[2] action: @selector(takeMenu:) keyEquivalent: argv[3][0]];
		[menucell setTarget: Pinspector];
		[menucell setTag: tg];
		sprintf(str, "%d", tg);
		Tcl_SetVar2( interp, "menu", str, argv[4], TCL_GLOBAL_ONLY);
		return TCL_OK;
	}
	}
	ERR("? P_addMenuItem <subtag> <name> <key-eq> <action>");
}

int
P_setAttributes(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=13 && Pview) {
		[Pinspector takeSettings: argv[1]: NXConvertRGBToColor(atof(argv[7]), atof(argv[8]), atof(argv[9])): NXConvertRGBToColor(atof(argv[10]), atof(argv[11]), atof(argv[12])): atof(argv[6]): argv[2]: argv[3]: argv[4]: argv[5]];
		[Pview changeCUR];
		[Pview displayCurrentGraphic];
		return TCL_OK;
	}
	ERR("? P_setAttributes <path> <draw> <fill> <stroke> <udef> <lw> <col1> <col2>");
}

int
P_convert2CP(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) [Pview convertToCharPath: nil];
	return TCL_OK;
}

int
P_forSelection(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2 && Pview) {
		id cu;
		
		if(cu=[Pview curGraphic])
			[Pview performForObject: cu: argv[1]];
		return TCL_OK;
	}
	ERR("? P_forSelection <script>");
}

int
P_hideDisplay(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2 && Pview) {
		[[Pview window] disableDisplay];
		Tcl_VarEval( interp, argv[1], NULL);
		[[Pview window] reenableDisplay];
		return TCL_OK;
	}
	ERR("? P_hideDisplay <script>");
}

int
P_selectAll(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(Pview) {
		[Pview selectAll: nil];
		return TCL_OK;
	}
	ERR("? P_selectAll");
}

#define SPACES while(*p==' ' || *p=='\n' || *p=='\t') ++p
#define NOSPACES while(*p!=' ' && *p!='\n' && *p!='\t' && *p!=0) ++p
#define STRLEN 49

int
P_parse(ClientData cd, Tcl_Interp *interp, int argc, char * argv[])
{
	if(argc>=2) {
	char *p, *beg, *end, *value;
	int openBraces, lng;
	char str[STRLEN+1];
	char vlu[STRLEN+1];
	char braceOpen, braceClosed, save;
	
	Tcl_UnsetVar( interp, "udef", TCL_GLOBAL_ONLY);
	
	p=argv[1];
	while(*p!=0) {
	SPACES;
	
	if(*p!='/') break;
	beg=p;
	NOSPACES;
	if((lng=(int)(p-beg))>STRLEN) break;
	strncpy( str, beg, lng);
	str[lng]=0;
	
	SPACES;
	
	beg=p;
	braceOpen=0;
	switch(*p) {
	case '(': braceOpen='('; braceClosed=')'; break;
	case '{': braceOpen='{'; braceClosed='}'; break;
	case '[': braceOpen='['; braceClosed=']'; break;
	}
	if(braceOpen) {
		openBraces=0;
		++p;
		while(*p!=0) {
			while(*p!=0 && *p!=braceOpen && *p!=braceClosed && *p!='\\') ++p;
			if(*p!=0) {
				if(*p=='\\' && *(p+1)!=0) ++p;
				if(*p==braceOpen) ++openBraces;
				if(*p==braceClosed) {
					--openBraces;
					if(openBraces<0) {
						++p;
						break;
					}
				}
				++p;
			}
		}
		if(openBraces>0) break;
	} else {
		if(*p!=0) {
			NOSPACES;
		}
	}
	end=p;
	
	SPACES;
	if(*(p++)!='d') break;
	if(*(p++)!='e') break;
	if(*(p++)!='f') break;
	save=*end;
	*end=0;
	lng=(int)(end-beg);
	if(lng<=STRLEN)
		value=vlu;
	else {
		if(!(value=(char *)malloc(sizeof(char)*(lng+1))))
			break;
	}
	strncpy( value, beg, lng);
	value[lng]=0;
	Tcl_SetVar2( interp, "udef", str, value, TCL_GLOBAL_ONLY);
	
	if(lng>STRLEN)
		free(value);
	}
	}
	ERR("? P_parse <user-def PS>");
}

#define CREATE(a,b) 	Tcl_CreateCommand( myinterp, a, (Tcl_CmdProc *)b, (ClientData) NULL, NULL)

// sets up a TCL interpreter, initializes variables, sources scripts, connects to GUI
Tcl_Interp * initPencilTCL (id inspector)
{
	Tcl_Interp *myinterp;
	
	if(myinterp=Tcl_CreateInterp()) {
	CREATE("P_clearitems", P_clearitems);
	CREATE("P_additem", P_additem);
	CREATE("P_setPath", P_setPath);
	CREATE("P_setDraw", P_setDraw);
	CREATE("P_setFill", P_setFill);
	CREATE("P_setStroke", P_setStroke);
	CREATE("P_getLayers", P_getLayers);
	CREATE("P_setLayers", P_setLayers);
	CREATE("P_getCurLayer", P_getCurLayer);
	CREATE("P_setCurLayer", P_setCurLayer);
	CREATE("P_new", P_new);
	CREATE("P_open", P_open);
	CREATE("P_objectcount", P_objectcount);
	CREATE("P_getobject", P_getobject);
	CREATE("P_addobject", P_addobject);
	CREATE("P_changeobject", P_changeobject);
	CREATE("P_display", P_display);
	CREATE("P_resize", P_resize);
	CREATE("P_save", P_save);
	CREATE("P_selection", P_selection);
	CREATE("P_delete", P_delete);
	CREATE("P_print", P_print);
	CREATE("P_name", P_name);
	CREATE("P_move", P_move);
	CREATE("P_scale", P_scale);
	CREATE("P_select1", P_select1);
	CREATE("P_select", P_select);
	CREATE("P_group", P_group);
	CREATE("P_clipgroup", P_clipgroup);
	CREATE("P_ungroup", P_ungroup);
	CREATE("P_front", P_front);
	CREATE("P_back", P_back);
	CREATE("P_copyPS", P_copyPS);
	CREATE("P_import", P_import);
	CREATE("P_userDef", P_userDef);
	CREATE("P_setUserDef", P_setUserDef);
	CREATE("P_dispCurGr", P_dispCurGr);
	CREATE("P_resizeView", P_resizeView);
	CREATE("P_display1", P_display1);
	CREATE("P_parse", P_parse);
	CREATE("P_writePS", P_writePS);
	CREATE("P_writeObject", P_writeObject);
	CREATE("P_readObject", P_readObject);
	CREATE("P_objectBounds", P_objectBounds);
	CREATE("P_moveObject", P_moveObject);
	CREATE("P_setClearBG", P_setClearBG);
	CREATE("P_setPrintTransp", P_setPrintTransp);
	CREATE("P_addMenuItem", P_addMenuItem);
	CREATE("P_scaleObject", P_scaleObject);
	CREATE("P_rotateObject", P_rotateObject);
	CREATE("P_setAttributes", P_setAttributes);
	CREATE("P_convert2CP", P_convert2CP);
	CREATE("P_forSelection", P_forSelection);
	CREATE("P_hideDisplay", P_hideDisplay);
	CREATE("P_displayRect", P_displayRect);
	CREATE("P_selectAll", P_selectAll);

	Tcl_SetVar(myinterp, "P_appdir", (char *)[[NXBundle mainBundle] directory], TCL_GLOBAL_ONLY);
	Tcl_SetVar(myinterp,"P_searchpath", "$env(HOME)/Library/PencilTWO/ $env(HOME)/.AppInfo/PencilTWO/ $P_appdir/../PencilLibrary/ $P_appdir/ $env(HOME)/Library/TCL/", TCL_GLOBAL_ONLY);
	Tcl_GlobalEval(myinterp, "proc P_subst {j} {uplevel \"return $j\"};proc P_source {n} { global P_searchpath env P_appdir;foreach i $P_searchpath {if ![catch \"uplevel #0 {source [P_subst $i]$n}\"] {break}} }");
	globGUI=[GUI initTCLCommands: myinterp: inspector];
	Tcl_GlobalEval(myinterp, "P_source PENCILinit.tcl");
	}
	return myinterp;
}
