#!/usr/cogent/bin/phgamma

/*
 * This is a simple example of communicating with a Gamma application
 * through program control.  There is a text file called example12.doc
 * in the /usr/cogent/examples directory, which walks you through an
 * interactive session allowing you to modify a program as it runs.
 *
 * This program will perform the same steps as the interactive sample
 * without the interactive component.
 *
 * To run, restart example08, and then run this program using:
 *    example12
 *
 * This program will exit when it completes.
 *
 * This file is best viewed with a tab width of 4.
 */

/*
 * Initialize IPC requests.  If we do not do this, locate_task and send
 * will cause a crash.
 */

init_ipc ("example12", nil);

/*
 * Look up the Photon program by name, as "example8".  The return value
 * from the lookup will be nil if it fails, or an opaque task identifier.
 * The Cogent nserve has to be running for this to succeed.
 */
task = locate_task ("example08", nil);

/*
 * If we found the task, send commands to it.  The commands must be in
 * pre_parsed internal form, so we allow the Gamma parser to see the
 * expression we want to send, but do not evaluate it.  This is done with
 * '#' symbol.
 */
if (task)
{
	/*
	 * Change the color of the Arc.  Test for inside_color, as this
	 * differentiates Photon 1.14 from Photon 2.0.
	 */

	function ChangeColor ()
	{
		if (has_ivar (Arc, #inside_color))
		{
			Arc.fill_color = -1;
			Arc.inside_color = PgRGB(0xff, 0xff, 0);
		}
		else
		{
			Arc.fill_color = PgRGB(0xff, 0xff, 0);
		}
	}

	/*
	 * Transmit the function definition.
	 */
	send (task, ChangeColor);

	/*
	 * Transmit the command to run the function.
	 */
	send (task, #ChangeColor());

	/*
	 * Define the TitleClock function.  Notice that we do not have a
	 * variable named 'win'.  If we try to run this function here, it
	 * will generate errors.  However, when we pass the function
	 * definition to the running task, TitleClock will make sense.
	 */
	function TitleClock()
	{
		win.title = date();
	}

	/*
	 * Transmit our new function.
	 */
	send (task, TitleClock);

	/*
	 * Execute our new function once.
	 */
	send (task, #TitleClock());

	/*
	 * Set up a timer to run the function over and over.
	 */
	send (task, #every (1, #TitleClock()));
	
	/*
	 * Re_define the function and transmit it again.  Notice that we did
	 * not stop the timer, but simply inserted a new function definition
	 * which immediately replaced the old one.
	 */
	function TitleClock()
	{
		win.title = string ("Example 8 - ", date());
	}
	
	send (task, TitleClock);

	/*
	 * We can add new functionality to an existing screen by transmitting
	 * arbitrarily complex code to the running application, and then
	 * invoking that code.  In this case, we add a slider to the screen
	 * which alters the arc angle for the rotating arc.
	 */
	function add_angle_slider ()
	{
		Angle = new (PtSlider);
		Angle.SetArea (275, 250, 160, 25);
		Angle.gauge_minimum = 0;
		Angle.gauge_maximum = 359;

		/* These only work in Photon 1.14 */
		if (has_ivar (Angle, #slider_label_tl))
		{
			Angle.slider_label_tl = "Arc";
			Angle.slider_label_br = "090";
			Angle.slider_tick_major_col = PgRGB(0xff, 0xff, 0xff);
			Angle.slider_label_br_col = PgRGB(0xff, 0xff, 0xff);
			Angle.slider_label_tl_col = PgRGB(0xff, 0xff, 0xff);
			PtAttachCallback (Angle, Pt_CB_SLIDER_MOVE,
							  #Angle.slider_label_br =
							  format("%03d", Angle.gauge_value));
		}
		Angle.gauge_value = 90;
	
		PtAttachCallback (Angle, Pt_CB_SLIDER_MOVE,
						  #arc_angle=Angle.gauge_value);
		PtRealizeWidget (Angle);
		PtFlush();
		add_set_function (#arc_angle, #rotate_arc());
	}

	send (task, add_angle_slider);
	send (task, #add_angle_slider());
}
else
{
	princ("Make sure you are running example 8 first, and that the Cogent\n");
	princ("name server is running.\n");
	princ("Run example 8 in the background like this:\n\n");
	princ("example08 &\n\n");
	princ("then run example12.");
}


princ("\n\nMake sure you read the example12.doc file\n");
princ("for more information on an interactive\n");
princ("walk-though for direct control of the\n");
princ("example08 program.\n");

/*
 * There is no event loop in this program, so it will end when it
 * gets to the bottom of the file.  We did not call the event handler
 * or any Photon functions, so we did not have to call PtInit.
 */
