// Text of project AutoRoute written on 2/14/96 at 3:42 PM
// Beginning of text file Constants
/*
**      Newton Developer Technical Support Sample Code
**
**      AutoRoute, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

constant kDataSymbol 		:= '|myData:AutoRoute:PIEDTS|;
constant kPrintFormat1Sym 	:= '|format1:AutoRoute:PIEDTS|;
constant kPrintFormat2Sym 	:= '|format2:AutoRoute:PIEDTS|;
constant kFrameFormatSym 	:= '|frameFormat:AutoRoute:PIEDTS|;

DefConst('kMyFrameFormat, {
	 _proto: protoFrameFormat,
	 symbol: kFrameFormatSym,
	 title: "Frame Format",

	 // for your project, you may have to do more work to export the item to text
	 textScript: func(item, target) 
	 	clone(target.text);
	});
// End of text file Constants
// Beginning of text file Install/Remove Scripts
/*
**      Newton Developer Technical Support Sample Code
**
**      Auto Route, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

InstallScript := func(partFrame)
	begin
		local myApp := partFrame.theForm ;
	
		// Don't use GetLayout(...) in form ("Application") part InstallScripts 
		// because it wastes much NewtonScript memory! See the CustomRoute 
		// sample for more info.
		
		// We get the routing formats from slots in our base view.
		// See the base view myFormats slot for the declarations...
		RegisterViewDef(myApp.myFormats.printFormat1, kDataSymbol);
		RegisterViewDef(myApp.myFormats.printFormat2, kDataSymbol);
		RegisterViewDef(myApp.myFormats.frameFormat, kDataSymbol);
	end;


RemoveScript := func(packageFrame)
	begin
		UnRegisterViewDef(kPrintFormat1Sym, kDataSymbol);
		UnRegisterViewDef(kPrintFormat2Sym, kDataSymbol);
		UnRegisterViewDef(kFrameFormatSym, kDataSymbol);
	end;
	
// End of text file Install/Remove Scripts
// Beginning of file PrintFormat1

// Before Script for "Format#1"
/*
**      Newton Developer Technical Support Sample Code
**
**      AutoRoute, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

Format#1 :=
    {
     printNextPageScript:
       func()
       begin
       	// only print one page
       	nil;
       end,
     title: "Print Format #1",
     symbol: kPrintFormat1Sym,
     debug: "Format#1",
     _proto: @200
    };

border&margins :=
    {viewFlags: 33,
     viewFormat: 593,
     viewBounds: {left: 5, top: 5, right: -5, bottom: -5},
     viewJustify: 240,
     debug: "border&margins",
     viewClass: 74
    };
AddStepForm(Format#1, border&margins);

_view000 :=
    {
     text:
       "This was done using the Print Format #1!\nAutoRoute!......Custom text sent from a Newton far far away..."
     ,
     viewBounds: {top: 30, left: 2, right: -2, bottom: 50},
     viewJustify: 50,
     _proto: @218
    };
AddStepForm(border&margins, _view000);



_view001 :=
    {text: "Static Text",
     viewBounds: {top: 300, left: 2, right: -2, bottom: 350},
     viewSetupFormScript:
       func()
       begin
       	// Change our appearance based on the routing data
       	// Print formats should always access 'target not fields
       	SetValue(self, 'text, target.text);
       end,
     viewJustify: 50,
     viewFormat: 336,
     _proto: @218
    };
AddStepForm(border&margins, _view001);






constant |layout_PrintFormat1| := Format#1;
// End of file PrintFormat1
// Beginning of file PrintFormat2

// Before Script for "Format#2"
/*
**      Newton Developer Technical Support Sample Code
**
**      AutoRoute, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

Format#2 :=
    {
     printNextPageScript:
       func()
       begin
       	// only print one page
       	// returning nil means there are no other pages
       	nil;
       end,
     title: "Print Format #2",
     symbol: kPrintFormat2Sym,
     debug: "Format#2",
     _proto: @200
    };

border&margins :=
    {viewFlags: 33,
     viewFormat: 593,
     viewBounds: {left: 5, top: 5, right: -5, bottom: -5},
     viewJustify: 240,
     debug: "border&margins",
     viewClass: 74
    };
AddStepForm(Format#2, border&margins);

_view002 :=
    {
     text:
       "This was done using the Print Format #2!\nAutoRoute!......Custom text sent from a Newton far far away..."
     ,
     viewBounds: {top: 30, left: 2, right: -2, bottom: 50},
     viewJustify: 50,
     _proto: @218
    };
AddStepForm(border&margins, _view002);



_view003 :=
    {text: "Static Text",
     viewBounds: {top: 300, left: 2, right: -2, bottom: 350},
     viewSetupFormScript:
       func()
       begin
       	// Change our appearance based on the routing data
       	// Print formats should always access 'target not fields
       	SetValue(self, 'text, target.text);
       end,
     viewJustify: 50,
     viewFormat: 336,
     _proto: @218
    };
AddStepForm(border&margins, _view003);






constant |layout_PrintFormat2| := Format#2;
// End of file PrintFormat2
// Beginning of file PrinterChooser

// Before Script for "_view004"
/*
**      Newton Developer Technical Support Sample Code
**
**      AutoRoute, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

_view004 :=
    {viewFlags: 608,
     viewBounds: {left: 10, top: -17, right: -10, bottom: 49},
     viewJustify: 112,
     _proto: @180
    };

_view005 :=
    {viewBounds: {left: 8, top: 14, right: 208, bottom: 46},
     viewSetupFormScript:
       func()
       	begin
       		local toDisplay;
       		
       		// temporarily SAVE the system-wide printer setting
       		originalPrinter := GetUserConfig('currentPrinter);
       		
       		// find out the temporary printer choice
       		toDisplay := :GetTemporaryPrinterChoice();
       		
       		// temporarily set the system-wide printer setting
       		SetUserConfig('currentPrinter, toDisplay);
       		
       		// we call this last so that the printerChooserButton sets up its text
       		// with the system-wide currentPrinter (which we just changed
       		inherited:?viewSetupFormScript();
       	end,
     viewQuitScript:
       func()
       	begin
       		// SAVE the user's printer setting
       		local theChoice := GetUserConfig('currentPrinter);
       		
       		// save the user's printer setting
       		:SetTemporaryPrinterChoice(theChoice);
       		
       		// restore the original system-wide printer setting
       		SetUserConfig('currentPrinter, originalPrinter);
       		
       		 // make sure any changes to the user configuration are saved!
       		FlushUserConfig();
       		
       		inherited:?viewQuitScript();
       	end,
     originalPrinter:
       nil // when the view is open, this contains 
          // the actual system-wide 'currentPrinter setting
       ,
     GetTemporaryPrinterChoice:
       // used by the printer chooser (see the PrinterChooser layout for more info...)
       func()
       	begin
       		// Get the printer setting we should use when displaying the printer to the user.
       		// In this sample, it is a base view slot...
       		getroot().(kAppSymbol).currentPrinterSetting;
       	end,
     SetTemporaryPrinterChoice:
       // used by the printer chooser (see the PrinterChooser layout for more info...)
       func(theChoice)
       	begin
       		// Set the user's printer choice. We store it in a base view slot.
       		getroot().(kAppSymbol).currentPrinterSetting := theChoice;
       	end,
     _proto: @153
    };
AddStepForm(_view004, _view005);




constant |layout_PrinterChooser| := _view004;
// End of file PrinterChooser
// Beginning of file AutoRoute.t

// Before Script for "AutoRoute"
/*
**      Newton Developer Technical Support Sample Code
**
**      AutoRoute, an example of the Send function.
**
**      by J. Christopher Bell, Newton Developer Technical Support
**
**      Copyright  1995-1996 by Apple Computer, Inc.  All rights reserved.
**
**      You may incorporate this sample code into your applications without
**      restriction.  This sample code has been provided "AS IS" and the
**      responsibility for its operation is 100% yours.  You are not
**      permitted to modify and redistribute the source as "DTS Sample Code."
**      If you are going to re-distribute the source, we require that you
**      make it clear in the source that the code was descended from
**      Apple-provided sample code, but that you've made changes.
*/

