# Window "hello world" program
#
# Qiang A. Zhao, October 92
#
# Usage: hello [nap_time [font] ]
#

resource hello()

  import SRWin

  const	ST_LOW := 8.0
  const	ST_LEN := 6.0
  const	ST_ST := 0.05

  const W := 500
  const H := 500
  const PI := 3.1415927
  const	TWO_PI := 6.2831856

  var mainwin, win2, win3, win4: winWindow
  op  ec : winEventChannel
  sem gone := 0
  var ev: winEvent
  var stay := true
  var slp : int := 200;		getarg(1, slp)
  var font := "lucidasanstypewriter-14"
				getarg(2, font)

  ### Op to draw flying text
  op	ftext(win1, win2: winWindow; str: string[*])
  proc	ftext(win1, win2, str)
    var pt : winPoint := winPoint(int(random(W)), int(random(H)))
    var ff : winFont
    var ww : int := 90
    ff:=WinLoadFont(mainwin, font)
    if ff = null ->
      write("Whoops, can't load my favorite font... Use default...")
    [] else ->
      ww := WinTextWidth(ff, str)
      WinSetFont(win1, ff)
      WinSetFont(win2, ff)
    fi
    do stay ->
      WinDrawString(win2, pt, str)
      pt.x := int(random(-ww, W))
      pt.y := int(random(-ww, H))
      WinDrawImageString(win1, pt, str)
      WinFlush(mainwin)
      nap(int(random(1000, 2000)))
    od
    if ff != null -> WinFreeFont(win1, ff) fi
    V(gone)
  end

  ### m copies, n-point polygon
  op	drawing(win1, win2: winWindow; m, n: int)
  proc	drawing(win1, win2, m, n)
    var	data[m][n] : winPoint
    var dir[n]: real
    var sta : real := random(TWO_PI)
    var	stp : real
    var	lastp := 1, curp := 2
    fa i:= 1 to n ->
      data[1][i].x := int(random(W))
      data[1][i].y := int(random(H))
      dir[i] := random(TWO_PI)
    af
    do stay ->
      WinDrawPolygon(win2, data[curp])
      fa i:=1 to n ->
	stp := ST_LOW + ST_LEN * sin(sta)
	data[curp][i].x := data[lastp][i].x + int(stp*cos(dir[i]))
	data[curp][i].y := data[lastp][i].y + int(stp*sin(dir[i]))
	# change direction if hit any wall
	if data[curp][i].x < 0 ->
	  dir[i] := PI-dir[i]; data[curp][i].x := 0 
	[] data[curp][i].x >= W ->
	  dir[i] := PI-dir[i]; data[curp][i].x := W-1
	fi
	if data[curp][i].y < 0 ->
	  dir[i] := -dir[i]; data[curp][i].y := 0 
	[] data[curp][i].y >= H ->
	  dir[i] := -dir[i]; data[curp][i].y := H-1
	fi
      af
      WinDrawPolygon(win1, data[curp])
      WinFlush(win1)
      lastp := lastp mod m + 1
      curp := curp mod m + 1
      sta +:= ST_ST
      if sta >= TWO_PI ->
	sta -:= TWO_PI
      fi
      nap(int(random(slp/2, slp)))
    od
    V(gone)
  end

  ###
  # open a WxH window called "Test", map_depth=0 means "on screen"
  mainwin := WinOpen("", "Test", ec, UseDefault, W, H)
  if mainwin = null ->
    write("Ouch, can't open window")
    stop(1)
  fi
  win2 := WinNewContext(mainwin)
  win3 := WinNewContext(mainwin)
  win4 := WinNewContext(mainwin)

  # begin to draw...
  WinSetForeground(win2, "blue")
  WinSetForeground(win3, "red")
  WinSetForeground(win4, "cyan")
  WinSetForeground(mainwin, "black")

  # fire up several processes (keep PROCESSES consistent)
  const	PROCESSES := 3
  send drawing(win2, mainwin, 10, 4)
  send drawing(win3, mainwin, 15, 3)
  send ftext(win4, mainwin, "Hello World")

  # test events...
  WinSetEventMask(mainwin, Ev_KeyUp)
  WinSetPoll(mainwin, 10)
  do stay ->
    receive ec(ev)
    if ev.event_type = Ev_KeyUp ->
      if char(ev.data) = 'Q' ->
	stay := false
      fi
    [] ev.event_type = Ev_DeleteWindow ->
      write("DeleteWindow ...")
      stay := false
    fi
  od

  # wait for all fancy processes quit
  fa i := 1 to PROCESSES -> P(gone) af

  ### done
  # close window - the event polling process will terminate automatically
  WinClose(mainwin)

end hello

