'(Globals):

Option Public
' sample script application that uses the Scriptable Graph Part (ODS_Graph)
' and the Scriptable Timer (ODS_Timer) to build a clock

' The following statement will access the definition of the class ODS_Timer
' and allow us to create an instance of that class later.
Uselsx "SOM:ODS_Timer"

' These global declarations allow access to the Graph object and the
' Timer object. The third global is essentially a boolean that indicates
' whether the initilaization has been performed.
Dim G As ODS_Graph
Dim theTimer As ODS_Timer
Dim InitDone As Long ' if value = 1000, initialization done

Sub MyInit (theGraph As ODS_Graph)
' This subroutine will perform the initialization needed to allow access to the
' Graph part, create an instance of the Timer, and attch the proper subroutine
' to the timer's event	
	If InitDone < 1000 Then
		Set G = theGraph  ' allows access to the Graph part via the identifer G
		Set theTimer = New ODS_Timer ' create a new Timer object
		theTimer.interval = 0
		On Event TimerEvent From thetimer Call Tick ' attach subroutine to timer event
		InitDone = 2000    ' use this global as a boolean for initialization
	End If
	'
	'The following will allow the timer to be halted or restarted
	If theTimer.interval > 0 Then
		theTimer.stop
		theTimer.interval = 0
	Else
		theTimer.interval = 1000
		theTimer.start
	End If
	' Beep
End Sub

Sub Tick (tt As ODS_Timer)
	Static xmax As Long, ymax As Long  'Hold graph part size
	Static XOrig As Long, YOrig As Long 'Computed center of clock
	Static CRadius As Long        'Computed radius for clock
' the following act as handles to the various graphic elements
' used to build the clock image.
	Static Sec0 As Long
	Static Hour0 As Long, hour1 As Long, hour2 As Long, HourX As Long, HourY As Long
	Static Min0 As Long, min1 As Long, min2 As Long, MinX As Long, MinY As Long
' the following collection is used when we redraw the clock after it is resized
	Static LC As New LongSOMCollection
	Dim x As Long, y As Long
	Dim X0 As Long, y0 As Long
	Dim A As Double, HalfPi As Double
	HalfPi = Pi/2
' check for a change in size of the graph part. Note that the -1 used
' here (and elsewhere) is a handle that will not be matched, the GraphPart
' is defined to return the corresponding information for the graphpart
' itself when the specified object is not found.
	G.GetBounds -1, x0, y0, x, y
	If (xMax <> x) Or (yMax <> y ) Then
		xMax = x
		yMax = y
		XOrig = xMax / 2
		yOrig = yMax / 2
' the radius is 95% of the smaller of x or y size
		CRadius = 95 * XOrig / 100
		If XOrig > YOrig Then
			CRadius = 95 * YOrig / 100
		End If
'    since the size has changed, we remove all the old parts
'    and redraw the clock face
		G.GetAllParts LC
		Forall LCx In LC
			G.remove LCx
'    this refresh will redraw things.  It is not strictly needed
'    because we will refresh later but it gives feedback as we
'    progress.  Sort of a warm fuzzy.
			G.refresh -1
		End Forall
		x0 = XOrig + CRadius
		y0 = YOrig
		For A = 0 To 2 * Pi Step Pi / 30
			x = CRadius * Cos(a) + XOrig
			y = CRadius * Sin(a) + YOrig
			G.AddLine x0,y0,x,y,0
'      Again, this refresh is not NEEDED but is a warm fuzzy.
			G.Refresh -1
			x0 = x
			y0 = y
		Next
		For A = 0 To 2 * Pi Step Pi/6
			x = Cos(a) * CRadius
			x0 = x + XOrig
			x = 93 * x /100 + XOrig
			y = Sin(a) * CRadius
			y0 = y  + YOrig
			y = 93 * y / 100 + YOrig
			G.AddLine x0, y0, x,y, 0
			G.Refresh -1
		Next
		
' create the objects for the clock hands, for these we save the
' handle for later use (coordinates here are not really used)
		Sec0 = G.AddRectangle ( XOrig, YOrig, XOrig, yOrig, 256& * 255		)
		Hour0 = G.addline (XOrig, YOrig, XOrig, YOrig, 255 )
		Hour1 = G.addline (XOrig, YOrig, XOrig, YOrig, 255 )
		Hour2 = G.addline (XOrig, YOrig, XOrig, YOrig, 255 )
		Min0 = G.addline (XOrig, YOrig, XOrig, YOrig, 65535 )
		Min1 = G.addline (XOrig, YOrig, XOrig, YOrig, 65535 )
		Min2 = G.addline (XOrig, YOrig, XOrig, YOrig, 65535 )
		HourX = 0
		MinX = 0
' set the color of the graphpart itself to an uninteresting grey
' all colors are integers with form red + 256*( green +256*blue)
' each of red/green/blue is in range 0 to 255.  In the following
' we use the Lotus specification 256& which forces the 256 to be
' a long integer and thus avoids an overflow that we get if we
' use all short integers.
		G.SetColor  -1, 192 + 256&* (192 + 256& * 192)
	End If

' Now we will update the clock to reflect the current time.
	asof = Now            ' just what is the current time
	a = Pi * Second(asof) / 30  - HalfPi  'compute the angle for seconds
	x = 89 * CRadius * Cos(a) /100 + XOrig
	y = 89 * CRadius * Sin(a) / 100 + YOrig
	x0 = (CRadius * 3) /100
	G.Adjust Sec0, x-x0, y-x0, x+x0, y+x0  ' adjust the location of the second object
	
'   compute the position for the hour hand, includes both hour and minutes
'   in the computation.  Only if the hand needs to move will we adjust it.
	a =  ((Hour(asof) Mod 12) + Minute(asof)/60)  * Pi / 6  - HalfPi
	x = 70 * CRadius * Cos(a) / 100 + XOrig
	y = 70 * CRadius * Sin(a) / 100 + YOrig
	If ( x <> HourX) Or (Y <> HourY) Then
		HourX = x
		HourY = y
		x = 5 * CRadius * Cos(a-HalfPi) / 100 + XOrig
		y = 5 * CRadius * Sin(a-HalfPi)  / 100 + YOrig
		x0 = 5 * CRadius * Cos(A + HalfPi) / 100 + XOrig
		y0 = 5 * CRadius * Sin(A + HalfPi) / 100 + YOrig
		G.Adjust Hour0, x,y, HourX, HourY
		G.Adjust Hour1, x0,y0, HourX, HourY
		G.Adjust Hour2, x,y, X0,y0
	End If
	
'   now do the same thing for the minute hand.
	a = Pi * Minute(asof)  / 30 - HalfPi
	x = 80 * CRadius * Cos(a) / 100 + XOrig
	y = 80 * CRadius * Sin(a) / 100 + YOrig
	If ( x <> MinX) Or (Y <> MinY) Then
		MinX = x
		MinY = y
		x = 3 * CRadius * Cos(a-HalfPi) / 100 + XOrig
		y = 3 * CRadius * Sin(a-HalfPi)  / 100 + YOrig
		x0 = 3 * CRadius * Cos(A + HalfPi) / 100 + XOrig
		y0 = 3 * CRadius * Sin(A + HalfPi) / 100 + YOrig
		G.Adjust Min0, x,y, MinX, MinY
		G.Adjust Min1, x0,y0, MinX, MinY
		G.Adjust Min2, x,y, X0,y0
	End If
	
' all the parts have been 'moved' but we have not yet updated
' the display.  This call will do that.
	G.Refresh -1
	
End Sub