AutoRoute :=
    {
     AutoRoute:
       func()
       begin
       	if not transportSym then
       		return :Notify(kNotifyAlert, "AutoRoute", "No transport has been selected.");
       	else if not formatSym then
       		return :Notify(kNotifyAlert, "AutoRoute", "No format has been selected.");
       	
       	// get the entry alias containing the current user's personal data (we will send the item to ourselves)
       	local persona := GetUserConfig('currentPersona);
       	
       	// create a new I/O Box item based on the current transport setting
       	local item := TransportNotify(transportSym, 'NewItem, [nil]);
       	
       	if item and not item = 'noReceiver then
       		begin
       			// Get the data def for the "nameRef type" (for example, '|nameRef.Fax|)
       			local class := GetItemTransport(item).addressingClass;
       			local dataDef := GetDataDefs(class);
       
       			// Make a name ref , which is the type of object required in the toRef slot
       			// We are making a nameRef that represents the users CURRENT persona.
       			// This is just because this example sends an item to the user via email/fax, etc.
       			local myToRef := dataDef:MakeNameRef(persona, class);
       			
       			item.toRef := [myToRef];
       			
       			// Get the data to send to the transport
       			item.body := self:GetTargetInfo('routing).target;
       			
       			item.appSymbol := appSymbol;	// necessary for frame transport put away (beam, mail, etc)
       			
       			item.title := "Auto-"& GetItemTransport(item).title && datentime(time());
       
       			item.currentFormat := formatSym;
       			
       			// Add our optional settings (may be ignored by individual transports)
       			item.connect := sendNow;
       						
       			// Do not override the printer slot if it is already there. Otherwise fax won't work!
       			if not item.printer then
       				item.printer := currentPrinterSetting;
       			
       			// WARNING: The following code is ONLY necessary for the eWorld transport.
       			// eWorld is not a "standard transport". It requires an extra 'attachment slot
       			// to handle routing items in the body slot and a non-standard 'text slot
       			// to handle routing text to the eWorld server. Do not add these slots for
       			// transports other than eWorld.
       			if transportSym = 'mailSlip then
       				begin
       					item.attachment := true; 	// to make "attachments" work with eWorld
       					item.text := item.body.text // to make "text" work with eWorld
       				end;
       			
       			Send(transportSym, item);
       		end
       	else
       		:Notify(kNotifyAlert, "AutoRoute", "Could not send. The selected transport was not found.");
       end,
     GetTargetInfo:
       /* Usually, you will determine what to Route (or file, etc) in your :GetTargetInfo(...) method
          If your 'target and 'targetView slots are always up-to-date, you do not need to implement this
          method because the root view implements GetTargetView and will use your target and targetView slots.
        */
       func(reason)
       	begin
       		constant kMyVersionNum := 1;
       
       		local tempText := DataInputLine.entryline.text;
       		
       		if not StrFilled(tempText) then
       			tempText := "<no text entered>";
       			
       		// Create your data. Only the class slot is required; the rest is up to you...
       		{target: 
       			{class: kDataSymbol, // always give your target a unique class symbol!
       			 text: clone(tempText), // keep a separate copy of the text so it isn't shared.
       			 timeStamp: time(),      // not required. Just a good idea.
       			 version: kMyVersionNum, // not required. Just a good idea.
       			 }, 
       			 
       		 targetView: GetRoot().(kAppSymbol), // our base view is the targetView
       		 }
       	end,
     viewFormat: 83951953,
     viewFlags: 5,
     viewBounds: {left: 2, top: 2, right: 236, bottom: 325},
     appSymbol: kAppSymbol,
     declareSelf: 'base,
     currentPrinterSetting:
       nil // used by the printer chooser. See the PrinterChooser layout for more info...
       ,
     viewSetupFormScript:
       func()
       	begin
       		viewBounds := GetAppParams().appAreaBounds;
       		
       		// used by the printer chooser. See the PrinterChooser layout for more info.
       		currentPrinterSetting := GetUserConfig('currentPrinter);
       	end,
     sendNow:
       true // default base view slot for "send immediately"
       ,
     transportSym:
       nil // base view slot setting for the "transport picker"
       ,
     viewSetupDoneScript:
       func()
       	begin
       		// show the printer chooser picker only if the print transport is the currently selected transport
       		PrintChooserPicker:NewTransportChosen();
       	end,
     ReorientToScreen:
       ROM_defRotateFunc; // used for rotation and opening in landscape mode...
       ,
     formatSym:
       nil // base view slot setting for the "format picker"
       ,
     PutAwayScript:
       /* To receive the PutAwayScript, one of the following must occur:
       	1) the item has an appSymbol slot. When routing with a protoActionButton, this is easy
       	   since the system sets it up for you with the appSymbol value from your base view (actually,
       	   the message context of the Action button, but it usually finds it in your base view because
       	   NTK creates that slot for you if you do not already define it)
       	2) your application uses the RegAppClasses function in its installScript
       	
          This application sets the appSymbol slot in the item directly using the Send function.
          See the AutoRoute base view method to see that code...
       */
       func(item)
       	begin
       		// your app might be asked to put away something you don't know about. Return
       		// nil if you don't know how to deal with it!
       		if classof(item.body) <> kDataSymbol or TargetIsCursor(item.body) then
       			return nil;
       	
       	    if kDebugOn then
       	    	begin
       		    	print("Received the following item:");
       				print(item);
       			end;
       	
       		self:Open();   // won't do anything if we are already open
       	
       		// At this point, you would do WHATEVER Put Away would mean for your application...
       		SetValue(DataInputLine.entryline, 'text, item.body.text);
       		
       		true; // returning non-nil to indicate that we handled the item
       	end,
     myFormats:
       // These formats are used in the installScript. See the 
       // Install/Remove Scripts file to see how to register and unregister them...
       {
         frameFormat: kMyFrameFormat,
         printFormat1: GetLayout("PrintFormat1"),
         printFormat2: GetLayout("PrintFormat2"),
        },
     debug: "AutoRoute",
     viewClass: 74
    };

_view006 :=
    {viewBounds: {left: 10, top: 4, right: 155, bottom: 17},
     viewJustify: 4,
     _proto: @497
    };
AddStepForm(AutoRoute, _view006);



DataInputLine :=
    {viewBounds: {left: 2, top: 32, right: -10, bottom: 54},
     label: "Data",
     viewJustify: 8396852,
     debug: "DataInputLine",
     _proto: @189
    };
AddStepForm(AutoRoute, DataInputLine);
StepDeclare(AutoRoute, DataInputLine, 'DataInputLine);



sendNowCheckbox :=
    {text: "Send immediately",
     viewBounds: {left: 13, top: 10, right: -10, bottom: 30},
     valueChanged:
       func()
       begin
       	sendNow := viewValue;
       end,
     viewJustify: 8396852,
     viewSetupFormScript:
       func()
       	begin
       		// initialize the checkbox from the base view default...
       		viewValue := sendNow;
       	end,
     debug: "sendNowCheckbox",
     _proto: @164
    };
AddStepForm(AutoRoute, sendNowCheckbox);



transportPicker :=
    {text: "Transport",
     viewBounds: {left: 13, top: 5, right: -10, bottom: 25},
     viewJustify: 8396848,
     labelActionScript:
       func(cmd)
       begin
       
       	local stringChoice := labelCommands[cmd];
       	
       	local target := :GetTargetInfo('routing).target; // you could define your own targetInfo 'reasons'
       	
       	local transports := GetFormatTransports(GetRouteFormats(target), target);
       	
       	// get the chosen transport's symbol
       	transportSym := transports[cmd].appSymbol; 
       	
       	// update format picker with new choices
       	formatPicker:GetFormats(); 
       
       	// show the printer chooser picker if appropriate
       	PrintChooserPicker:NewTransportChosen(); 
       	return;
       end;,
     pickerSetup:
       func()
       begin
       	local target := :GetTargetInfo('routing).target;
       	
       	local transports := GetFormatTransports(GetRouteFormats(target), target);
       	
       	if transports then
       		begin
       			// Build a user-visible list of strings to show to the user.
       			local stringList := foreach transport in transports collect transport.title;
       		
       			labelCommands := stringList;
       			
       			// If there was no current choice, since the first labelCommand will be displayed,
       			// set the base view transport to match this setting.
       			if not transportSym then
       				transportSym := transports[0].appSymbol;
       		end;
       	else
       		begin
       			labelCommands := ["<No Transports>"];
       			transportSym := nil;
       			return nil; // the popup shouldn't happen
       		end;
       
       	true;		// the popup should happen
       end,
     viewSetupFormScript:
       func()
       begin
       	:PickerSetup();
       	inherited:?viewSetupFormScript();		// this method is defined internally
       end,
     debug: "transportPicker",
     _proto: @190
    };
AddStepForm(AutoRoute, transportPicker);



formatPicker :=
    {text: "Format",
     viewBounds: {left: 13, top: 5, right: -10, bottom: 25},
     pickerSetup:
       func()
       begin
       	local target := :GetTargetInfo('routing).target;
       	
       	local formats := GetRouteFormats(target);
       		
       	if transportSym and formats then
       		begin
       			formatChoices := [ ]; // set the slot in this view to include no choices
       			
       			local formatNames := [ ]; // initialize array of format names
       			
       			// Get a reference to the transport in a supported way.
       			// (Don't use the code getroot().(transportSym). That is unsupported and subject to change)
       			local transportReference := GetItemTransport(TransportNotify(transportSym, 'NewItem, [nil]));
       
       			// include only formats that are compatible with the selected transport
       			foreach format in formats do
       				begin
       					// a format and transport are compatible if they SHARE at least one dataType
       					if SetOverlaps(format.dataTypes, transportReference.dataTypes) then
       						begin
       							AddArraySlot(formatChoices, format.symbol);
       							
       							if StrFilled(format.title) then // if title is non-nil, it is a string...
       								AddArraySlot(formatNames, format.title);
       							else	// if title is nil, just display the symbol as a string...
       								AddArraySlot(formatNames, ""&format.symbol);
       						end;
       				end; 
       
       			// set up the choices for the popup
       			labelCommands := formatNames;
       			
       			// Since the first labelCommand will be displayed initially,  
       			// set our base view slot to match this setting.
       			if not formatSym then
       				formatSym := formatChoices[0];
       		end;
       	else
       		begin
       			labelCommands := ["<No Formats>"];
       			transportSym := nil;
       			return nil; // the popup shouldn't happen
       		end;
       
       	true;		// the popup should happen
       end,
     GetFormats:
       // This is called when the user switches transports and new formats must be calculated 
       func()
       	begin
       		:PickerSetup();
       		:UpdateText(labelCommands[0]); // set the visible text to the first labelCommand 
       	end,
     viewJustify: 8396848,
     labelActionScript:
       func(cmd)
       	begin	
       		// Look up the formatChoices array we created in the pickerSetup method.
       		// Set our base view slot with the chosen format symbol.
       		formatSym := formatChoices[cmd];
       	end;,
     viewSetupFormScript:
       func()
       	begin
       		:PickerSetup();							// ensure we are showing the right choices initially
       		inherited:?viewSetupFormScript();		// this method is defined internally
       	end,
     formatChoices:
       nil // set in pickerSetup
       ,
     debug: "formatPicker",
     _proto: @190
    };
AddStepForm(AutoRoute, formatPicker);
StepDeclare(AutoRoute, formatPicker, 'formatPicker);



PrintChooserPicker :=
    {text: "Print Options",
     viewBounds: {left: 15, top: 5, right: 100, bottom: 20},
     viewJustify: 8396806,
     NewTransportChosen:
       // Show the printer chooser picker only if the print transport is the currently selected transport.
       func()
       	begin
       		if transportSym = '|Print:Newton| then 
       			self:Show();
       		else
       			self:Hide();
       	end,
     buttonClickScript:
       func()
       	begin
       		// open the printChooser, which is a linked subview...
       		printChooser:Open();	
       	end,
     viewSetupFormScript:
       func()
       	begin	
       		// set our size appropriately, based on the size of our text
       		viewbounds := clone(viewbounds);
       		viewbounds.right := viewbounds.left + StdButtonWidth(text);
       		
       		inherited:?viewSetupFormScript();
       	end,
     debug: "PrintChooserPicker",
     _proto: @226
    };
AddStepForm(AutoRoute, PrintChooserPicker);
StepDeclare(AutoRoute, PrintChooserPicker, 'PrintChooserPicker);


PrintChooser := LinkedSubview(_view004,
    {viewBounds: {left: 146, top: 274, right: 231, bottom: 325},
     debug: "PrintChooser"
    });
AddStepForm(AutoRoute, PrintChooser);
StepDeclare(AutoRoute, PrintChooser, 'PrintChooser);

_view007 :=
    {
     menuLeftButtons:
       [{
       	_proto: protoInfoButton,
       	doInfoAbout: func()
       		:Notify(kNotifyQAlert, "AutoRoute", "AutoRoute, an example of the Send function.\n\nCopyright 1995-1996 by Apple Computer, Inc. All rights reserved.");
        },
       ];,
     menuRightButtons:
       [{
       	_proto: protoTextButton,
       	text: "AutoRoute",
       	buttonClickScript: func() 
       		begin
       			:AutoRoute();
       		end
        }
       ],
     _proto: @401
    };
AddStepForm(AutoRoute, _view007);




constant |layout_AutoRoute.t| := AutoRoute;
// End of file AutoRoute.t



